diff -r dc213d745642 tools/ioemu/block.c --- a/tools/ioemu/block.c Mon May 15 16:32:09 2006 +0100 +++ b/tools/ioemu/block.c Thu May 25 14:57:13 2006 -0600 @@ -1,8 +1,8 @@ /* * QEMU System Emulator block driver - * + * * Copyright (c) 2003 Fabrice Bellard - * + * * 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 @@ -41,6 +41,7 @@ BlockDriverState *bdrv_new(const char *d bs = qemu_mallocz(sizeof(BlockDriverState)); if(!bs) return NULL; + pstrcpy(bs->device_name, sizeof(bs->device_name), device_name); if (device_name[0] != '\0') { /* insert at the end */ @@ -62,7 +63,7 @@ BlockDriver *bdrv_find_format(const char return NULL; } -int bdrv_create(BlockDriver *drv, +int bdrv_create(BlockDriver *drv, const char *filename, int64_t size_in_sectors, const char *backing_file, int flags) { @@ -86,7 +87,7 @@ static BlockDriver *find_image_format(co return NULL; } close(fd); - + drv = NULL; score_max = 0; for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) { @@ -108,12 +109,13 @@ int bdrv_open2(BlockDriverState *bs, con BlockDriver *drv) { int ret; - + + pstrcpy(bs->filename, sizeof(bs->filename), filename); + bs->read_only = 0; bs->is_temporary = 0; bs->encrypted = 0; - - pstrcpy(bs->filename, sizeof(bs->filename), filename); + if (!drv) { drv = find_image_format(filename); if (!drv) @@ -123,7 +125,7 @@ int bdrv_open2(BlockDriverState *bs, con bs->opaque = qemu_mallocz(drv->instance_size); if (bs->opaque == NULL && drv->instance_size > 0) return -1; - + ret = drv->bdrv_open(bs, filename); if (ret < 0) { qemu_free(bs->opaque); @@ -146,6 +148,8 @@ int bdrv_open2(BlockDriverState *bs, con goto fail; } + shdev_set_media_instance(bs); + bs->inserted = 1; /* call the change callback */ @@ -170,6 +174,7 @@ void bdrv_close(BlockDriverState *bs) bs->opaque = NULL; bs->drv = NULL; bs->inserted = 0; + bs->media_instance = 0; /* call the change callback */ if (bs->change_cb) @@ -222,7 +227,7 @@ int bdrv_commit(BlockDriverState *bs) } /* return -1 if error */ -int bdrv_read(BlockDriverState *bs, int64_t sector_num, +int bdrv_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors) { int ret, n; @@ -261,7 +266,7 @@ int bdrv_read(BlockDriverState *bs, int6 } /* return -1 if error */ -int bdrv_write(BlockDriverState *bs, int64_t sector_num, +int bdrv_write(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors) { if (!bs->inserted) @@ -286,7 +291,7 @@ void bdrv_set_boot_sector(BlockDriverSta memset(bs->boot_sector_data + size, 0, 512 - size); } -void bdrv_set_geometry_hint(BlockDriverState *bs, +void bdrv_set_geometry_hint(BlockDriverState *bs, int cyls, int heads, int secs) { bs->cyls = cyls; @@ -301,7 +306,7 @@ void bdrv_set_type_hint(BlockDriverState type == BDRV_TYPE_FLOPPY)); } -void bdrv_get_geometry_hint(BlockDriverState *bs, +void bdrv_get_geometry_hint(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs) { *pcyls = bs->cyls; @@ -339,7 +344,7 @@ void bdrv_set_locked(BlockDriverState *b bs->locked = locked; } -void bdrv_set_change_cb(BlockDriverState *bs, +void bdrv_set_change_cb(BlockDriverState *bs, void (*change_cb)(void *opaque), void *opaque) { bs->change_cb = change_cb; @@ -377,7 +382,7 @@ void bdrv_get_format(BlockDriverState *b } } -void bdrv_iterate_format(void (*it)(void *opaque, const char *name), +void bdrv_iterate_format(void (*it)(void *opaque, const char *name), void *opaque) { BlockDriver *drv; @@ -387,7 +392,7 @@ void bdrv_iterate_format(void (*it)(void } } -BlockDriverState *bdrv_find(const char *name) +BlockDriverState *bdrv_find_by_device(const char *name) { BlockDriverState *bs; @@ -396,6 +401,15 @@ BlockDriverState *bdrv_find(const char * return bs; } return NULL; +} + +BlockDriverState *bdrv_find_bs(int (*it)(BlockDriverState *, void *), void *opaque) +{ + BlockDriverState *bs; + + for (bs = bdrv_first; bs != NULL && !it(bs, opaque); bs = bs->next); + + return( bs ); } void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque) @@ -481,28 +495,28 @@ static int raw_open(BlockDriverState *bs return 0; } -static int raw_read(BlockDriverState *bs, int64_t sector_num, +static int raw_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors) { BDRVRawState *s = bs->opaque; int ret; - + lseek(s->fd, sector_num * 512, SEEK_SET); ret = read(s->fd, buf, nb_sectors * 512); - if (ret != nb_sectors * 512) - return -1; - return 0; -} - -static int raw_write(BlockDriverState *bs, int64_t sector_num, + if (ret != nb_sectors * 512) + return -1; + return 0; +} + +static int raw_write(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors) { BDRVRawState *s = bs->opaque; int ret; - + lseek(s->fd, sector_num * 512, SEEK_SET); ret = write(s->fd, buf, nb_sectors * 512); - if (ret != nb_sectors * 512) + if (ret != nb_sectors * 512) return -1; return 0; } @@ -521,7 +535,7 @@ static int raw_create(const char *filena if (flags || backing_file) return -ENOTSUP; - fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, 0644); if (fd < 0) return -EIO; diff -r dc213d745642 tools/ioemu/block_int.h --- a/tools/ioemu/block_int.h Mon May 15 16:32:09 2006 +0100 +++ b/tools/ioemu/block_int.h Thu May 25 14:57:13 2006 -0600 @@ -1,8 +1,8 @@ /* * QEMU System Emulator block driver - * + * * Copyright (c) 2003 Fabrice Bellard - * + * * 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 @@ -24,36 +24,22 @@ #ifndef BLOCK_INT_H #define BLOCK_INT_H -struct BlockDriver { - const char *format_name; - int instance_size; - int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename); - int (*bdrv_open)(BlockDriverState *bs, const char *filename); - int (*bdrv_read)(BlockDriverState *bs, int64_t sector_num, - uint8_t *buf, int nb_sectors); - int (*bdrv_write)(BlockDriverState *bs, int64_t sector_num, - const uint8_t *buf, int nb_sectors); - void (*bdrv_close)(BlockDriverState *bs); - int (*bdrv_create)(const char *filename, int64_t total_sectors, - const char *backing_file, int flags); - int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num, - int nb_sectors, int *pnum); - int (*bdrv_set_key)(BlockDriverState *bs, const char *key); - struct BlockDriver *next; -}; +struct BlockDriver; -struct BlockDriverState { +typedef struct BlockDriverState { int64_t total_sectors; int read_only; /* if true, the media is read only */ int inserted; /* if true, the media is present */ int removable; /* if true, the media can be removed */ int locked; /* if true, the media cannot temporarily be ejected */ int encrypted; /* if true, the media is encrypted */ + int media_instance; + int shdev_el; /* event callback when inserting/removing */ void (*change_cb)(void *opaque); void *change_opaque; - BlockDriver *drv; + struct BlockDriver *drv; void *opaque; int boot_sector_enabled; @@ -63,15 +49,34 @@ struct BlockDriverState { char backing_file[1024]; /* if non zero, the image is a diff of this file image */ int is_temporary; - - BlockDriverState *backing_hd; - + + struct BlockDriverState *backing_hd; + /* NOTE: the following infos are only hints for real hardware drivers. They are not used by the block driver */ int cyls, heads, secs; int type; char device_name[32]; - BlockDriverState *next; -}; + struct BlockDriverState *next; +} BlockDriverState; + +typedef struct BlockDriver { + const char *format_name; + int instance_size; + int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename); + int (*bdrv_open)(BlockDriverState *bs, const char *filename); + int (*bdrv_read)(BlockDriverState *bs, int64_t sector_num, + uint8_t *buf, int nb_sectors); + int (*bdrv_write)(BlockDriverState *bs, int64_t sector_num, + const uint8_t *buf, int nb_sectors); + void (*bdrv_close)(BlockDriverState *bs); + int (*bdrv_create)(const char *filename, int64_t total_sectors, + const char *backing_file, int flags); + int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num, + int nb_sectors, int *pnum); + int (*bdrv_set_key)(BlockDriverState *bs, const char *key); + struct BlockDriver *next; +} BlockDriver; + #endif /* BLOCK_INT_H */ diff -r dc213d745642 tools/ioemu/hw/ide.c --- a/tools/ioemu/hw/ide.c Mon May 15 16:32:09 2006 +0100 +++ b/tools/ioemu/hw/ide.c Thu May 25 14:57:13 2006 -0600 @@ -278,6 +278,7 @@ #define ASC_ILLEGAL_OPCODE 0x20 #define ASC_LOGICAL_BLOCK_OOR 0x21 #define ASC_INV_FIELD_IN_CMD_PACKET 0x24 +#define ASC_MEDIA_CHANGED 0x28 #define ASC_MEDIUM_NOT_PRESENT 0x3a #define ASC_SAVING_PARAMETERS_NOT_SUPPORTED 0x39 @@ -294,6 +295,7 @@ typedef struct IDEState { typedef struct IDEState { /* ide config */ int is_cdrom; + int media_changed; int cylinders, heads, sectors; int64_t nb_sectors; int mult_sectors; @@ -1132,11 +1134,34 @@ static int cdrom_read_toc_raw(IDEState * return len; } +static int cd_media_inserted(IDEState *s) +{ + int h, x = 0; + + if (s->bs->removable) { + h = open(s->bs->filename, O_NONBLOCK, O_RDONLY); + + if (h >= 0) { + x = fcntl(h, F_GETFL); + x &= ~O_NONBLOCK; + fcntl(h, F_SETFL, x); + + x = read(h, &x, sizeof(x)); + close(h); + } + } + else + x = sizeof( x ); + + return((x == sizeof(x))); +} + static void ide_atapi_cmd(IDEState *s) { const uint8_t *packet; uint8_t *buf; int max_len; + packet = s->io_buffer; buf = s->io_buffer; @@ -1150,13 +1175,28 @@ static void ide_atapi_cmd(IDEState *s) printf("\n"); } #endif + switch(s->io_buffer[0]) { case GPCMD_TEST_UNIT_READY: if (bdrv_is_inserted(s->bs)) { - ide_atapi_cmd_ok(s); + if (s->media_changed) { + s->media_changed = 0; + ide_atapi_cmd_error(s, SENSE_UNIT_ATTENTION, ASC_MEDIA_CHANGED); + } + else { + if (!cd_media_inserted(s) || shdev_media_check(s->bs)) { + bdrv_close(s->bs); + ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); + } + else + ide_atapi_cmd_ok(s); + } } else { - ide_atapi_cmd_error(s, SENSE_NOT_READY, - ASC_MEDIUM_NOT_PRESENT); + ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); + + if (cd_media_inserted(s)) { + do_insert_request(); + } } break; case GPCMD_MODE_SENSE_10: @@ -1288,6 +1328,13 @@ static void ide_atapi_cmd(IDEState *s) ASC_MEDIUM_NOT_PRESENT); break; } + + if (shdev_media_check(s->bs)) { + bdrv_close(s->bs); + ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); + break; + } + nb_sectors = (packet[6] << 16) | (packet[7] << 8) | packet[8]; lba = ube32_to_cpu(packet + 2); if (nb_sectors == 0) { @@ -1345,7 +1392,7 @@ static void ide_atapi_cmd(IDEState *s) if (eject && !start) { /* eject the disk */ - bdrv_close(s->bs); + do_eject(1, s->bs->device_name); } ide_atapi_cmd_ok(s); } @@ -1372,6 +1419,13 @@ static void ide_atapi_cmd(IDEState *s) ASC_MEDIUM_NOT_PRESENT); break; } + + if (shdev_media_check(s->bs)) { + bdrv_close(s->bs); + ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); + break; + } + max_len = ube16_to_cpu(packet + 7); format = packet[9] >> 6; msf = (packet[1] >> 1) & 1; @@ -1444,9 +1498,9 @@ static void cdrom_change_cb(void *opaque IDEState *s = opaque; int64_t nb_sectors; - /* XXX: send interrupt too */ bdrv_get_geometry(s->bs, &nb_sectors); s->nb_sectors = nb_sectors; + s->media_changed = 1; } static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) @@ -1631,6 +1685,7 @@ static void ide_ioport_write(void *opaqu ide_set_signature(s); s->status = 0x00; /* NOTE: READY is _not_ set */ s->error = 0x01; + s->media_changed = 0; break; case WIN_PACKETCMD: if (!s->is_cdrom) diff -r dc213d745642 tools/ioemu/monitor.c --- a/tools/ioemu/monitor.c Mon May 15 16:32:09 2006 +0100 +++ b/tools/ioemu/monitor.c Thu May 25 14:57:13 2006 -0600 @@ -1,8 +1,8 @@ /* * QEMU monitor - * + * * Copyright (c) 2003-2004 Fabrice Bellard - * + * * 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 @@ -23,6 +23,7 @@ */ #include "vl.h" #include +#include //#define DEBUG //#define DEBUG_COMPLETION @@ -33,7 +34,7 @@ /* * Supported types: - * + * * 'F' filename * 'B' block device name * 's' string (accept optional quote) @@ -66,7 +67,7 @@ void term_flush(void) { if (term_outbuf_index > 0) { if(monitor_hd) - qemu_chr_write(monitor_hd, term_outbuf, term_outbuf_index); + qemu_chr_write(monitor_hd, (const uint8_t *)term_outbuf, term_outbuf_index); else fwrite(term_outbuf, term_outbuf_index, 1, stderr); term_outbuf_index = 0; @@ -240,7 +241,7 @@ static const KeyDef key_defs[] = { static const KeyDef key_defs[] = { { 0x2a, "shift" }, { 0x36, "shift_r" }, - + { 0x38, "alt" }, { 0xb8, "alt_r" }, { 0x1d, "ctrl" }, @@ -293,7 +294,7 @@ static const KeyDef key_defs[] = { { 0x30, "b" }, { 0x31, "n" }, { 0x32, "m" }, - + { 0x39, "spc" }, { 0x3a, "caps_lock" }, { 0x3b, "f1" }, @@ -348,7 +349,7 @@ static void do_send_key(const char *stri uint8_t keycodes[16]; const char *p; int nb_keycodes, keycode, i; - + nb_keycodes = 0; p = string; while (*p != '\0') { @@ -387,7 +388,7 @@ static void do_send_key(const char *stri } -static int eject_device(BlockDriverState *bs, int force) +static int eject_logical_device(BlockDriverState *bs, int force) { if (bdrv_is_inserted(bs)) { if (!force) { @@ -405,23 +406,57 @@ static int eject_device(BlockDriverState return 0; } -static void do_eject(int force, const char *filename) +void do_eject(int force, const char *device) { char cmd[1024]; BlockDriverState *bs; - bs = bdrv_find(filename); + bs = bdrv_find_by_device(device); + if (!bs) { - term_printf("device not found\n"); + term_printf("'%s' not found\n", device); return; } - eject_device(bs, force); - sprintf(cmd, "eject %s", filename); - system(cmd); - -} - -static void do_change(const char *device, const char *filename) + + if (eject_logical_device(bs, force) == 0) { + shdev_eject_notice(bs); + sprintf(cmd, "eject %s", bs->filename); + system(cmd); + } +} + +void do_insert(const char *device) +{ + BlockDriverState *bs; + + bs = bdrv_find_by_device(device); + + if (!bs) { + term_printf("'%s' not found\n", device); + return; + } + + if (!bs->removable) { + term_printf("'%s' not removable\n", device); + return; + } + + if (bs->inserted) { + term_printf("'%s' is already inserted\n", device); + return; + } + + bdrv_open(bs, bs->filename, 0); +} + +static int find_bs_by_type(BlockDriverState *bs, void *opaque) +{ + int *type = (int *)opaque; + + return( (bs->type == *type) ); +} + +static void do_change_source(const char *device, const char *filename) { BlockDriverState *bs; #if 0 @@ -429,14 +464,18 @@ static void do_change(const char *device char password[256]; #endif - bs = bdrv_find(device); + bs = bdrv_find_by_device(device); + if (!bs) { term_printf("device not found\n"); return; } - if (eject_device(bs, 0) < 0) + + if (eject_logical_device(bs, 0) < 0) return; - bdrv_open(bs, filename, 0); + + do_insert(bs->device_name); + #if 0 if (bdrv_is_encrypted(bs)) { term_printf("%s is encrypted.\n", device); @@ -448,6 +487,20 @@ static void do_change(const char *device } } #endif +} + +void do_insert_request() +{ + BlockDriverState *bs = NULL; + int type = BDRV_TYPE_CDROM; + + bs = bdrv_find_bs(find_bs_by_type, &type); + + if (bs) { + do_change_source(bs->device_name, bs->filename); + } + else + term_printf("Did not find cdrom bs.\n"); } static void do_screen_dump(const char *filename) @@ -482,17 +535,19 @@ static term_cmd_t term_cmds[] = { "", "quit the emulator" }, { "eject", "-fB", do_eject, "[-f] device", "eject a removable media (use -f to force it)" }, - { "change", "BF", do_change, - "device filename", "change a removable media" }, + { "insert", "B", do_insert, + "device", "notifies qemu of inserted removable media." }, + { "change", "BF", do_change_source, + "device filename", "change source for virtual removable-media device." }, { "screendump", "F", do_screen_dump, "filename", "save screen into PPM image 'filename'" }, { "log", "s", do_log, "item1[,...]", "activate logging of the specified items to '/tmp/qemu.log'" }, { "q|quit", "", do_quit, "", "quit the emulator" }, - { "sendkey", "s", do_send_key, + { "sendkey", "s", do_send_key, "keys", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1')" }, - { NULL, NULL, }, + { NULL, NULL, }, }; static term_cmd_t info_cmds[] = { @@ -596,7 +651,7 @@ static void monitor_handle_command(const #ifdef DEBUG term_printf("command='%s'\n", cmdline); #endif - + /* extract the command name */ p = cmdline; q = cmdname; @@ -612,10 +667,10 @@ static void monitor_handle_command(const len = sizeof(cmdname) - 1; memcpy(cmdname, pstart, len); cmdname[len] = '\0'; - + /* find the command */ for(cmd = term_cmds; cmd->name != NULL; cmd++) { - if (compare_cmd(cmdname, cmd->name)) + if (compare_cmd(cmdname, cmd->name)) goto found; } term_printf("unknown command: '%s'\n", cmdname); @@ -624,7 +679,7 @@ static void monitor_handle_command(const for(i = 0; i < MAX_ARGS; i++) str_allocated[i] = NULL; - + /* parse the parameters */ typestr = cmd->args_type; nb_args = 0; @@ -717,7 +772,7 @@ static void monitor_handle_command(const while (isspace(*p)) p++; if (*p != '\0') { - term_printf("%s: extraneous characters at the end of line\n", + term_printf("%s: extraneous characters at the end of line\n", cmdname); goto fail; } diff -r dc213d745642 tools/ioemu/target-i386-dm/Makefile --- a/tools/ioemu/target-i386-dm/Makefile Mon May 15 16:32:09 2006 +0100 +++ b/tools/ioemu/target-i386-dm/Makefile Thu May 25 14:57:13 2006 -0600 @@ -250,7 +250,7 @@ endif endif # must use static linking to avoid leaving stuff in virtual address space -VL_OBJS=vl.o exec.o monitor.o osdep.o block.o readline.o pci.o console.o +VL_OBJS=vl.o exec.o monitor.o shdev.o osdep.o block.o readline.o pci.o console.o VL_OBJS+=block-cow.o block-qcow.o block-vmdk.o block-cloop.o aes.o #VL_OBJS+= block-cloop.o diff -r dc213d745642 tools/ioemu/vl.c --- a/tools/ioemu/vl.c Mon May 15 16:32:09 2006 +0100 +++ b/tools/ioemu/vl.c Thu May 25 14:57:13 2006 -0600 @@ -818,7 +818,7 @@ static void init_timers(void) { /* get times() syscall frequency */ timer_freq = sysconf(_SC_CLK_TCK); - + #ifndef TARGET_HVM /* timer signal */ sigfillset(&act.sa_mask); @@ -887,7 +887,7 @@ void qemu_chr_printf(CharDriverState *s, va_list ap; va_start(ap, fmt); vsnprintf(buf, sizeof(buf), fmt, ap); - qemu_chr_write(s, buf, strlen(buf)); + qemu_chr_write(s, (uint8_t *) buf, strlen(buf)); va_end(ap); } @@ -954,7 +954,7 @@ static int unix_write(int fd, const uint fd_set writefds; struct timeval timeout; - max_fd = fd; + max_fd = fd; len = len1; while (len > 0) { @@ -1900,7 +1900,7 @@ int qemu_savevm(const char *filename) /* ID string */ len = strlen(se->idstr); qemu_put_byte(f, len); - qemu_put_buffer(f, se->idstr, len); + qemu_put_buffer(f, (uint8_t *)se->idstr, len); qemu_put_be32(f, se->instance_id); qemu_put_be32(f, se->version_id); @@ -1974,7 +1974,7 @@ int qemu_loadvm(const char *filename) len = qemu_get_byte(f); if (feof(f)) break; - qemu_get_buffer(f, idstr, len); + qemu_get_buffer(f, (uint8_t *)idstr, len); idstr[len] = '\0'; instance_id = qemu_get_be32(f); version_id = qemu_get_be32(f); @@ -2533,7 +2533,7 @@ int main(int argc, char **argv) #ifdef CONFIG_GDBSTUB int use_gdbstub, gdbstub_port; #endif - int i, has_cdrom; + int i, has_cdrom = 0; int snapshot, linux_boot; CPUState *env; const char *initrd_filename; @@ -2553,6 +2553,8 @@ int main(int argc, char **argv) char qemu_dm_logfilename[64]; const char *loadvm = NULL; unsigned long nr_pages, *page_array; + int dev_type; + char buf[64]; extern void *shared_page; #if !defined(CONFIG_SOFTMMU) @@ -2579,7 +2581,6 @@ int main(int argc, char **argv) vncconnect=NULL; kernel_filename = NULL; kernel_cmdline = ""; - has_cdrom = 1; cyls = heads = secs = 0; pstrcpy(monitor_device, sizeof(monitor_device), "vc"); @@ -2642,12 +2643,6 @@ int main(int argc, char **argv) case QEMU_OPTION_initrd: initrd_filename = optarg; break; - case QEMU_OPTION_hda: - hd_filename[0] = optarg; - break; - case QEMU_OPTION_hdb: - hd_filename[1] = optarg; - break; case QEMU_OPTION_snapshot: snapshot = 1; break; @@ -2720,15 +2715,56 @@ int main(int argc, char **argv) } } break; + case QEMU_OPTION_hda: + if (hd_filename[0]) { + fprintf(stderr, + "qemu: virtual device 'hd%c' already defined as %s\n", + 'a', + hd_filename[0] ); + break; + } + hd_filename[0] = optarg; + break; + case QEMU_OPTION_hdb: + if (hd_filename[1]) { + fprintf(stderr, + "qemu: virtual device 'hd%c' already defined as %s\n", + 'b', + hd_filename[1] ); + break; + } + hd_filename[1] = optarg; + break; case QEMU_OPTION_hdc: + if (hd_filename[2]) { + fprintf(stderr, + "qemu: virtual device 'hd%c' already defined as %s\n", + 'c', + hd_filename[2] ); + break; + } hd_filename[2] = optarg; - has_cdrom = 0; break; case QEMU_OPTION_hdd: + if (hd_filename[3]) { + fprintf(stderr, + "qemu: virtual device 'hd%c' already defined as %s\n", + 'd', + hd_filename[3] ); + break; + } hd_filename[3] = optarg; break; case QEMU_OPTION_cdrom: - hd_filename[2] = optarg; + if (hd_filename[CDROM_DISK_POSITION]) { + fprintf(stderr, + "qemu: virtual device 'hd%c' for cdrom " + "is already defined as %s\n", + 'a' + CDROM_DISK_POSITION, + hd_filename[CDROM_DISK_POSITION] ); + break; + } + hd_filename[CDROM_DISK_POSITION] = optarg; has_cdrom = 1; break; case QEMU_OPTION_boot: @@ -2944,7 +2980,7 @@ int main(int argc, char **argv) linux_boot = (kernel_filename != NULL); if ( !linux_boot && hd_filename[0] == '\0' && - hd_filename[2] == '\0' && fd_filename[0] == '\0' ) + hd_filename[CDROM_DISK_POSITION] == '\0' && fd_filename[0] == '\0' ) help(); /* boot to cd by default if no hard disk */ @@ -3074,59 +3110,55 @@ int main(int argc, char **argv) fprintf(logfile, "shared page at pfn:%lx, mfn: %lx\n", (nr_pages-1), (page_array[nr_pages - 1])); - /* we always create the cdrom drive, even if no disk is there */ bdrv_init(); - if (has_cdrom) { - int fd; - if ( (fd = open(hd_filename[2], O_RDONLY | O_BINARY)) < 0) { - hd_filename[2]=NULL; - bs_table[2]=NULL; - fprintf(logfile, "Could not open CD %s.\n", hd_filename[i]); - } - else { - close(fd); - bs_table[2] = bdrv_new("cdrom"); - bdrv_set_type_hint(bs_table[2], BDRV_TYPE_CDROM); - } - } + + shdev_init(); /* open the virtual block devices */ for(i = 0; i < MAX_DISKS; i++) { if (hd_filename[i]) { - if (!bs_table[i]) { - char buf[64]; + if ((i == CDROM_DISK_POSITION) && has_cdrom) { + snprintf(buf, sizeof(buf), "cdrom"); + dev_type = BDRV_TYPE_CDROM; + } + else { snprintf(buf, sizeof(buf), "hd%c", i + 'a'); - bs_table[i] = bdrv_new(buf); + dev_type = BDRV_TYPE_HD; } + + bs_table[i] = bdrv_new(buf); + + bdrv_set_type_hint(bs_table[i], dev_type); + + if (bs_table[i]->removable) + shdev_report_device(bs_table[i], hd_filename[i]); + if (bdrv_open(bs_table[i], hd_filename[i], snapshot) < 0) { + if (bs_table[i]->removable) + continue; + fprintf(stderr, "qemu: could not open hard disk image '%s'\n", hd_filename[i]); exit(1); } + if (i == 0 && cyls != 0) bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs); } } - /* we always create at least one floppy disk */ - fd_table[0] = bdrv_new("fda"); - bdrv_set_type_hint(fd_table[0], BDRV_TYPE_FLOPPY); - for(i = 0; i < MAX_FD; i++) { if (fd_filename[i]) { if (!fd_table[i]) { - char buf[64]; snprintf(buf, sizeof(buf), "fd%c", i + 'a'); fd_table[i] = bdrv_new(buf); bdrv_set_type_hint(fd_table[i], BDRV_TYPE_FLOPPY); + shdev_report_device(fd_table[i], fd_filename[i]); } - if (fd_filename[i] != '\0') { - if (bdrv_open(fd_table[i], fd_filename[i], snapshot) < 0) { - fprintf(stderr, "qemu: could not open floppy disk image '%s'\n", + + if (bdrv_open(fd_table[i], fd_filename[i], snapshot) < 0) + fprintf(stderr, "qemu: could not open floppy disk '%s'\n", fd_filename[i]); - exit(1); - } - } } } diff -r dc213d745642 tools/ioemu/vl.h --- a/tools/ioemu/vl.h Mon May 15 16:32:09 2006 +0100 +++ b/tools/ioemu/vl.h Thu May 25 14:57:13 2006 -0600 @@ -1,8 +1,8 @@ /* * QEMU System Emulator header - * + * * Copyright (c) 2003 Fabrice Bellard - * + * * 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 @@ -37,9 +37,11 @@ #include #include #include +#include #include "audio/audio.h" #include "xenctrl.h" #include "xs.h" + #ifndef O_LARGEFILE #define O_LARGEFILE 0 @@ -147,6 +149,8 @@ extern int graphic_depth; #define BIOS_SIZE ((256 + 64) * 1024) #endif +#define CDROM_DISK_POSITION 2 + /* keyboard/mouse support */ #define MOUSE_EVENT_LBUTTON 0x01 @@ -192,9 +196,9 @@ typedef void IOReadHandler(void *opaque, typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size); typedef int IOCanRWHandler(void *opaque); -int qemu_add_fd_read_handler(int fd, IOCanRWHandler *fd_can_read, +int qemu_add_fd_read_handler(int fd, IOCanRWHandler *fd_can_read, IOReadHandler *fd_read, void *opaque); -int qemu_add_fd_event_read_handler(int fd, IOCanRWHandler *fd_can_read, +int qemu_add_fd_event_read_handler(int fd, IOCanRWHandler *fd_can_read, IOReadHandler *fd_read, void *opaque); void qemu_del_fd_read_handler(int fd); @@ -207,8 +211,8 @@ typedef void IOEventHandler(void *opaque typedef struct CharDriverState { int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len); - void (*chr_add_read_handler)(struct CharDriverState *s, - IOCanRWHandler *fd_can_read, + void (*chr_add_read_handler)(struct CharDriverState *s, + IOCanRWHandler *fd_can_read, IOReadHandler *fd_read, void *opaque); IOEventHandler *chr_event; void (*chr_send_event)(struct CharDriverState *chr, int event); @@ -218,11 +222,11 @@ void qemu_chr_printf(CharDriverState *s, void qemu_chr_printf(CharDriverState *s, const char *fmt, ...); int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len); void qemu_chr_send_event(CharDriverState *s, int event); -void qemu_chr_add_read_handler(CharDriverState *s, - IOCanRWHandler *fd_can_read, +void qemu_chr_add_read_handler(CharDriverState *s, + IOCanRWHandler *fd_can_read, IOReadHandler *fd_read, void *opaque); void qemu_chr_add_event_handler(CharDriverState *s, IOEventHandler *chr_event); - + /* consoles */ typedef struct DisplayState DisplayState; @@ -250,10 +254,10 @@ typedef struct NetDriverState { int index; /* index number in QEMU */ uint8_t macaddr[6]; char ifname[16]; - void (*send_packet)(struct NetDriverState *nd, + void (*send_packet)(struct NetDriverState *nd, const uint8_t *buf, int size); - void (*add_read_packet)(struct NetDriverState *nd, - IOCanRWHandler *fd_can_read, + void (*add_read_packet)(struct NetDriverState *nd, + IOCanRWHandler *fd_can_read, IOReadHandler *fd_read, void *opaque); /* tun specific data */ int fd; @@ -264,7 +268,7 @@ extern NetDriverState nd_table[MAX_NICS] extern NetDriverState nd_table[MAX_NICS]; void qemu_send_packet(NetDriverState *nd, const uint8_t *buf, int size); -void qemu_add_read_packet(NetDriverState *nd, IOCanRWHandler *fd_can_read, +void qemu_add_read_packet(NetDriverState *nd, IOCanRWHandler *fd_can_read, IOReadHandler *fd_read, void *opaque); /* timers */ @@ -361,8 +365,8 @@ typedef int LoadStateHandler(QEMUFile *f int qemu_loadvm(const char *filename); int qemu_savevm(const char *filename); -int register_savevm(const char *idstr, - int instance_id, +int register_savevm(const char *idstr, + int instance_id, int version_id, SaveStateHandler *save_state, LoadStateHandler *load_state, @@ -374,8 +378,6 @@ void port_e9_init(void); void port_e9_init(void); /* block.c */ -typedef struct BlockDriverState BlockDriverState; -typedef struct BlockDriver BlockDriver; extern BlockDriver bdrv_raw; extern BlockDriver bdrv_cow; @@ -385,7 +387,7 @@ extern BlockDriver bdrv_cloop; void bdrv_init(void); BlockDriver *bdrv_find_format(const char *format_name); -int bdrv_create(BlockDriver *drv, +int bdrv_create(BlockDriver *drv, const char *filename, int64_t size_in_sectors, const char *backing_file, int flags); BlockDriverState *bdrv_new(const char *device_name); @@ -394,9 +396,9 @@ int bdrv_open2(BlockDriverState *bs, con int bdrv_open2(BlockDriverState *bs, const char *filename, int snapshot, BlockDriver *drv); void bdrv_close(BlockDriverState *bs); -int bdrv_read(BlockDriverState *bs, int64_t sector_num, +int bdrv_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors); -int bdrv_write(BlockDriverState *bs, int64_t sector_num, +int bdrv_write(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors); void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr); int bdrv_commit(BlockDriverState *bs); @@ -406,10 +408,10 @@ void bdrv_set_boot_sector(BlockDriverSta #define BDRV_TYPE_CDROM 1 #define BDRV_TYPE_FLOPPY 2 -void bdrv_set_geometry_hint(BlockDriverState *bs, +void bdrv_set_geometry_hint(BlockDriverState *bs, int cyls, int heads, int secs); void bdrv_set_type_hint(BlockDriverState *bs, int type); -void bdrv_get_geometry_hint(BlockDriverState *bs, +void bdrv_get_geometry_hint(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs); int bdrv_get_type_hint(BlockDriverState *bs); int bdrv_is_removable(BlockDriverState *bs); @@ -417,15 +419,17 @@ int bdrv_is_inserted(BlockDriverState *b int bdrv_is_inserted(BlockDriverState *bs); int bdrv_is_locked(BlockDriverState *bs); void bdrv_set_locked(BlockDriverState *bs, int locked); -void bdrv_set_change_cb(BlockDriverState *bs, +void bdrv_set_change_cb(BlockDriverState *bs, void (*change_cb)(void *opaque), void *opaque); void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size); void bdrv_info(void); -BlockDriverState *bdrv_find(const char *name); +BlockDriverState *bdrv_find_bs(int (*it)(BlockDriverState *bs, void *opaque), void *opaque); +BlockDriverState *bdrv_find_by_device(const char *name); +BlockDriverState *bdrv_find_by_filename(const char *name); void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque); int bdrv_is_encrypted(BlockDriverState *bs); int bdrv_set_key(BlockDriverState *bs, const char *key); -void bdrv_iterate_format(void (*it)(void *opaque, const char *name), +void bdrv_iterate_format(void (*it)(void *opaque, const char *name), void *opaque); const char *bdrv_get_device_name(BlockDriverState *bs); @@ -441,9 +445,9 @@ typedef void (IOPortWriteFunc)(void *opa typedef void (IOPortWriteFunc)(void *opaque, uint32_t address, uint32_t data); typedef uint32_t (IOPortReadFunc)(void *opaque, uint32_t address); -int register_ioport_read(int start, int length, int size, +int register_ioport_read(int start, int length, int size, IOPortReadFunc *func, void *opaque); -int register_ioport_write(int start, int length, int size, +int register_ioport_write(int start, int length, int size, IOPortWriteFunc *func, void *opaque); void isa_unassign_ioport(int start, int length); @@ -456,11 +460,11 @@ typedef struct PCIBus PCIBus; typedef struct PCIBus PCIBus; typedef struct PCIDevice PCIDevice; -typedef void PCIConfigWriteFunc(PCIDevice *pci_dev, +typedef void PCIConfigWriteFunc(PCIDevice *pci_dev, uint32_t address, uint32_t data, int len); -typedef uint32_t PCIConfigReadFunc(PCIDevice *pci_dev, +typedef uint32_t PCIConfigReadFunc(PCIDevice *pci_dev, uint32_t address, int len); -typedef void PCIMapIORegionFunc(PCIDevice *pci_dev, int region_num, +typedef void PCIMapIORegionFunc(PCIDevice *pci_dev, int region_num, uint32_t addr, uint32_t size, int type); #define PCI_ADDRESS_SPACE_MEM 0x00 @@ -485,7 +489,7 @@ struct PCIDevice { int devfn; char name[64]; PCIIORegion io_regions[PCI_NUM_REGIONS]; - + /* do not access the following fields */ PCIConfigReadFunc *config_read; PCIConfigWriteFunc *config_write; @@ -494,18 +498,18 @@ struct PCIDevice { PCIDevice *pci_register_device(PCIBus *bus, const char *name, int instance_size, int devfn, - PCIConfigReadFunc *config_read, + PCIConfigReadFunc *config_read, PCIConfigWriteFunc *config_write); -void pci_register_io_region(PCIDevice *pci_dev, int region_num, - uint32_t size, int type, +void pci_register_io_region(PCIDevice *pci_dev, int region_num, + uint32_t size, int type, PCIMapIORegionFunc *map_func); void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level); -uint32_t pci_default_read_config(PCIDevice *d, +uint32_t pci_default_read_config(PCIDevice *d, uint32_t address, int len); -void pci_default_write_config(PCIDevice *d, +void pci_default_write_config(PCIDevice *d, uint32_t address, uint32_t val, int len); void generic_pci_save(QEMUFile* f, void *opaque); int generic_pci_load(QEMUFile* f, void *opaque, int version_id); @@ -553,7 +557,7 @@ static inline void dpy_resize(DisplaySta s->dpy_resize(s, w, h); } -int vga_initialize(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, +int vga_initialize(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, unsigned long vga_ram_offset, int vga_ram_size); void vga_update_display(void); void vga_invalidate_display(void); @@ -564,9 +568,9 @@ void vnc_display_init(DisplayState *ds, long port, const char* connect); /* cirrus_vga.c */ -void pci_cirrus_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, +void pci_cirrus_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, unsigned long vga_ram_offset, int vga_ram_size); -void isa_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base, +void isa_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base, unsigned long vga_ram_offset, int vga_ram_size); /* sdl.c */ @@ -612,7 +616,7 @@ extern BlockDriverState *fd_table[MAX_FD typedef struct fdctrl_t fdctrl_t; -fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, +fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, uint32_t io_base, BlockDriverState **fds); int fdctrl_get_drive_type(fdctrl_t *fdctrl, int drive_num); @@ -783,9 +787,9 @@ int adb_request(ADBBusState *s, uint8_t const uint8_t *buf, int len); int adb_poll(ADBBusState *s, uint8_t *buf_out); -ADBDevice *adb_register_device(ADBBusState *s, int devaddr, - ADBDeviceRequest *devreq, - ADBDeviceReset *devreset, +ADBDevice *adb_register_device(ADBBusState *s, int devaddr, + ADBDeviceRequest *devreq, + ADBDeviceReset *devreset, void *opaque); void adb_kbd_init(ADBBusState *bus); void adb_mouse_init(ADBBusState *bus); @@ -796,6 +800,15 @@ int cuda_init(openpic_t *openpic, int ir int cuda_init(openpic_t *openpic, int irq); #endif /* defined(QEMU_TOOL) */ + +/* shdev.h */ + +int shdev_init(void); +int shdev_report_device(BlockDriverState *bs, const char *name); +void shdev_set_media_instance(BlockDriverState *bs); +void shdev_eject_notice(BlockDriverState *bs); +inline int shdev_media_check(BlockDriverState *bs); +void do_info_shdev(void); /* monitor.c */ void monitor_init(CharDriverState *hd, int show_banner); @@ -804,6 +817,8 @@ void term_printf(const char *fmt, ...) _ void term_printf(const char *fmt, ...) __attribute__ ((__format__ (__printf__, 1, 2))); void term_flush(void); void term_print_help(void); +void do_insert_request(void); +void do_eject(int force, const char *device); /* readline.c */ typedef void ReadLineFunc(void *opaque, const char *str);