]> xenbits.xensource.com Git - qemu-xen-4.2-testing.git/commitdiff
Merge branch 'upstream' into qemu
authorIan Jackson <ian.jackson@eu.citrix.com>
Thu, 16 Oct 2008 16:37:38 +0000 (17:37 +0100)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Thu, 16 Oct 2008 16:37:38 +0000 (17:37 +0100)
Conflicts:

.gitignore
Makefile
audio/sys-queue.h
block-raw-posix.c
block.c
block.h
configure
hw/ide.c
hw/usb-uhci.c
osdep.c
osdep.h
qemu_socket.h
usb-linux.c
vl.c

30 files changed:
1  2 
.gitignore
Makefile
audio/audio.c
block-cow.c
block-dmg.c
block-qcow.c
block-qcow2.c
block-raw-posix.c
block-raw-win32.c
block-vmdk.c
block-vvfat.c
block.c
block.h
block_int.h
configure
cutils.c
dyngen.c
hw/ide.c
hw/pci.c
hw/scsi-disk.c
linux-user/elfload.c
monitor.c
osdep.c
osdep.h
qemu-common.h
qemu_socket.h
target-ppc/translate_init.c
usb-linux.c
vl.c
vnc.c

diff --cc .gitignore
index d47fcc4c1bfb3b15d7595764099d47cf9d76bde6,e70ebab457230db35fca1067306cf58463d65cd3..76a2e648ed892277560bdce7724e94f363b7d771
@@@ -26,6 -30,4 +30,5 @@@ qemu-nbd.
  *.tp
  *.vr
  *.d
--
- *.[oa]
++*.o
 +*~
diff --cc Makefile
index 103aaf84ca16b6813fd3d29e540ce4cd93f22dae,36b36cd26aa34e8666e444adba85edbe50f248cb..2693387248e98f8b4665c15b2688c9ad936d7ae8
+++ b/Makefile
@@@ -34,10 -47,17 +47,17 @@@ recurse-all: $(SUBDIR_RULES
  #######################################################################
  # BLOCK_OBJS is code used by both qemu system emulation and qemu-img
  
- BLOCK_OBJS=cutils.o osdep.o
 -BLOCK_OBJS=cutils.o qemu-malloc.o
++BLOCK_OBJS=cutils.o osdep.o qemu-malloc.o
  BLOCK_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o
  BLOCK_OBJS+=block-dmg.o block-bochs.o block-vpc.o block-vvfat.o
- BLOCK_OBJS+=block-qcow2.o block-parallels.o
+ BLOCK_OBJS+=block-qcow2.o block-parallels.o block-nbd.o
+ BLOCK_OBJS+=nbd.o block.o aio.o
+ ifdef CONFIG_WIN32
+ BLOCK_OBJS += block-raw-win32.o
+ else
+ BLOCK_OBJS += block-raw-posix.o
+ endif
  
  ######################################################################
  # libqemu_common.a: Target independent part of system emulation. The
@@@ -156,11 -188,11 +188,11 @@@ qemu-img$(EXESUF): qemu-img.o qemu-tool
  %.o: %.c
        $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
  
+ qemu-nbd$(EXESUF):  qemu-nbd.o qemu-tool.o osdep.o $(BLOCK_OBJS)
+       $(CC) $(LDFLAGS) -o $@ $^ -lz $(LIBS)
  # dyngen host tool
 -dyngen$(EXESUF): dyngen.c
 +dyngen$(EXESUF): dyngen.c osdep.o
        $(HOST_CC) $(CFLAGS) $(CPPFLAGS) -o $@ $^
  
  clean:
diff --cc audio/audio.c
index 0273ac1b5c685b60cb5d3a60b658cbd54e132777,b3ac10e128165dbc03bcda67db6d8cad67133e01..cca77dd35afdeae2fa8954bdfa33e01782379d03
@@@ -231,11 -211,11 +211,11 @@@ static char *audio_alloc_prefix (const 
          size_t i;
          char *u = r + sizeof (qemu_prefix) - 1;
  
-         strcpy (r, qemu_prefix);
-         strcat (r, s);
+         pstrcpy (r, len + sizeof (qemu_prefix), qemu_prefix);
+         pstrcat (r, len + sizeof (qemu_prefix), s);
  
          for (i = 0; i < len; ++i) {
 -            u[i] = toupper (u[i]);
 +            u[i] = CTYPE(toupper, u[i]);
          }
      }
      return r;
@@@ -489,10 -470,10 +470,10 @@@ static void audio_process_options (cons
  
          /* copy while upper-casing, including trailing zero */
          for (i = 0; i <= preflen; ++i) {
 -            optname[i + sizeof (qemu_prefix) - 1] = toupper (prefix[i]);
 +            optname[i + sizeof (qemu_prefix) - 1] = CTYPE(toupper, prefix[i]);
          }
-         strcat (optname, "_");
-         strcat (optname, opt->name);
+         pstrcat (optname, optlen, "_");
+         pstrcat (optname, optlen, opt->name);
  
          def = 1;
          switch (opt->tag) {
diff --cc block-cow.c
index 6c0d657718c13a8f9b1a712cb3c5a9e248d2ceb9,9e7b64602fc943bbce608de57568cec5a00c88ca..777d8a581706352454b534b3c24973589d931c51
@@@ -246,10 -246,10 +246,12 @@@ static int cow_create(const char *filen
      return 0;
  }
  
--static void cow_flush(BlockDriverState *bs)
++static int cow_flush(BlockDriverState *bs)
  {
      BDRVCowState *s = bs->opaque;
--    fsync(s->fd);
++    if (fsync(s->fd))
++        return errno;
++    return 0;
  }
  
  BlockDriver bdrv_cow = {
diff --cc block-dmg.c
Simple merge
diff --cc block-qcow.c
Simple merge
diff --cc block-qcow2.c
Simple merge
index c9f01255bd0ed6be533d18fc37a8a3191911830c,83a358cd4dd45f2eda72049568b927d5753cc197..92b4038e72965b7eeafa17c790c785d459b3f5d7
@@@ -602,8 -894,8 +910,9 @@@ BlockDriver bdrv_raw = 
      .bdrv_aio_read = raw_aio_read,
      .bdrv_aio_write = raw_aio_write,
      .bdrv_aio_cancel = raw_aio_cancel,
++    .bdrv_aio_flush = raw_aio_flush,
      .aiocb_size = sizeof(RawAIOCB),
-     .protocol_name = "file",
+ #endif
      .bdrv_pread = raw_pread,
      .bdrv_pwrite = raw_pwrite,
      .bdrv_truncate = raw_truncate,
@@@ -957,8 -1249,8 +1268,9 @@@ BlockDriver bdrv_host_device = 
      .bdrv_aio_read = raw_aio_read,
      .bdrv_aio_write = raw_aio_write,
      .bdrv_aio_cancel = raw_aio_cancel,
 +    .bdrv_aio_flush = raw_aio_flush,
      .aiocb_size = sizeof(RawAIOCB),
+ #endif
      .bdrv_pread = raw_pread,
      .bdrv_pwrite = raw_pwrite,
      .bdrv_getlength = raw_getlength,
index c94ad0e2927dbefb2ccb1002ff8c19aac79d9b1f,fd4a9e3a4c649f9c9f32029bcfa87a15c6841fe8..2bcebb0b4cc08b7d0cc413bd53ba7c348f99db20
@@@ -265,18 -259,13 +259,17 @@@ static void raw_aio_cancel(BlockDriverA
      /* XXX: if more than one async I/O it is not correct */
      CancelIo(s->hfile);
      qemu_aio_release(acb);
- #endif
  }
- #endif /* #if 0 */
+ #endif /* #if WIN32_AIO */
  
 -static void raw_flush(BlockDriverState *bs)
 +static int raw_flush(BlockDriverState *bs)
  {
      BDRVRawState *s = bs->opaque;
 -    FlushFileBuffers(s->hfile);
 +    int ret;
 +    ret = FlushFileBuffers(s->hfile);
 +    if (ret)
 +      return -EIO;
 +    return 0;
  }
  
  static void raw_close(BlockDriverState *bs)
diff --cc block-vmdk.c
index e49db6b9139336a2d1723f3a74174130f2302ae0,c49b67193cb61f610bf338783ccf5ef58850865f..f3b54fd24dc965f6431fb388f67ef2e53f7d9d3f
@@@ -376,9 -377,8 +377,8 @@@ static int vmdk_open(BlockDriverState *
      if (parent_open)
          // Parent must be opened as RO.
          flags = BDRV_O_RDONLY;
-     fprintf(stderr, "(VMDK) image open: flags=0x%x filename=%s\n", flags, bs->filename);
  
 -    ret = bdrv_file_open(&s->hd, filename, flags);
 +    ret = bdrv_file_open(&s->hd, filename, flags | BDRV_O_EXTENDABLE);
      if (ret < 0)
          return ret;
      if (bdrv_pread(s->hd, 0, &magic, sizeof(magic)) != sizeof(magic))
@@@ -810,15 -810,15 +812,15 @@@ static void vmdk_close(BlockDriverStat
  
      qemu_free(s->l1_table);
      qemu_free(s->l2_cache);
-     bdrv_delete(s->hd);
      // try to close parent image, if exist
      vmdk_parent_close(s->hd);
+     bdrv_delete(s->hd);
  }
  
 -static void vmdk_flush(BlockDriverState *bs)
 +static int vmdk_flush(BlockDriverState *bs)
  {
      BDRVVmdkState *s = bs->opaque;
 -    bdrv_flush(s->hd);
 +    return bdrv_flush(s->hd);
  }
  
  BlockDriver bdrv_vmdk = {
diff --cc block-vvfat.c
Simple merge
diff --cc block.c
index fcaf703237eb17fd26944dee346758cc581bf608,3eb45261643bc1f23069961efa783a0f4bcde60b..95dc4fab853cb6c7518644f560780c72b723d19c
+++ b/block.c
@@@ -125,28 -122,7 +124,28 @@@ void path_combine(char *dest, int dest_
      }
  }
  
-     
 +static int bdrv_rw_badreq_sectors(BlockDriverState *bs,
 +                              int64_t sector_num, int nb_sectors)
 +{
 +    return (
 +      nb_sectors < 0 ||
 +      nb_sectors > bs->total_sectors ||
 +      sector_num > bs->total_sectors - nb_sectors
 +      ) && !bs->extendable;
 +}
 +
 +static int bdrv_rw_badreq_bytes(BlockDriverState *bs,
 +                                int64_t offset, int count)
 +{
 +    int64_t size = bs->total_sectors << SECTOR_BITS;
 +    return (
 +      count < 0 ||
 +      count > size ||
 +      offset > size - count
 +      ) && !bs->extendable;
 +}
++ 
  static void bdrv_register(BlockDriver *bdrv)
  {
      if (!bdrv->bdrv_aio_read) {
@@@ -716,10 -690,8 +727,10 @@@ int bdrv_pread(BlockDriverState *bs, in
  
      if (!drv)
          return -ENOMEDIUM;
-     if (!drv->bdrv_pread)
-         return bdrv_pread_em(bs, offset, buf1, count1);
 +    if (bdrv_rw_badreq_bytes(bs, offset, count1))
 +      return -EDOM;
+     if (!drv->bdrv_pread)
+         return bdrv_pread_em(bs, offset, buf1, count1);
      return drv->bdrv_pread(bs, offset, buf1, count1);
  }
  
@@@ -733,10 -705,8 +744,10 @@@ int bdrv_pwrite(BlockDriverState *bs, i
  
      if (!drv)
          return -ENOMEDIUM;
-     if (!drv->bdrv_pwrite)
-         return bdrv_pwrite_em(bs, offset, buf1, count1);
 +    if (bdrv_rw_badreq_bytes(bs, offset, count1))
 +      return -EDOM;
+     if (!drv->bdrv_pwrite)
+         return bdrv_pwrite_em(bs, offset, buf1, count1);
      return drv->bdrv_pwrite(bs, offset, buf1, count1);
  }
  
@@@ -917,17 -887,51 +928,58 @@@ const char *bdrv_get_device_name(BlockD
      return bs->device_name;
  }
  
 -void bdrv_flush(BlockDriverState *bs)
 +int bdrv_flush(BlockDriverState *bs)
  {
-     if (bs->drv->bdrv_flush) 
 +    int ret = 0;
 -        bs->drv->bdrv_flush(bs);
 -    if (bs->backing_hd)
 -        bdrv_flush(bs->backing_hd);
+     if (bs->drv->bdrv_flush)
 +        ret = bs->drv->bdrv_flush(bs);
 +    if (!ret && bs->backing_hd)
 +        ret = bdrv_flush(bs->backing_hd);
 +    return ret;
  }
  
- #ifndef QEMU_IMG
 -void bdrv_flush_all(void)
++int bdrv_flush_all(void)
+ {
+     BlockDriverState *bs;
++    int ret = 0, ret1;
+     for (bs = bdrv_first; bs != NULL; bs = bs->next)
+         if (bs->drv && !bdrv_is_read_only(bs) && 
 -            (!bdrv_is_removable(bs) || bdrv_is_inserted(bs)))
 -            bdrv_flush(bs);
++            (!bdrv_is_removable(bs) || bdrv_is_inserted(bs))) {
++            ret1 = bdrv_flush(bs);
++            if (ret1) ret = ret1;
++        }
++
++    return ret;
+ }
+ /*
+  * Returns true iff the specified sector is present in the disk image. Drivers
+  * not implementing the functionality are assumed to not support backing files,
+  * hence all their sectors are reported as allocated.
+  *
+  * 'pnum' is set to the number of sectors (including and immediately following
+  * the specified sector) that are known to be in the same
+  * allocated/unallocated state.
+  *
+  * 'nb_sectors' is the max value 'pnum' should be set to.
+  */
+ int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
+       int *pnum)
+ {
+     int64_t n;
+     if (!bs->drv->bdrv_is_allocated) {
+         if (sector_num >= bs->total_sectors) {
+             *pnum = 0;
+             return 0;
+         }
+         n = bs->total_sectors - sector_num;
+         *pnum = (n < nb_sectors) ? (n) : (nb_sectors);
+         return 1;
+     }
+     return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum);
+ }
  void bdrv_info(void)
  {
      BlockDriverState *bs;
@@@ -1003,10 -1006,8 +1054,10 @@@ int bdrv_write_compressed(BlockDriverSt
      BlockDriver *drv = bs->drv;
      if (!drv)
          return -ENOMEDIUM;
-     if (!drv->bdrv_write_compressed)
-         return -ENOTSUP;
 +    if (bdrv_rw_badreq_sectors(bs, sector_num, nb_sectors))
 +      return -EDOM;
+     if (!drv->bdrv_write_compressed)
+         return -ENOTSUP;
      return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
  }
  
@@@ -1210,18 -1207,7 +1261,17 @@@ void bdrv_aio_cancel(BlockDriverAIOCB *
      drv->bdrv_aio_cancel(acb);
  }
  
 +BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs, 
 +                                 BlockDriverCompletionFunc *cb, void *opaque)
 +{
 +    BlockDriver *drv = bs->drv;
 +
 +    if (!drv)
 +        return NULL;
 +
 +    return drv->bdrv_aio_flush(bs, cb, opaque);
 +}
  
  /**************************************************************/
  /* async block device emulation */
  
@@@ -1372,7 -1303,6 +1367,21 @@@ static int bdrv_write_em(BlockDriverSta
      return async_ret;
  }
  
++static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs,
++        BlockDriverCompletionFunc *cb, void *opaque)
++{
++    BlockDriverAIOCBSync *acb;
++    int ret;
++
++    acb = qemu_aio_get(bs, cb, opaque);
++    if (!acb->bh)
++        acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
++    ret = bdrv_flush(bs);
++    acb->ret = ret;
++    qemu_bh_schedule(acb->bh);
++    return &acb->common;
++}
++
  void bdrv_init(void)
  {
      bdrv_register(&bdrv_raw);
diff --cc block.h
index 56ca9d191ce4430feadb2e87417316d39813ce41,f0129130be221ff15dffeb111161ac763c0ae20f..218c7901dbbb2f57598294ae6ca640508a152ad2
+++ b/block.h
@@@ -45,13 -48,9 +48,11 @@@ typedef struct QEMUSnapshotInfo 
                                       it (default for
                                       bdrv_file_open()) */
  #define BDRV_O_DIRECT      0x0020
 +#define BDRV_O_EXTENDABLE  0x0080 /* allow writes out of original size range;
 +                                   only effective for some drivers */
  
- #ifndef QEMU_IMG
  void bdrv_info(void);
  void bdrv_info_stats(void);
- #endif
  
  void bdrv_init(void);
  BlockDriver *bdrv_find_format(const char *format_name);
@@@ -88,21 -87,16 +89,18 @@@ BlockDriverAIOCB *bdrv_aio_read(BlockDr
  BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
                                   const uint8_t *buf, int nb_sectors,
                                   BlockDriverCompletionFunc *cb, void *opaque);
 +BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs, 
 +                                 BlockDriverCompletionFunc *cb, void *opaque);
  void bdrv_aio_cancel(BlockDriverAIOCB *acb);
  
- void qemu_aio_init(void);
- void qemu_aio_poll(void);
- void qemu_aio_flush(void);
- void qemu_aio_wait_start(void);
- void qemu_aio_wait(void);
- void qemu_aio_wait_end(void);
  int qemu_key_check(BlockDriverState *bs, const char *name);
  
  /* Ensure contents are flushed to disk.  */
 -void bdrv_flush(BlockDriverState *bs);
 -void bdrv_flush_all(void);
 +int bdrv_flush(BlockDriverState *bs);
++int bdrv_flush_all(void);
+ int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
+       int *pnum);
  
  #define BDRV_TYPE_HD     0
  #define BDRV_TYPE_CDROM  1
diff --cc block_int.h
Simple merge
diff --cc configure
index f138bec28871acebb6d534e7f5b54989e17c38aa,ba80f1c5577b27a2dc8a322018cf9f5421f0a18a..c15ffd181529b2025bc22726d04d7d1731036958
+++ b/configure
@@@ -336,17 -354,9 +354,10 @@@ for opt d
    esac
  done
  
- if [ "$bsd" = "yes" ] ; then
-     AIOLIBS="-lrt"
- elif [ "$darwin" = "yes" -o "$mingw32" = "yes" ] ; then
-     AIOLIBS=
- else
-     # Some Linux architectures (e.g. s390) don't imply -lpthread automatically.
-     AIOLIBS="-lrt -lpthread"
- fi
 +
  # default flags for all hosts
- CFLAGS="$CFLAGS -Wall -O2 -g -fno-strict-aliasing"
+ CFLAGS="$CFLAGS -O2 -g -fno-strict-aliasing"
+ CFLAGS="$CFLAGS -Wall -Wundef -Wendif-labels -Wwrite-strings"
  LDFLAGS="$LDFLAGS -g"
  if test "$werror" = "yes" ; then
  CFLAGS="$CFLAGS -Werror"
diff --cc cutils.c
Simple merge
diff --cc dyngen.c
Simple merge
diff --cc hw/ide.c
index 68c6f8596e385e51d23c690021f5acbae6887ff3,33e8b393298420b60477821ba4579a60bef4a4f9..8cf4fdc922e06475f3dafe28a923c3e10ecdc7f6
+++ b/hw/ide.c
  #define ASC_ILLEGAL_OPCODE                   0x20
  #define ASC_LOGICAL_BLOCK_OOR                0x21
  #define ASC_INV_FIELD_IN_CMD_PACKET          0x24
 +#define ASC_MEDIUM_MAY_HAVE_CHANGED          0x28
+ #define ASC_INCOMPATIBLE_FORMAT              0x30
  #define ASC_MEDIUM_NOT_PRESENT               0x3a
  #define ASC_SAVING_PARAMETERS_NOT_SUPPORTED  0x39
  
@@@ -734,7 -749,6 +752,7 @@@ static inline void ide_dma_submit_check
  static inline void ide_set_irq(IDEState *s)
  {
      BMDMAState *bm = s->bmdma;
-     if (!s->bs) return; /* yikes */
++    if (!s->bs) return; /* ouch! (see ide_flush_cb) */
      if (!(s->cmd & IDE_CMD_DISABLE_IRQ)) {
          if (bm) {
              bm->status |= BM_STATUS_INT;
@@@ -922,8 -928,6 +940,8 @@@ static void ide_read_dma_cb(void *opaqu
        return;
      }
  
-     if (!s->bs) return; /* yikes */
++    if (!s->bs) return; /* ouch! (see ide_flush_cb) */
 +
      n = s->io_buffer_size >> 9;
      sector_num = ide_get_sector(s);
      if (n > 0) {
@@@ -1048,8 -1039,6 +1066,8 @@@ static void ide_write_dma_cb(void *opaq
        return;
      }
  
-     if (!s->bs) return; /* yikes */
++    if (!s->bs) return; /* ouch! (see ide_flush_cb) */
 +
      n = s->io_buffer_size >> 9;
      sector_num = ide_get_sector(s);
      if (n > 0) {
@@@ -1096,39 -1085,6 +1114,39 @@@ static void ide_sector_write_dma(IDESta
      ide_dma_start(s, ide_write_dma_cb);
  }
  
-     if (!s->bs) return; /* yikes */
 +static void ide_device_utterly_broken(IDEState *s) {
 +    s->status |= BUSY_STAT;
 +    s->bs = NULL;
 +    /* This prevents all future commands from working.  All of the
 +     * asynchronous callbacks (and ide_set_irq, as a safety measure)
 +     * check to see whether this has happened and bail if so.
 +     */
 +}
 +
 +static void ide_flush_cb(void *opaque, int ret)
 +{
 +    IDEState *s = opaque;
 +
-         s->status = READY_STAT;
++    if (!s->bs) return; /* ouch! (see ide_flush_cb) */
 +
 +    if (ret) {
 +        /* We are completely doomed.  The IDE spec does not permit us
 +       * to return an error from a flush except via a protocol which
 +       * requires us to say where the error is and which
 +       * contemplates the guest repeating the flush attempt to
 +       * attempt flush the remaining data.  We can't support that
 +       * because f(data)sync (which is what the block drivers use
 +       * eventually) doesn't report the necessary information or
 +       * give us the necessary control.  So we make the disk vanish.
 +       */
 +      ide_device_utterly_broken(s);
 +      return;
 +    }
 +    else
++        s->status = READY_STAT | SEEK_STAT;
 +    ide_set_irq(s);
 +}
 +
  static void ide_atapi_cmd_ok(IDEState *s)
  {
      s->error = 0;
@@@ -1355,8 -1311,6 +1373,8 @@@ static void ide_atapi_cmd_read_dma_cb(v
      IDEState *s = bm->ide_if;
      int data_offset, n;
  
-     if (!s->bs) return; /* yikes */
++    if (!s->bs) return; /* ouch! (see ide_flush_cb) */
 +
      if (ret < 0) {
          ide_atapi_io_error(s, ret);
          goto eot;
@@@ -1936,8 -1974,6 +2039,8 @@@ static void cdrom_change_cb(void *opaqu
      IDEState *s = opaque;
      uint64_t nb_sectors;
  
-     if (!s->bs) return; /* yikes */
++    if (!s->bs) return; /* ouch! (see ide_flush_cb) */
 +
      /* XXX: send interrupt too */
      bdrv_get_geometry(s->bs, &nb_sectors);
      s->nb_sectors = nb_sectors;
@@@ -2041,10 -2081,14 +2149,14 @@@ static void ide_ioport_write(void *opaq
          printf("ide: CMD=%02x\n", val);
  #endif
          s = ide_if->cur_drive;
-       /* ignore commands to non existant device */
 -        /* ignore commands to non existant slave */
 -        if (s != ide_if && !s->bs)
++        /* ignore commands to non existant device */
 +        if (!s->bs)
              break;
  
+         /* Only DEVICE RESET is allowed while BSY or/and DRQ are set */
+         if ((s->status & (BUSY_STAT|DRQ_STAT)) && val != WIN_DEVICE_RESET)
+             break;
          switch(val) {
          case WIN_IDENTIFY:
              if (s->bs && !s->is_cdrom) {
diff --cc hw/pci.c
Simple merge
diff --cc hw/scsi-disk.c
Simple merge
Simple merge
diff --cc monitor.c
Simple merge
diff --cc osdep.c
index c78dc2be553091dd2226455e8a78f9b5972e2000,683aad0f0cce168368bda866a6490e073788020b..b53b9559fe4474cf5159733565692da07f4ef614
+++ b/osdep.c
  #include <malloc.h>
  #endif
  
 +#define define_readwrite(rw, cnst)                            \
 +ssize_t qemu_##rw(int fd, cnst void *buf, size_t count) {     \
 +    ssize_t got, done;                                                \
 +    done = 0;                                                 \
 +    while (count>0) {                                         \
 +      got = rw(fd, buf, count);                               \
 +      if (got == 0) { errno = 0; return done; }               \
 +      if (got < 0) {                                          \
 +          if (errno==EINTR) continue;                         \
 +          return done ? done : -1;                            \
 +      }                                                       \
 +        assert(got <= count);                                 \
 +      done += got;                                            \
 +      count -= got;                                           \
 +      buf = (cnst char*)buf + got;                            \
 +    }                                                         \
 +    return done;                                              \
 +}                                                             \
 +int qemu_##rw##_ok(int fd, cnst void *buf, size_t count) {    \
 +    ssize_t got;                                              \
 +    got = qemu_##rw(fd, buf, count);                          \
 +    if (got == count) return 1;                                       \
 +    return -1;                                                        \
 +}
 +define_readwrite(read, /* empty */)
 +define_readwrite(write, const)
 +
+ #include "qemu_socket.h"
  #if defined(_WIN32)
  void *qemu_memalign(size_t alignment, size_t size)
  {
diff --cc osdep.h
Simple merge
diff --cc qemu-common.h
index 964e203ac9756e186ecc6a6b3cd2100c99c5bd17,cc95fe62bbf7758d0d1ff4d39c8365c8edca14b9..1c5f0a4b780b5fb05d531fab37cfcc9b54426c7a
@@@ -86,18 -86,8 +86,19 @@@ int strstart(const char *str, const cha
  int stristart(const char *str, const char *val, const char **ptr);
  time_t mktimegm(struct tm *tm);
  
 +#define CTYPE(isfoobar,argumentchar) (isfoobar((unsigned char)(argumentchar)))
 +  /* One must not pass a plain `char' to isupper, toupper, et al.  If
 +   * it has the top bit set (ie, is negative if your chars are
 +   * signed), undefined behaviour results.  The <ctype.h> functions
 +   * are defined to take the value of an unsigned char, as an int.
 +   * So use this macro.  You may pass toupper et al for isfoobar.
 +   * Do not pass EOF as a character to this macro.  If you might have
 +   * EOF then you ought to have it in an int representing an unsigned
 +   * char, which is safe for the ctype macros directly.  Or test separately.
 +   * Obviously don't use this for floating point things like isnan! */
 +
  void *qemu_malloc(size_t size);
+ void *qemu_realloc(void *ptr, size_t size);
  void *qemu_mallocz(size_t size);
  void qemu_free(void *ptr);
  char *qemu_strdup(const char *str);
diff --cc qemu_socket.h
index 0609041362545ffc7980daaf4c61dceebb19f86e,ef2d88bfe9c9267c3de0fa3632534c79e256119a..6595837796b231d0004caa321b93254166747366
  #define EINTR       WSAEINTR
  #define EINPROGRESS WSAEINPROGRESS
  
 +#ifndef NO_UNIX_SOCKETS
 +#define NO_UNIX_SOCKETS 1
 +#endif
 +
+ int inet_aton(const char *cp, struct in_addr *ia);
  #else
  
  #include <sys/socket.h>
  #include <netinet/in.h>
  #include <netinet/tcp.h>
 +#ifndef NO_UNIX_SOCKETS
+ #include <arpa/inet.h>
+ #include <netdb.h>
  #include <sys/un.h>
 +#endif
  
  #define socket_error() errno
  #define closesocket(s) close(s)
Simple merge
diff --cc usb-linux.c
index 5b573f45f4c9a92069040a50472babe895db5bd7,6113a0c5fb670d6ef7e8222aab377d49908bbb45..a485671035bc80e9313b5a005dabfe321eb352cd
  #if defined(__linux__)
  #include <dirent.h>
  #include <sys/ioctl.h>
 +/* Some versions of usbdevice_fs.h need __user to be defined for them.   */
 +/* This may (harmlessly) conflict with a definition in linux/compiler.h. */
 +#define __user
+ #include <signal.h>
  #include <linux/usbdevice_fs.h>
  #include <linux/version.h>
- #include <signal.h>
+ #include "hw/usb.h"
  
  /* We redefine it to avoid version problems */
  struct usb_ctrltransfer {
@@@ -807,7 -1141,115 +1144,116 @@@ static int usb_host_scan_dev(void *opaq
                     product_id, product_name, speed);
      }
   the_end:
-     fclose(f);
+     if (f)
+         fclose(f);
+     return ret;
+ }
+ /*
+  * Read sys file-system device file
+  *
+  * @line address of buffer to put file contents in
+  * @line_size size of line
+  * @device_file path to device file (printf format string)
+  * @device_name device being opened (inserted into device_file)
+  *
+  * @return 0 failed, 1 succeeded ('line' contains data)
+  */
+ static int usb_host_read_file(char *line, size_t line_size, const char *device_file, const char *device_name)
+ {
+     FILE *f;
+     int ret = 0;
+     char filename[PATH_MAX];
+     snprintf(filename, PATH_MAX, device_file, device_name);
+     f = fopen(filename, "r");
+     if (f) {
 -        fgets(line, line_size, f);
++        if (fgets(line, line_size, f) != NULL &&
++            !ferror(f))
++            ret = 1;
+         fclose(f);
 -        ret = 1;
+     } else {
+         term_printf("husb: could not open %s\n", filename);
+     }
+     return ret;
+ }
+ /*
+  * Use /sys/bus/usb/devices/ directory to determine host's USB
+  * devices.
+  *
+  * This code is based on Robert Schiele's original patches posted to
+  * the Novell bug-tracker https://bugzilla.novell.com/show_bug.cgi?id=241950
+  */
+ static int usb_host_scan_sys(void *opaque, USBScanFunc *func)
+ {
+     DIR *dir = 0;
+     char line[1024];
+     int bus_num, addr, speed, class_id, product_id, vendor_id;
+     int ret = 0;
+     char product_name[512];
+     struct dirent *de;
+     dir = opendir(USBSYSBUS_PATH "/devices");
+     if (!dir) {
+         perror("husb: cannot open devices directory");
+         goto the_end;
+     }
+     while ((de = readdir(dir))) {
+         if (de->d_name[0] != '.' && !strchr(de->d_name, ':')) {
+             char *tmpstr = de->d_name;
+             if (!strncmp(de->d_name, "usb", 3))
+                 tmpstr += 3;
+             bus_num = atoi(tmpstr);
+             if (!usb_host_read_file(line, sizeof(line), USBSYSBUS_PATH "/devices/%s/devnum", de->d_name))
+                 goto the_end;
+             if (sscanf(line, "%d", &addr) != 1)
+                 goto the_end;
+             if (!usb_host_read_file(line, sizeof(line), USBSYSBUS_PATH "/devices/%s/bDeviceClass", de->d_name))
+                 goto the_end;
+             if (sscanf(line, "%x", &class_id) != 1)
+                 goto the_end;
+             if (!usb_host_read_file(line, sizeof(line), USBSYSBUS_PATH "/devices/%s/idVendor", de->d_name))
+                 goto the_end;
+             if (sscanf(line, "%x", &vendor_id) != 1)
+                 goto the_end;
+             if (!usb_host_read_file(line, sizeof(line), USBSYSBUS_PATH "/devices/%s/idProduct", de->d_name))
+                 goto the_end;
+             if (sscanf(line, "%x", &product_id) != 1)
+                 goto the_end;
+             if (!usb_host_read_file(line, sizeof(line), USBSYSBUS_PATH "/devices/%s/product", de->d_name)) {
+                 *product_name = 0;
+             } else {
+                 if (strlen(line) > 0)
+                     line[strlen(line) - 1] = '\0';
+                 pstrcpy(product_name, sizeof(product_name), line);
+             }
+             if (!usb_host_read_file(line, sizeof(line), USBSYSBUS_PATH "/devices/%s/speed", de->d_name))
+                 goto the_end;
+             if (!strcmp(line, "480\n"))
+                 speed = USB_SPEED_HIGH;
+             else if (!strcmp(line, "1.5\n"))
+                 speed = USB_SPEED_LOW;
+             else
+                 speed = USB_SPEED_FULL;
+             ret = func(opaque, bus_num, addr, class_id, vendor_id,
+                        product_id, product_name, speed);
+             if (ret)
+                 goto the_end;
+         }
+     }
+  the_end:
+     if (dir)
+         closedir(dir);
      return ret;
  }
  
diff --cc vl.c
index 86dbf8341f3668396e37fa2e97f5bf9323009a14,e8410a8a1b9785e59aa1791e19ccffbd80d7410d..bb1cc8d21ee9e371b529b239926af0984e1ac51f
--- 1/vl.c
--- 2/vl.c
+++ b/vl.c
@@@ -1991,25 -2128,32 +2128,13 @@@ static int send_all(int fd, const uint8
      return len1 - len;
  }
  
- void socket_set_nonblock(int fd)
- {
-     unsigned long opt = 1;
-     ioctlsocket(fd, FIONBIO, &opt);
- }
  #else
  
 -static int unix_write(int fd, const uint8_t *buf, int len1)
 -{
 -    int ret, len;
 -
 -    len = len1;
 -    while (len > 0) {
 -        ret = write(fd, buf, len);
 -        if (ret < 0) {
 -            if (errno != EINTR && errno != EAGAIN)
 -                return -1;
 -        } else if (ret == 0) {
 -            break;
 -        } else {
 -            buf += ret;
 -            len -= ret;
 -        }
 -    }
 -    return len1 - len;
 -}
 -
  static inline int send_all(int fd, const uint8_t *buf, int len1)
  {
 -    return unix_write(fd, buf, len1);
 +    return qemu_write(fd, buf, len1);
  }
- void socket_set_nonblock(int fd)
- {
-     int f;
-     f = fcntl(fd, F_GETFL);
-     fcntl(fd, F_SETFL, f | O_NONBLOCK);
- }
 +
  #endif /* !_WIN32 */
  
  #ifndef _WIN32
@@@ -2312,13 -2453,153 +2437,153 @@@ void cfmakeraw (struct termios *termios
  }
  #endif
  
- #if defined(__linux__) || defined(__sun__)
+ #if defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
+     || defined(__NetBSD__) || defined(__OpenBSD__)
+ typedef struct {
+     int fd;
+     int connected;
+     int polling;
+     int read_bytes;
+     QEMUTimer *timer;
+ } PtyCharDriver;
+ static void pty_chr_update_read_handler(CharDriverState *chr);
+ static void pty_chr_state(CharDriverState *chr, int connected);
+ static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
+ {
+     PtyCharDriver *s = chr->opaque;
+     if (!s->connected) {
+         /* guest sends data, check for (re-)connect */
+         pty_chr_update_read_handler(chr);
+         return 0;
+     }
 -    return unix_write(s->fd, buf, len);
++    return qemu_write(s->fd, buf, len);
+ }
+ static int pty_chr_read_poll(void *opaque)
+ {
+     CharDriverState *chr = opaque;
+     PtyCharDriver *s = chr->opaque;
+     s->read_bytes = qemu_chr_can_read(chr);
+     return s->read_bytes;
+ }
+ static void pty_chr_read(void *opaque)
+ {
+     CharDriverState *chr = opaque;
+     PtyCharDriver *s = chr->opaque;
+     int size, len;
+     uint8_t buf[1024];
+     len = sizeof(buf);
+     if (len > s->read_bytes)
+         len = s->read_bytes;
+     if (len == 0)
+         return;
+     size = read(s->fd, buf, len);
+     if ((size == -1 && errno == EIO) ||
+         (size == 0)) {
+         pty_chr_state(chr, 0);
+         return;
+     }
+     if (size > 0) {
+         pty_chr_state(chr, 1);
+         qemu_chr_read(chr, buf, size);
+     }
+ }
+ static void pty_chr_update_read_handler(CharDriverState *chr)
+ {
+     PtyCharDriver *s = chr->opaque;
+     qemu_set_fd_handler2(s->fd, pty_chr_read_poll,
+                          pty_chr_read, NULL, chr);
+     s->polling = 1;
+     /*
+      * Short timeout here: just need wait long enougth that qemu makes
+      * it through the poll loop once.  When reconnected we want a
+      * short timeout so we notice it almost instantly.  Otherwise
+      * read() gives us -EIO instantly, making pty_chr_state() reset the
+      * timeout to the normal (much longer) poll interval before the
+      * timer triggers.
+      */
+     qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 10);
+ }
+ static void pty_chr_state(CharDriverState *chr, int connected)
+ {
+     PtyCharDriver *s = chr->opaque;
+     if (!connected) {
+         qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
+         s->connected = 0;
+         s->polling = 0;
+         /* (re-)connect poll interval for idle guests: once per second.
+          * We check more frequently in case the guests sends data to
+          * the virtual device linked to our pty. */
+         qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 1000);
+     } else {
+         if (!s->connected)
+             qemu_chr_reset(chr);
+         s->connected = 1;
+     }
+ }
+ static void pty_chr_timer(void *opaque)
+ {
+     struct CharDriverState *chr = opaque;
+     PtyCharDriver *s = chr->opaque;
+     if (s->connected)
+         return;
+     if (s->polling) {
+         /* If we arrive here without polling being cleared due
+          * read returning -EIO, then we are (re-)connected */
+         pty_chr_state(chr, 1);
+         return;
+     }
+     /* Next poll ... */
+     pty_chr_update_read_handler(chr);
+ }
+ static void pty_chr_close(struct CharDriverState *chr)
+ {
+     PtyCharDriver *s = chr->opaque;
+     qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
+     close(s->fd);
+     qemu_free(s);
+ }
  static CharDriverState *qemu_chr_open_pty(void)
  {
+     CharDriverState *chr;
+     PtyCharDriver *s;
      struct termios tty;
-     int master_fd, slave_fd;
+     int slave_fd;
+ #if defined(__OpenBSD__)
+     char pty_name[PATH_MAX];
+ #define q_ptsname(x) pty_name
+ #else
+     char *pty_name = NULL;
+ #define q_ptsname(x) ptsname(x)
+ #endif
  
-     if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) < 0) {
+     chr = qemu_mallocz(sizeof(CharDriverState));
+     if (!chr)
+         return NULL;
+     s = qemu_mallocz(sizeof(PtyCharDriver));
+     if (!s) {
+         qemu_free(chr);
+         return NULL;
+     }
+     if (openpty(&s->fd, &slave_fd, pty_name, NULL, NULL) < 0) {
          return NULL;
      }
  
diff --cc vnc.c
Simple merge