Re: [Qemu-devel] Is realview-pb-a8 fully supported ?

2011-10-13 Thread Francis Moreau
On Wed, Oct 12, 2011 at 10:46 PM, Peter Maydell
peter.mayd...@linaro.org wrote:
 On 12 October 2011 20:39, Francis Moreau francis.m...@gmail.com wrote:
 On Wed, Oct 12, 2011 at 11:23 AM, Peter Maydell
 peter.mayd...@linaro.org wrote:
 I think the mainline kernel sources should in theory work
 (in particular if they work with 512MB then that's a good
 sign...) but I'm not a kernel expert; mostly I use other peoples'
 prebuilt ones.

 ok, but wouldn't you recommend to use the kernel from Linaro ? ;)

 Obviously those work too (and in practice they're the ones
 I test most often with). Linaro kernels will certainly have
 been tested with Versatile Express, but probably not with the
 other older ARM devboards. But if you don't need to be on the
 bleeding edge for anything then I don't think it makes much
 difference whether you use the Linaro kernel or mainline for
 an established platform like the ARM devboards.
 (more info on the aims of the linaro kernel tree here:
 https://wiki.linaro.org/WorkingGroups/Kernel/KernelTree
 )


Thanks a lot for your answers.

-- 
Francis



Re: [Qemu-devel] [PATCH v3] add add-cow file format

2011-10-13 Thread Dong Xu Wang

On Thu 13 Oct 2011 12:23:16 AM CST, Dong Xu Wang wrote:

Add add-cow file format

Signed-off-by: Dong Xu Wangwdon...@linux.vnet.ibm.com
---
  Makefile.objs  |1 +
  block.c|2 +-
  block.h|1 +
  block/add-cow.c|  412 
  block_int.h|1 +
  docs/specs/add-cow.txt |   45 ++
  6 files changed, 461 insertions(+), 1 deletions(-)
  create mode 100644 block/add-cow.c
  create mode 100644 docs/specs/add-cow.txt

diff --git a/Makefile.objs b/Makefile.objs
index c849e51..624c04c 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -31,6 +31,7 @@ block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o

  block-nested-y += raw.o cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o 
vvfat.o
  block-nested-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o 
qcow2-cache.o
+block-nested-y += add-cow.o
  block-nested-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o
  block-nested-y += qed-check.o
  block-nested-y += parallels.o nbd.o blkdebug.o sheepdog.o blkverify.o
diff --git a/block.c b/block.c
index e865fab..c25241d 100644
--- a/block.c
+++ b/block.c
@@ -106,7 +106,7 @@ int is_windows_drive(const char *filename)
  #endif

  /* check if the path starts with protocol: */
-static int path_has_protocol(const char *path)
+int path_has_protocol(const char *path)
  {
  #ifdef _WIN32
  if (is_windows_drive(path) ||
diff --git a/block.h b/block.h
index 16bfa0a..8b09f12 100644
--- a/block.h
+++ b/block.h
@@ -256,6 +256,7 @@ char *bdrv_snapshot_dump(char *buf, int buf_size, 
QEMUSnapshotInfo *sn);

  char *get_human_readable_size(char *buf, int buf_size, int64_t size);
  int path_is_absolute(const char *path);
+int path_has_protocol(const char *path);
  void path_combine(char *dest, int dest_size,
const char *base_path,
const char *filename);
diff --git a/block/add-cow.c b/block/add-cow.c
new file mode 100644
index 000..d2538a2
--- /dev/null
+++ b/block/add-cow.c
@@ -0,0 +1,412 @@
+#include qemu-common.h
+#include block_int.h
+#include module.h
+
+#define ADD_COW_MAGIC  (((uint64_t)'A'  56) | ((uint64_t)'D'  48) | \
+((uint64_t)'D'  40) | ((uint64_t)'_'  32) | \
+((uint64_t)'C'  24) | ((uint64_t)'O'  16) | \
+((uint64_t)'W'  8) | 0xFF)
+#define ADD_COW_VERSION 1
+
+typedef struct AddCowHeader {
+uint64_t magic;
+uint32_t version;
+char backing_file[1024];
+char image_file[1024];
+uint64_t size;
+} QEMU_PACKED AddCowHeader;
+
+typedef struct BDRVAddCowState {
+char image_file[1024];
+BlockDriverState *image_hd;
+uint8_t *bitmap;
+uint64_t bitmap_size;
+} BDRVAddCowState;
+
+static int add_cow_probe(const uint8_t *buf, int buf_size, const char 
*filename)
+{
+const AddCowHeader *header = (const void *)buf;
+
+if (be64_to_cpu(header-magic) == ADD_COW_MAGIC
+be32_to_cpu(header-version) == ADD_COW_VERSION) {
+return 100;
+} else {
+return 0;
+}
+}
+
+static int add_cow_open(BlockDriverState *bs, int flags)
+{
+AddCowHeader header;
+int64_t size;
+char image_filename[1024];
+int image_flags;
+BlockDriver *image_drv = NULL;
+int ret;
+BDRVAddCowState *state = (BDRVAddCowState *)(bs-opaque);
+
+ret = bdrv_pread(bs-file, 0,header, sizeof(header));
+if (ret != sizeof(header)) {
+goto fail;
+}
+
+if (be64_to_cpu(header.magic) != ADD_COW_MAGIC ||
+be32_to_cpu(header.version) != ADD_COW_VERSION) {
+ret = -1;
+goto fail;
+}
+
+size = be64_to_cpu(header.size);
+bs-total_sectors = size / BDRV_SECTOR_SIZE;
+
+QEMU_BUILD_BUG_ON(sizeof(state-image_file) != sizeof(header.image_file));
+pstrcpy(bs-backing_file, sizeof(bs-backing_file),
+header.backing_file);
+pstrcpy(state-image_file, sizeof(state-image_file),
+header.image_file);
+
+state-bitmap_size = ((bs-total_sectors + 7)  3);
+state-bitmap = g_malloc0(state-bitmap_size);
+
+ret = bdrv_pread(bs-file, sizeof(header), state-bitmap,
+state-bitmap_size);
+if (ret != state-bitmap_size) {
+goto fail;
+}
+   /* If there is a image_file, must be together with backing_file */
+if (state-image_file[0] != '\0') {
+state-image_hd = bdrv_new();
+/* Relative to image or working dir, need discussion */
+if (path_has_protocol(state-image_file)) {
+pstrcpy(image_filename, sizeof(image_filename),
+state-image_file);
+} else {
+path_combine(image_filename, sizeof(image_filename),
+ bs-filename, state-image_file);
+}
+
+image_drv = bdrv_find_format(raw);
+image_flags =
+ (flags  (~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING))) | BDRV_O_RDWR;
+state-image_hd-keep_read_only = 0;
+
+   

Re: [Qemu-devel] [PATCH] ps2: migrate ledstate

2011-10-13 Thread Gerd Hoffmann

  Hi,


One thing that could be improved after this patch is that the ledstate
is now present both in spice-input and hw/ps2.c, but I couldn't find
an easy way to get the ps2 ledstate from spice-input so I left things
this way for now.


Directly linking ps/2 and spice-input would be wrong anyway as there are 
other keyboards (usb) too ...


input.c could cache the ledstate and offer a kbd_get_ledstate function, 
so anyone interested in the state doesn't need to keep it itself.  That 
is a pretty minor thing though IMHO.


cheers,
  Gerd




Re: [Qemu-devel] 2 MiB alignment in qemu_vmalloc()

2011-10-13 Thread Gerd Hoffmann

  Hi,


I can try to make QEMU more useable with Valgrind by changing
the QEMU code (which was Valgrind compatible up to Avi's change).


Is there some way for apps to figure they are running in valgrind?
Then we could choose a different alignment automagically.

Who aborts btw?  Is this valgrind itself?  Or qemu due to memalign 
failing?  In case of the latter we could simply catch it and try again 
with another alignment ...


cheers,
  Gerd




Re: [Qemu-devel] [PATCH] apic: test tsc deadline timer

2011-10-13 Thread Liu, Jinsong
Avi Kivity wrote:
 On 10/09/2011 05:32 PM, Liu, Jinsong wrote:
 Updated test case for kvm tsc deadline timer
 https://github.com/avikivity/kvm-unit-tests, as attached. 
 
 
 Applied, thanks.

Which tree? I didn't find it at git://github.com/avikivity/kvm-unit-tests.git

Thanks,
Jinsong


Re: [Qemu-devel] [PATCH 0/6] trace: Add support for trace events grouping

2011-10-13 Thread Mark Wu

On 10/13/2011 01:14 AM, Mark Wu wrote:

This series add support for trace events grouping. The state of a given group
of trace events can be queried or changed in bulk by the following monitor
commands:

* info trace-groups
   View available trace event groups and their state.  State 1 means enabled,
   state 0 means disabled.

* trace-group NAME on|off
   Enable/disable a given trace event group.

A group of trace events can also be enabled in early running stage through
adding its group name prefixed with group: to trace events list file
which is passed to -trace events.

Mark Wu (6):
   trace: Make tracetool generate a group list
   trace: Add HMP monitor commands for trace events group
   trace: Add trace events group implementation in the backend simple
   trace: Add trace events group implementation in the backend stderr
   trace: Enable -trace events argument to control initial state of
 groups
   trace: Update doc for trace events group

  docs/tracing.txt  |   29 ++--
  hmp-commands.hx   |   14 
  monitor.c |   22 
  scripts/tracetool |   94 +++-
  trace-events  |   88 +
  trace/control.c   |   17 +
  trace/control.h   |9 +
  trace/default.c   |   15 
  trace/simple.c|   30 +
  trace/simple.h|7 
  trace/stderr.c|   32 ++
  trace/stderr.h|7 
  12 files changed, 359 insertions(+), 5 deletions(-)

Sorry, there're some coding style problems in the patches. I have fixed 
them and will send out later in order to see if there's any other 
problem coming up. :)




[Qemu-devel] [PATCH 2/4] ppc: First cut implementation of -cpu host

2011-10-13 Thread David Gibson
For convenience with kvm, x86 allows the user to specify -cpu host on the
qemu command line, which means make the guest cpu the same as the host
cpu.  This patch implements the same option for ppc targets.

For now, this just read the host PVR (Processor Version Register) and
selects one of our existing CPU specs based on it.  This means that the
option will not work if the host cpu is not supported by TCG, even if that
wouldn't matter for use under kvm.

In future, we can extend this in future to override parts of the cpu spec
based on information obtained from the host (via /proc/cpuinfo, the host
device tree, or explicit KVM calls).  That will let us handle cases where
the real kvm-virtualized CPU doesn't behave exactly like the TCG-emulated
CPU.  With appropriate annotation of the CPU specs we'll also then be able
to use host cpus under kvm even when there isn't a matching full TCG model.

Signed-off-by: David Gibson da...@gibson.dropbear.id.au
---
 target-ppc/cpu.h|1 +
 target-ppc/kvm.c|   19 +++
 target-ppc/kvm_ppc.h|6 ++
 target-ppc/translate_init.c |8 +++-
 4 files changed, 33 insertions(+), 1 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 3f77e30..8e5c85c 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1107,6 +1107,7 @@ void ppc_store_msr (CPUPPCState *env, target_ulong value);
 
 void ppc_cpu_list (FILE *f, fprintf_function cpu_fprintf);
 
+const ppc_def_t *ppc_find_by_pvr(uint32_t pvr);
 const ppc_def_t *cpu_ppc_find_by_name (const char *name);
 int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def);
 
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 6a48eb4..430558b 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -878,6 +878,25 @@ int kvmppc_remove_spapr_tce(void *table, int fd, uint32_t 
window_size)
 return 0;
 }
 
+static inline uint32_t mfpvr(void)
+{
+uint32_t pvr;
+
+asm (mfpvr %0
+ : =r(pvr));
+return pvr;
+}
+
+const ppc_def_t *kvmppc_host_cpu_def(void)
+{
+uint32_t host_pvr = mfpvr();
+const ppc_def_t *base_spec;
+
+base_spec = ppc_find_by_pvr(host_pvr);
+
+return base_spec;
+}
+
 bool kvm_arch_stop_on_emulation_error(CPUState *env)
 {
 return true;
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index fa131bf..0062906 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -24,6 +24,7 @@ int kvmppc_smt_threads(void);
 off_t kvmppc_alloc_rma(const char *name);
 void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd);
 int kvmppc_remove_spapr_tce(void *table, int pfd, uint32_t window_size);
+const ppc_def_t *kvmppc_host_cpu_def(void);
 
 #else
 
@@ -83,6 +84,11 @@ static inline int kvmppc_remove_spapr_tce(void *table, int 
pfd,
 return -1;
 }
 
+static inline const ppc_def_t *kvmppc_host_cpu_def(void)
+{
+return NULL;
+}
+
 #endif
 
 #ifndef CONFIG_KVM
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 73b49cf..62f0a6b 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -24,6 +24,8 @@
 
 #include dis-asm.h
 #include gdbstub.h
+#include kvm.h
+#include kvm_ppc.h
 
 //#define PPC_DUMP_CPU
 //#define PPC_DEBUG_SPR
@@ -10041,7 +10043,7 @@ int cpu_ppc_register_internal (CPUPPCState *env, const 
ppc_def_t *def)
 return 0;
 }
 
-static const ppc_def_t *ppc_find_by_pvr (uint32_t pvr)
+const ppc_def_t *ppc_find_by_pvr(uint32_t pvr)
 {
 int i;
 
@@ -10063,6 +10065,10 @@ const ppc_def_t *cpu_ppc_find_by_name (const char 
*name)
 const char *p;
 int i, max, len;
 
+if (kvm_enabled()  (strcasecmp(name, host) == 0)) {
+return kvmppc_host_cpu_def();
+}
+
 /* Check if the given name is a PVR */
 len = strlen(name);
 if (len == 10  name[0] == '0'  name[1] == 'x') {
-- 
1.7.6.3




[Qemu-devel] [0/4] ppc: Implement -host CPU

2011-10-13 Thread David Gibson
This series of patches implements a -cpu host option for ppc,
analagous to the version that already exists for x86.  For now, only
the basic framework is implement.  In later patches, we will need to
improve the code to override those parts of the cpu spec that can be
queried from the host, and use this mechanism to subsume, for example,
the current advertisement by the pseries machine of KVM CPU
capabilities to the guest.




[Qemu-devel] [PATCH 3/4] ppc: Add cpu defs for POWER7 revisions 2.1 and 2.3

2011-10-13 Thread David Gibson
This patch adds cpu specs to the table for POWER7 revisions 2.1 and 2.3.
This allows -cpu host to be used on these host cpus.

Signed-off-by: David Gibson da...@gibson.dropbear.id.au
---
 target-ppc/translate_init.c |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 62f0a6b..7de097d 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -7333,6 +7333,8 @@ enum {
 CPU_POWERPC_POWER6A= 0x0F02,
 #define CPU_POWERPC_POWER7   CPU_POWERPC_POWER7_v20
 CPU_POWERPC_POWER7_v20 = 0x003F0200,
+CPU_POWERPC_POWER7_v21 = 0x003F0201,
+CPU_POWERPC_POWER7_v23 = 0x003F0203,
 CPU_POWERPC_970= 0x00390202,
 #define CPU_POWERPC_970FXCPU_POWERPC_970FX_v31
 CPU_POWERPC_970FX_v10  = 0x00391100,
@@ -9139,6 +9141,8 @@ static const ppc_def_t ppc_defs[] = {
 /* POWER7*/
 POWERPC_DEF(POWER7,CPU_POWERPC_POWER7, POWER7),
 POWERPC_DEF(POWER7_v2.0,   CPU_POWERPC_POWER7_v20, POWER7),
+POWERPC_DEF(POWER7_v2.1,   CPU_POWERPC_POWER7_v21, POWER7),
+POWERPC_DEF(POWER7_v2.3,   CPU_POWERPC_POWER7_v23, POWER7),
 /* PowerPC 970   */
 POWERPC_DEF(970,   CPU_POWERPC_970,970),
 /* PowerPC 970FX (G5)*/
-- 
1.7.6.3




[Qemu-devel] [PATCH 4/4] pseries: Under kvm use guest cpu = host cpu by default

2011-10-13 Thread David Gibson
Now that we've implemented -cpu host for ppc, this patch updates the
pseries machine to use the host cpu as the guest cpu by default when
running under KVM.  This is important because under KVM Book3S-HV the guest
cpu _cannot_ be of a different type to the host cpu (at the moment
KVM Book3S-HV will silently virtualize the host cpu instead of whatever was
requested, but in future it is likely to simply refuse to run the VM if
a cpu model other than the host's is requested).

Signed-off-by: David Gibson da...@gibson.dropbear.id.au
---
 hw/spapr.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/spapr.c b/hw/spapr.c
index 00b9c67..fecfa4a 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -403,7 +403,7 @@ static void ppc_spapr_init(ram_addr_t ram_size,
 
 /* init CPUs */
 if (cpu_model == NULL) {
-cpu_model = POWER7;
+cpu_model = kvm_enabled() ? host : POWER7;
 }
 for (i = 0; i  smp_cpus; i++) {
 env = cpu_init(cpu_model);
-- 
1.7.6.3




[Qemu-devel] [PATCH 1/4] ppc: Remove broken partial PVR matching

2011-10-13 Thread David Gibson
The ppc target contains a ppc_find_by_pvr() function, which looks up a
CPU spec based on a PVR (that is, based on the value in the target cpu's
Processor Version Register).  PVR values contain information on both the
cpu model (upper 16 bits, usually) and on the precise revision (low 16
bits, usually).

ppc_find_by_pvr, as well as making exact PVR matches, attempts to find
close PVR matches, when we don't have a CPU spec for the exact revision
specified.  This sounds like a good idea, execpt that the current logic
is completely nonsensical.

It seems to assume CPU families are subdivided bit by bit in the PVR in a
way they just aren't.  Specifically, it requires a match on all bits of the
specified pvr up to the last non-zero bit.  This has the bizarre effect
that when the low bits are simply a sequential revision number (a common
though not universal pattern), then odd specified revisions must be matched
exactly, whereas even specified revisions will also match the next odd
revision, likewise for powers of 4, 8 and so forth.

To correctly do inexact matching we'd need to re-organize the table of CPU
specs to include a mask showing what PVR range the spec is compatible with
(similar to the cputable code in the Linux kernel).

For now, just remove the bogosity by only permitting exact PVR matches.
That at least makes the matching simple and consistent.  If we need inexact
matching we can add the necessary per-subfamily masks later.

Signed-off-by: David Gibson da...@gibson.dropbear.id.au
---
 target-ppc/translate_init.c |   38 +++---
 1 files changed, 7 insertions(+), 31 deletions(-)

diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index ca0d852..73b49cf 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -10043,40 +10043,16 @@ int cpu_ppc_register_internal (CPUPPCState *env, 
const ppc_def_t *def)
 
 static const ppc_def_t *ppc_find_by_pvr (uint32_t pvr)
 {
-const ppc_def_t *ret;
-uint32_t pvr_rev;
-int i, best, match, best_match, max;
+int i;
 
-ret = NULL;
-max = ARRAY_SIZE(ppc_defs);
-best = -1;
-pvr_rev = pvr  0x;
-/* We want all specified bits to match */
-best_match = 32 - ctz32(pvr_rev);
-for (i = 0; i  max; i++) {
-/* We check that the 16 higher bits are the same to ensure the CPU
- * model will be the choosen one.
- */
-if (((pvr ^ ppc_defs[i].pvr)  16) == 0) {
-/* We want as much as possible of the low-level 16 bits
- * to be the same but we allow inexact matches.
- */
-match = clz32(pvr_rev ^ (ppc_defs[i].pvr  0x));
-/* We check '=' instead of '' because the PPC_defs table
- * is ordered by increasing revision.
- * Then, we will match the higher revision compatible
- * with the requested PVR
- */
-if (match = best_match) {
-best = i;
-best_match = match;
-}
+for (i = 0; i  ARRAY_SIZE(ppc_defs); i++) {
+/* If we have an exact match, we're done */
+if (pvr == ppc_defs[i].pvr) {
+return ppc_defs[i];
 }
 }
-if (best != -1)
-ret = ppc_defs[best];
 
-return ret;
+return NULL;
 }
 
 #include ctype.h
-- 
1.7.6.3




Re: [Qemu-devel] [PATCH] This patch adds a new block driver : iSCSI

2011-10-13 Thread ronnie sahlberg
Previous version of the patch received very positive feedback and
several expressed seeing positive value of a built-in initiator.
I updated patch from feedback 3 weeks ago and Stefan kindly reviewed it.


Is there some other problem with the patch I am not aware of that I
should address?

I have been trying to push this patch in different versions since
December last year.
There is obviously a problem here I am not aware of.
Please advice what the problem is and I will try to rectify it.


Please advice on how I can move forward. I feel a bit at roads end
here. Please help.


regards
ronnie sahlberg



On Mon, Oct 10, 2011 at 7:46 AM, ronnie sahlberg
ronniesahlb...@gmail.com wrote:
 ping?


 On Thu, Sep 29, 2011 at 4:54 PM, Stefan Hajnoczi
 stefa...@linux.vnet.ibm.com wrote:
 On Wed, Sep 21, 2011 at 07:37:55PM +1000, Ronnie Sahlberg wrote:
 This provides built-in support for iSCSI to QEMU.
 This has the advantage that the iSCSI devices need not be made visible to 
 the host, which is useful if you have very many virtual machines and very 
 many iscsi devices.
 It also has the benefit that non-root users of QEMU can access iSCSI 
 devices across the network without requiring root privilege on the host.

 This driver interfaces with the multiplatform posix library for iscsi 
 initiator/client access to iscsi devices hosted at
     git://github.com/sahlberg/libiscsi.git

 The patch adds the driver to interface with the iscsi library.
 It also updated the configure script to
 * by default, probe is libiscsi is available and if so, build
   qemu against libiscsi.
 * --enable-libiscsi
   Force a build against libiscsi. If libiscsi is not available
   the build will fail.
 * --disable-libiscsi
   Do not link against libiscsi, even if it is available.

 When linked with libiscsi, qemu gains support to access iscsi resources 
 such as disks and cdrom directly, without having to make the devices 
 visible to the host.

 You can specify devices using a iscsi url of the form :
 iscsi://[username[:password@]]host[:port]/target-iqn-name/lun
 When using authentication, the password can optionally be set with
 LIBISCSI_CHAP_PASSWORD=password to avoid it showing up in the process list

 Signed-off-by: Ronnie Sahlberg ronniesahlb...@gmail.com
 ---
  Makefile.objs |    1 +
  block/iscsi.c |  596 
 +
  configure     |   31 +++
  trace-events  |    7 +
  4 files changed, 635 insertions(+), 0 deletions(-)
  create mode 100644 block/iscsi.c

 Reviewed-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com





Re: [Qemu-devel] [PATCH] This patch adds a new block driver : iSCSI

2011-10-13 Thread Paolo Bonzini

On 10/13/2011 11:46 AM, ronnie sahlberg wrote:

Previous version of the patch received very positive feedback and
several expressed seeing positive value of a built-in initiator.
I updated patch from feedback 3 weeks ago and Stefan kindly reviewed it.


Is there some other problem with the patch I am not aware of that I
should address?

I have been trying to push this patch in different versions since
December last year.
There is obviously a problem here I am not aware of.
Please advice what the problem is and I will try to rectify it.


The problem is just that everyone is busy. :)  The patch looks good to 
me too.


Paolo



Re: [Qemu-devel] [PATCH] This patch adds a new block driver : iSCSI

2011-10-13 Thread Stefan Hajnoczi
On Thu, Oct 13, 2011 at 10:46 AM, ronnie sahlberg
ronniesahlb...@gmail.com wrote:
 Previous version of the patch received very positive feedback and
 several expressed seeing positive value of a built-in initiator.
 I updated patch from feedback 3 weeks ago and Stefan kindly reviewed it.

I'm happy.

Stefan



Re: [Qemu-devel] [PATCH] This patch adds a new block driver : iSCSI

2011-10-13 Thread Daniel P. Berrange
On Thu, Oct 13, 2011 at 08:46:54PM +1100, ronnie sahlberg wrote:
 Previous version of the patch received very positive feedback and
 several expressed seeing positive value of a built-in initiator.
 I updated patch from feedback 3 weeks ago and Stefan kindly reviewed it.
 
 
 Is there some other problem with the patch I am not aware of that I
 should address?
 
 I have been trying to push this patch in different versions since
 December last year.
 There is obviously a problem here I am not aware of.
 Please advice what the problem is and I will try to rectify it.
 
 
 Please advice on how I can move forward. I feel a bit at roads end
 here. Please help.

I can't comment much on the code, but I'm supportive of QEMU gaining
this feature, because it addresses a number of use cases not satisfied
by using iSCSI via the host OS's block layer.


  You can specify devices using a iscsi url of the form :
  iscsi://[username[:password@]]host[:port]/target-iqn-name/lun
  When using authentication, the password can optionally be set with
  LIBISCSI_CHAP_PASSWORD=password to avoid it showing up in the process 
  list

I'm not a fan of sending passwords via command line args, or
environment variables.  Env variables *can* be exposed via
the process list, albeit not to unprivileged users. More
critically, env variables will end up in logfiles like
/var/log/libvirt/qemu/$GUESTNAME.log, and in data reported
to distro bug trackers, via tools like sosreport which
capture /proc/$PID/environ and aforementioned logfiles.

We have a similar requirement for specifying passwords with
the Ceph/RBD driver, and also for the curl/HTTP block drivers.
We have a monitor command for providing decryption passwords for
QCow2 disks. We could either reuse that for connection passwords,
or perhaps slightly better would be to have a separate command
for connection passwords.


Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org   -o-   http://live.gnome.org/gtk-vnc :|



Re: [Qemu-devel] [PATCH] usb-hid: activate usb tablet / mouse after migration.

2011-10-13 Thread Gerd Hoffmann

On 10/13/11 04:09, TeLeMan wrote:

On Wed, Oct 12, 2011 at 19:30, Gerd Hoffmannkra...@redhat.com  wrote:

qemu uses the ps/2 mouse by default.  The usb tablet (or mouse) is
activated as soon as qemu sees some guest activity on the device,
i.e. polling for HID events.  That used to work fine for both fresh
boot and migration.

It does not fix usb tablet/mouse when starting vm directly from snapshot.


What does info mice print before/after snapshotting?
Which guest?  WinXP IIRC?

cheers,
  Gerd




Re: [Qemu-devel] [PATCH] This patch adds a new block driver : iSCSI

2011-10-13 Thread Kevin Wolf
Am 13.10.2011 11:46, schrieb ronnie sahlberg:
 Previous version of the patch received very positive feedback and
 several expressed seeing positive value of a built-in initiator.
 I updated patch from feedback 3 weeks ago and Stefan kindly reviewed it.
 
 
 Is there some other problem with the patch I am not aware of that I
 should address?

No problems that I know of, other than me being on vacation in the last
two weeks. I'm planning to have another quick look before I merge it,
but Stefan's ack suggests that it's ready to be merged and your part is
done.

Kevin



Re: [Qemu-devel] [BUG] USB assertion triggers in usb_packet_complete()

2011-10-13 Thread Gerd Hoffmann

  Hi,


Hi Thomas,
I hit the same bug recently and Gerd has posted a patch which you can test:
http://patchwork.ozlabs.org/patch/118726/


Thanks for the hint, Stefan, you're right, that seems to be the same
bug. Your patch is working fine in my scenario, too.

However, Gerd's patch is not working for me, the assertion still
triggers. It seems like usb_packet_complete() is called for the leaf
node before it is called for the hub node, so the leaf node already set
p-owner = NULL.


Ah, right, on completion the call chain goes the other way around, so 
the usb_handle_packet() style approach doesn't fly.


I think going with Stefans approach + a big fat comment is the best 
solution then.  I'll go queue up a patch.


cheers,
  Gerd



Re: [Qemu-devel] [PATCH] This patch adds a new block driver : iSCSI

2011-10-13 Thread Daniel P. Berrange
On Thu, Oct 13, 2011 at 11:01:49AM +0100, Daniel P. Berrange wrote:
 On Thu, Oct 13, 2011 at 08:46:54PM +1100, ronnie sahlberg wrote:
  Previous version of the patch received very positive feedback and
  several expressed seeing positive value of a built-in initiator.
  I updated patch from feedback 3 weeks ago and Stefan kindly reviewed it.
  
  
  Is there some other problem with the patch I am not aware of that I
  should address?
  
  I have been trying to push this patch in different versions since
  December last year.
  There is obviously a problem here I am not aware of.
  Please advice what the problem is and I will try to rectify it.
  
  
  Please advice on how I can move forward. I feel a bit at roads end
  here. Please help.
 
 I can't comment much on the code, but I'm supportive of QEMU gaining
 this feature, because it addresses a number of use cases not satisfied
 by using iSCSI via the host OS's block layer.
 
 
   You can specify devices using a iscsi url of the form :
   iscsi://[username[:password@]]host[:port]/target-iqn-name/lun
   When using authentication, the password can optionally be set with
   LIBISCSI_CHAP_PASSWORD=password to avoid it showing up in the process 
   list
 
 I'm not a fan of sending passwords via command line args, or
 environment variables.  Env variables *can* be exposed via
 the process list, albeit not to unprivileged users. More
 critically, env variables will end up in logfiles like
 /var/log/libvirt/qemu/$GUESTNAME.log, and in data reported
 to distro bug trackers, via tools like sosreport which
 capture /proc/$PID/environ and aforementioned logfiles.
 
 We have a similar requirement for specifying passwords with
 the Ceph/RBD driver, and also for the curl/HTTP block drivers.
 We have a monitor command for providing decryption passwords for
 QCow2 disks. We could either reuse that for connection passwords,
 or perhaps slightly better would be to have a separate command
 for connection passwords.

NB, I didn't mean to suggest that this issue should block merging
of this iSCSI driver. The problem with passwords already exists for
Ceph  Curl drivers, and I believe the Ceph developers are already
working on a patch for QEMU which should be able to apply to all
these network block devs

Regards,
Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org   -o-   http://live.gnome.org/gtk-vnc :|



Re: [Qemu-devel] [PATCH] linux-user: Fix broken -version option

2011-10-13 Thread Peter Maydell
Ping?

-- PMM

On 29 September 2011 15:48, Peter Maydell peter.mayd...@linaro.org wrote:
 Fix the -version option, which was accidentally broken in commit
 fc9c541:
  * exit after printing version information rather than proceeding
   blithely onward (and likely printing the full usage message)
  * correct the cut-n-paste error in the usage message for it
  * don't insist on the presence of a following argument for
   options which don't take an argument (this was preventing
   'qemu-arm -version' from working)
  * remove a spurious argc check from the beginning of main() which
   meant 'QEMU_VERSION=1 qemu-arm' didn't work.

 Signed-off-by: Peter Maydell peter.mayd...@linaro.org
 ---
  linux-user/main.c |   19 ---
  1 files changed, 8 insertions(+), 11 deletions(-)

 diff --git a/linux-user/main.c b/linux-user/main.c
 index 186358b..e7dad54 100644
 --- a/linux-user/main.c
 +++ b/linux-user/main.c
 @@ -3084,6 +3084,7 @@ static void handle_arg_version(const char *arg)
  {
     printf(qemu- TARGET_ARCH  version  QEMU_VERSION QEMU_PKGVERSION
            , Copyright (c) 2003-2008 Fabrice Bellard\n);
 +    exit(0);
  }

  struct qemu_argument {
 @@ -3129,7 +3130,7 @@ struct qemu_argument arg_table[] = {
     {strace,     QEMU_STRACE,      false, handle_arg_strace,
      ,           log system calls},
     {version,    QEMU_VERSION,     false, handle_arg_version,
 -     ,           log system calls},
 +     ,           display version information and exit},
     {NULL, NULL, false, NULL, NULL, NULL}
  };

 @@ -3231,16 +3232,15 @@ static int parse_args(int argc, char **argv)

         for (arginfo = arg_table; arginfo-handle_opt != NULL; arginfo++) {
             if (!strcmp(r, arginfo-argv)) {
 -                if (optind = argc) {
 -                    usage();
 -                }
 -
 -                arginfo-handle_opt(argv[optind]);
 -
                 if (arginfo-has_arg) {
 +                    if (optind = argc) {
 +                        usage();
 +                    }
 +                    arginfo-handle_opt(argv[optind]);
                     optind++;
 +                } else {
 +                    arginfo-handle_opt(NULL);
                 }
 -
                 break;
             }
         }
 @@ -3276,9 +3276,6 @@ int main(int argc, char **argv, char **envp)
     int i;
     int ret;

 -    if (argc = 1)
 -        usage();
 -
     qemu_cache_utils_init(envp);

     if ((envlist = envlist_create()) == NULL) {
 --
 1.7.4.1



[Qemu-devel] [PATCH 22/35] scsi-disk: fix retrying a flush

2011-10-13 Thread Paolo Bonzini
Flush does not go anymore through scsi_disk_emulate_command.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-disk.c |9 +++--
 1 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 3f54891..860a3bf 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -81,7 +81,7 @@ struct SCSIDiskState
 };
 
 static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type);
-static int scsi_disk_emulate_command(SCSIDiskReq *r);
+static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf);
 
 static void scsi_free_request(SCSIRequest *req)
 {
@@ -336,7 +336,6 @@ static void scsi_dma_restart_bh(void *opaque)
 r = DO_UPCAST(SCSIDiskReq, req, req);
 if (r-status  SCSI_REQ_STATUS_RETRY) {
 int status = r-status;
-int ret;
 
 r-status =
 ~(SCSI_REQ_STATUS_RETRY | SCSI_REQ_STATUS_RETRY_TYPE_MASK);
@@ -349,10 +348,8 @@ static void scsi_dma_restart_bh(void *opaque)
 scsi_write_data(r-req);
 break;
 case SCSI_REQ_STATUS_RETRY_FLUSH:
-ret = scsi_disk_emulate_command(r);
-if (ret == 0) {
-scsi_req_complete(r-req, GOOD);
-}
+scsi_send_command(r-req, r-req.cmd.buf);
+break;
 }
 /* This reference was left in by scsi_handle_rw_error.  */
 scsi_req_unref(r-req);
-- 
1.7.6





[Qemu-devel] [PATCH 25/35] scsi-generic: check ioctl statuses when SG_IO succeeds

2011-10-13 Thread Paolo Bonzini
A succeeding ioctl does not imply that the SCSI command succeeded.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-generic.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index da104a6..9043eea 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -311,7 +311,7 @@ static int get_blocksize(BlockDriverState *bdrv)
 io_header.timeout = 6000; /* XXX */
 
 ret = bdrv_ioctl(bdrv, SG_IO, io_header);
-if (ret  0)
+if (ret  0 || io_header.driver_status || io_header.host_status)
 return -1;
 
 return (buf[4]  24) | (buf[5]  16) | (buf[6]  8) | buf[7];
@@ -342,7 +342,7 @@ static int get_stream_blocksize(BlockDriverState *bdrv)
 io_header.timeout = 6000; /* XXX */
 
 ret = bdrv_ioctl(bdrv, SG_IO, io_header);
-if (ret  0)
+if (ret  0 || io_header.driver_status || io_header.host_status)
 return -1;
 
 return (buf[9]  16) | (buf[10]  8) | buf[11];
-- 
1.7.6





[Qemu-devel] [PATCH 24/35] scsi-generic: remove scsi_req_fixup

2011-10-13 Thread Paolo Bonzini
This is not needed anymore, since asynchronous ioctls were introduced
by commit 221f715 (new scsi-generic abstraction, use SG_IO, 2009-03-28).

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-generic.c |   15 ---
 1 files changed, 0 insertions(+), 15 deletions(-)

diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index cea4fca..da104a6 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -233,19 +233,6 @@ static uint8_t *scsi_get_buf(SCSIRequest *req)
 return r-buf;
 }
 
-static void scsi_req_fixup(SCSIRequest *req)
-{
-switch(req-cmd.buf[0]) {
-case REWIND:
-case START_STOP:
-if (req-dev-type == TYPE_TAPE) {
-/* force IMMED, otherwise qemu waits end of command */
-req-cmd.buf[1] = 0x01;
-}
-break;
-}
-}
-
 /* Execute a scsi command.  Returns the length of the data expected by the
command.  This will be Positive for data transfers from the device
(eg. disk reads), negative for transfers to the device (eg. disk writes),
@@ -257,8 +244,6 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t 
*cmd)
 SCSIDevice *s = r-req.dev;
 int ret;
 
-scsi_req_fixup(r-req);
-
 DPRINTF(Command: lun=%d tag=0x%x len %zd data=0x%02x, lun, tag,
 r-req.cmd.xfer, cmd[0]);
 
-- 
1.7.6





[Qemu-devel] [PATCH 33/35] scsi: export scsi_generic_reqops

2011-10-13 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-generic.c |2 +-
 hw/scsi.h |3 +++
 2 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index abe92fa..c4f928a 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -407,7 +407,7 @@ static int scsi_generic_initfn(SCSIDevice *s)
 return 0;
 }
 
-static const SCSIReqOps scsi_generic_req_ops = {
+const SCSIReqOps scsi_generic_req_ops = {
 .size = sizeof(SCSIGenericReq),
 .free_req = scsi_free_request,
 .send_command = scsi_send_command,
diff --git a/hw/scsi.h b/hw/scsi.h
index af558c3..01c6655 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -197,4 +197,7 @@ void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense 
sense);
 int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed);
 SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int target, int lun);
 
+/* scsi-generic.c. */
+extern const SCSIReqOps scsi_generic_req_ops;
+
 #endif
-- 
1.7.6





[Qemu-devel] [PATCH 19/35] scsi-disk: fail READ CAPACITY if LBA != 0 but PMI == 0

2011-10-13 Thread Paolo Bonzini
Tested by the Windows Logo Kit SCSI Compliance test. From SBC-3, paragraph
5.25: The LOGICAL BLOCK ADDRESS field shall be set to zero if the PMI
bit is set to zero. If the PMI bit is set to zero and the LOGICAL BLOCK
ADDRESS field is not set to zero, then the device server shall terminate
the command with CHECK CONDITION status with the sense key set to ILLEGAL
REQUEST and the additional sense code set to INVALID FIELD IN CDB.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-disk.c |   12 ++--
 1 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 97a7335..b041fd5 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1161,8 +1161,12 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
 /* The normal LEN field for this command is zero.  */
 memset(outbuf, 0, 8);
 bdrv_get_geometry(s-bs, nb_sectors);
-if (!nb_sectors)
+if (!nb_sectors) {
 goto not_ready;
+}
+if ((req-cmd.buf[8]  1) == 0  req-cmd.lba) {
+goto illegal_request;
+}
 nb_sectors /= s-cluster_size;
 /* Returned value is the address of the last sector.  */
 nb_sectors--;
@@ -1207,8 +1211,12 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
 DPRINTF(SAI READ CAPACITY(16)\n);
 memset(outbuf, 0, req-cmd.xfer);
 bdrv_get_geometry(s-bs, nb_sectors);
-if (!nb_sectors)
+if (!nb_sectors) {
 goto not_ready;
+}
+if ((req-cmd.buf[14]  1) == 0  req-cmd.lba) {
+goto illegal_request;
+}
 nb_sectors /= s-cluster_size;
 /* Returned value is the address of the last sector.  */
 nb_sectors--;
-- 
1.7.6





[Qemu-devel] [PATCH 35/35] scsi-disk: add scsi-block for device passthrough

2011-10-13 Thread Paolo Bonzini
scsi-block is a new device that supports device passthrough of Linux
block devices (i.e. /dev/sda, not /dev/sg0).  It uses SG_IO for commands
other than I/O commands, and regular AIO read/writes for I/O commands.
Besides being simpler to configure (no mapping required to scsi-generic
device names), this removes the need for a large bounce buffer and,
in the future, will get scatter/gather support for free from scsi-disk.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-disk.c |  111 
 1 files changed, 111 insertions(+), 0 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 418b30d..b21fe1b 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -39,6 +39,10 @@ do { fprintf(stderr, scsi-disk:  fmt , ## __VA_ARGS__); } 
while (0)
 #include blockdev.h
 #include block_int.h
 
+#ifdef __linux
+#include scsi/sg.h
+#endif
+
 #define SCSI_DMA_BUF_SIZE131072
 #define SCSI_MAX_INQUIRY_LEN 256
 
@@ -1601,6 +1605,98 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, 
uint32_t tag, uint32_t lun,
 return req;
 }
 
+#ifdef __linux__
+static int get_device_type(SCSIDiskState *s)
+{
+BlockDriverState *bdrv = s-qdev.conf.bs;
+uint8_t cmd[16];
+uint8_t buf[36];
+uint8_t sensebuf[8];
+sg_io_hdr_t io_header;
+int ret;
+
+memset(cmd, 0, sizeof(cmd));
+memset(buf, 0, sizeof(buf));
+cmd[0] = INQUIRY;
+cmd[4] = sizeof(buf);
+
+memset(io_header, 0, sizeof(io_header));
+io_header.interface_id = 'S';
+io_header.dxfer_direction = SG_DXFER_FROM_DEV;
+io_header.dxfer_len = sizeof(buf);
+io_header.dxferp = buf;
+io_header.cmdp = cmd;
+io_header.cmd_len = sizeof(cmd);
+io_header.mx_sb_len = sizeof(sensebuf);
+io_header.sbp = sensebuf;
+io_header.timeout = 6000; /* XXX */
+
+ret = bdrv_ioctl(bdrv, SG_IO, io_header);
+if (ret  0 || io_header.driver_status || io_header.host_status) {
+return -1;
+}
+s-qdev.type = buf[0];
+s-removable = (buf[1]  0x80) != 0;
+s-qdev.blocksize = 0;
+s-qdev.max_lba = 0;
+return 0;
+}
+
+static int scsi_block_initfn(SCSIDevice *dev)
+{
+SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
+int sg_version;
+int rc;
+
+if (!s-qdev.conf.bs) {
+error_report(scsi-block: drive property not set);
+return -1;
+}
+
+/* check we are using a driver managing SG_IO (version 3 and after) */
+if (bdrv_ioctl(s-qdev.conf.bs, SG_GET_VERSION_NUM, sg_version)  0 ||
+sg_version  3) {
+error_report(scsi-block: scsi generic interface too old);
+return -1;
+}
+
+/* get device type from INQUIRY data */
+rc = get_device_type(s);
+if (rc  0) {
+error_report(scsi-block: INQUIRY failed);
+return -1;
+}
+
+return scsi_initfn(s-qdev);
+}
+
+static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag,
+   uint32_t lun, uint8_t *buf,
+   void *hba_private)
+{
+SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
+
+switch (buf[0]) {
+case READ_6:
+case READ_10:
+case READ_12:
+case READ_16:
+case WRITE_6:
+case WRITE_10:
+case WRITE_12:
+case WRITE_16:
+case WRITE_VERIFY_10:
+case WRITE_VERIFY_12:
+case WRITE_VERIFY_16:
+return scsi_req_alloc(scsi_disk_reqops, s-qdev, tag, lun,
+  hba_private);
+}
+
+return scsi_req_alloc(scsi_generic_req_ops, s-qdev, tag, lun,
+  hba_private);
+}
+#endif
+
 #define DEFINE_SCSI_DISK_PROPERTIES()   \
 DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf),  \
 DEFINE_PROP_STRING(ver,  SCSIDiskState, version), \
@@ -1636,6 +1732,21 @@ static SCSIDeviceInfo scsi_disk_info[] = {
 DEFINE_SCSI_DISK_PROPERTIES(),
 DEFINE_PROP_END_OF_LIST(),
 },
+#ifdef __linux__
+},{
+.qdev.name= scsi-block,
+.qdev.fw_name = disk,
+.qdev.desc= SCSI block device passthrough,
+.qdev.size= sizeof(SCSIDiskState),
+.qdev.reset   = scsi_disk_reset,
+.init = scsi_block_initfn,
+.destroy  = scsi_destroy,
+.alloc_req= scsi_block_new_request,
+.qdev.props   = (Property[]) {
+DEFINE_SCSI_DISK_PROPERTIES(),
+DEFINE_PROP_END_OF_LIST(),
+},
+#endif
 },{
 .qdev.name= scsi-disk, /* legacy -device scsi-disk */
 .qdev.fw_name = disk,
-- 
1.7.6




[Qemu-devel] [PATCH 12/35] scsi-disk: report media changed via GET EVENT STATUS NOTIFICATION

2011-10-13 Thread Paolo Bonzini
This adds support for media change notification via the GET EVENT STATUS
NOTIFICATION command, used by Linux versions 2.6.38 and newer.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-disk.c |   57 ---
 1 files changed, 53 insertions(+), 4 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 14db6a0..ce71df4 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -72,6 +72,7 @@ struct SCSIDiskState
 uint32_t removable;
 uint64_t max_lba;
 bool media_changed;
+bool media_event;
 QEMUBH *bh;
 char *version;
 char *serial;
@@ -682,11 +683,58 @@ fail:
 return -1;
 }
 
-static int scsi_get_event_status_notification(SCSIDiskState *s,
-  SCSIDiskReq *r, uint8_t *outbuf)
+static int scsi_event_status_media(SCSIDiskState *s, uint8_t *outbuf)
 {
-scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
-return -1;
+uint8_t event_code, media_status;
+
+media_status = 0;
+if (s-tray_open) {
+media_status = MS_TRAY_OPEN;
+} else if (bdrv_is_inserted(s-bs)) {
+media_status = MS_MEDIA_PRESENT;
+}
+
+/* Event notification descriptor */
+event_code = MEC_NO_CHANGE;
+if (media_status != MS_TRAY_OPEN  s-media_event) {
+event_code = MEC_NEW_MEDIA;
+s-media_event = false;
+}
+
+outbuf[0] = event_code;
+outbuf[1] = media_status;
+
+/* These fields are reserved, just clear them. */
+outbuf[2] = 0;
+outbuf[3] = 0;
+return 4;
+}
+
+static int scsi_get_event_status_notification(SCSIDiskState *s, SCSIDiskReq *r,
+  uint8_t *outbuf)
+{
+int size;
+uint8_t *buf = r-req.cmd.buf;
+uint8_t notification_class_request = buf[4];
+if (s-qdev.type != TYPE_ROM) {
+return -1;
+}
+if ((buf[1]  1) == 0) {
+/* asynchronous */
+return -1;
+}
+
+size = 4;
+outbuf[0] = outbuf[1] = 0;
+outbuf[3] = 1  GESN_MEDIA; /* supported events */
+if (notification_class_request  (1  GESN_MEDIA)) {
+outbuf[2] = GESN_MEDIA;
+size += scsi_event_status_media(s, outbuf[size]);
+} else {
+outbuf[2] = 0x80;
+}
+stw_be_p(outbuf, size - 4);
+return size;
 }
 
 static int scsi_get_configuration(SCSIDiskState *s, uint8_t *outbuf)
@@ -1416,6 +1464,7 @@ static void scsi_cd_change_media_cb(void *opaque, bool 
load)
 s-media_changed = load;
 s-tray_open = !load;
 s-qdev.unit_attention = SENSE_CODE(UNIT_ATTENTION_NO_MEDIUM);
+s-media_event = true;
 }
 
 static bool scsi_cd_is_tray_open(void *opaque)
-- 
1.7.6





[Qemu-devel] [PATCH 1/9] usb-storage: fix NULL pointer dereference.

2011-10-13 Thread Gerd Hoffmann
When a usb packet is canceled we need to check whenever we actually have
a scsi request in flight before we try to cancel it.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/usb-msd.c |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index e92434c..08d2d2a 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -325,7 +325,10 @@ static int usb_msd_handle_control(USBDevice *dev, 
USBPacket *p,
 static void usb_msd_cancel_io(USBDevice *dev, USBPacket *p)
 {
 MSDState *s = DO_UPCAST(MSDState, dev, dev);
-scsi_req_cancel(s-req);
+
+if (s-req) {
+scsi_req_cancel(s-req);
+}
 }
 
 static int usb_msd_handle_data(USBDevice *dev, USBPacket *p)
-- 
1.7.1




[Qemu-devel] [PATCH 8/9] usb-hid: activate usb tablet / mouse after migration.

2011-10-13 Thread Gerd Hoffmann
qemu uses the ps/2 mouse by default.  The usb tablet (or mouse) is
activated as soon as qemu sees some guest activity on the device,
i.e. polling for HID events.  That used to work fine for both fresh
boot and migration.

Remote wakeup support changed the picture though: There will be no
polling after migration in case the guest suspended the usb bus,
waiting for wakeup events.  Result is that the ps/2 mouse stays
active.

Fix this by activating the usb tablet / mouse in post_load() in case
the guest enabled remote wakeup.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/usb-hid.c |   11 +++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index ba79466..a110c74 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -527,10 +527,21 @@ static int usb_keyboard_initfn(USBDevice *dev)
 return usb_hid_initfn(dev, HID_KEYBOARD);
 }
 
+static int usb_ptr_post_load(void *opaque, int version_id)
+{
+USBHIDState *s = opaque;
+
+if (s-dev.remote_wakeup) {
+hid_pointer_activate(s-hid);
+}
+return 0;
+}
+
 static const VMStateDescription vmstate_usb_ptr = {
 .name = usb-ptr,
 .version_id = 1,
 .minimum_version_id = 1,
+.post_load = usb_ptr_post_load,
 .fields = (VMStateField []) {
 VMSTATE_USB_DEVICE(dev, USBHIDState),
 VMSTATE_HID_POINTER_DEVICE(hid, USBHIDState),
-- 
1.7.1




[Qemu-devel] [PATCH 9/9] usb-hub: don't trigger assert on packet completion.

2011-10-13 Thread Gerd Hoffmann
Calling usb_packet_complete() recursively when passing up the completion
event up the chain for devices connected via usb hub will trigger an
assert.  So don't do that, make the usb hub emulation call the upstream
completion callback directly instead.

Based on a patch from Stefan Hajnoczi stefa...@gmail.com

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/usb-hub.c |8 ++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/hw/usb-hub.c b/hw/usb-hub.c
index 39382c7..dab8f51 100644
--- a/hw/usb-hub.c
+++ b/hw/usb-hub.c
@@ -207,10 +207,14 @@ static void usb_hub_complete(USBPort *port, USBPacket 
*packet)
 /*
  * Just pass it along upstream for now.
  *
- * If we ever inplement usb 2.0 split transactions this will
+ * If we ever implement usb 2.0 split transactions this will
  * become a little more complicated ...
+ *
+ * Can't use usb_packet_complete() here because packet-owner is
+ * cleared already, go call the -complete() callback directly
+ * instead.
  */
-usb_packet_complete(s-dev, packet);
+s-dev.port-ops-complete(s-dev.port, packet);
 }
 
 static void usb_hub_handle_reset(USBDevice *dev)
-- 
1.7.1




[Qemu-devel] [PATCH 4/9] usb-host: factor out code

2011-10-13 Thread Gerd Hoffmann
Move code to claim usb ports and to disconnect usb interfaces into
usb_host_claim_port and usb_host_disconnect_ifaces functions.  No
functional change.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 usb-linux.c |  140 --
 1 files changed, 77 insertions(+), 63 deletions(-)

diff --git a/usb-linux.c b/usb-linux.c
index 2075c4c..ff1a29c 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -411,6 +411,80 @@ static void usb_host_async_cancel(USBDevice *dev, 
USBPacket *p)
 }
 }
 
+static int usb_host_claim_port(USBHostDevice *s)
+{
+#ifdef USBDEVFS_CLAIM_PORT
+char *h, hub_name[64], line[1024];
+int hub_addr, portnr, ret;
+
+snprintf(hub_name, sizeof(hub_name), %d-%s,
+ s-match.bus_num, s-match.port);
+
+/* try strip off last .$portnr to get hub */
+h = strrchr(hub_name, '.');
+if (h != NULL) {
+portnr = atoi(h+1);
+*h = '\0';
+} else {
+/* no dot in there - it is the root hub */
+snprintf(hub_name, sizeof(hub_name), usb%d,
+ s-match.bus_num);
+portnr = atoi(s-match.port);
+}
+
+if (!usb_host_read_file(line, sizeof(line), devnum,
+hub_name)) {
+return -1;
+}
+if (sscanf(line, %d, hub_addr) != 1) {
+return -1;
+}
+
+if (!usb_host_device_path) {
+return -1;
+}
+snprintf(line, sizeof(line), %s/%03d/%03d,
+ usb_host_device_path, s-match.bus_num, hub_addr);
+s-hub_fd = open(line, O_RDWR | O_NONBLOCK);
+if (s-hub_fd  0) {
+return -1;
+}
+
+ret = ioctl(s-hub_fd, USBDEVFS_CLAIM_PORT, portnr);
+if (ret  0) {
+close(s-hub_fd);
+s-hub_fd = -1;
+return -1;
+}
+
+trace_usb_host_claim_port(s-match.bus_num, hub_addr, portnr);
+return 0;
+#else
+return -1;
+#endif
+}
+
+static int usb_host_disconnect_ifaces(USBHostDevice *dev, int nb_interfaces)
+{
+/* earlier Linux 2.4 do not support that */
+#ifdef USBDEVFS_DISCONNECT
+struct usbdevfs_ioctl ctrl;
+int ret, interface;
+
+for (interface = 0; interface  nb_interfaces; interface++) {
+ctrl.ioctl_code = USBDEVFS_DISCONNECT;
+ctrl.ifno = interface;
+ctrl.data = 0;
+ret = ioctl(dev-fd, USBDEVFS_IOCTL, ctrl);
+if (ret  0  errno != ENODATA) {
+perror(USBDEVFS_DISCONNECT);
+return -1;
+}
+}
+#endif
+return 0;
+}
+
 static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration)
 {
 const char *op = NULL;
@@ -462,22 +536,9 @@ static int usb_host_claim_interfaces(USBHostDevice *dev, 
int configuration)
 }
 nb_interfaces = dev-descr[i + 4];
 
-#ifdef USBDEVFS_DISCONNECT
-/* earlier Linux 2.4 do not support that */
-{
-struct usbdevfs_ioctl ctrl;
-for (interface = 0; interface  nb_interfaces; interface++) {
-ctrl.ioctl_code = USBDEVFS_DISCONNECT;
-ctrl.ifno = interface;
-ctrl.data = 0;
-op = USBDEVFS_DISCONNECT;
-ret = ioctl(dev-fd, USBDEVFS_IOCTL, ctrl);
-if (ret  0  errno != ENODATA) {
-goto fail;
-}
-}
+if (usb_host_disconnect_ifaces(dev, nb_interfaces)  0) {
+goto fail;
 }
-#endif
 
 /* XXX: only grab if all interfaces are free */
 for (interface = 0; interface  nb_interfaces; interface++) {
@@ -1301,56 +1362,9 @@ static int usb_host_initfn(USBDevice *dev)
 qemu_add_exit_notifier(s-exit);
 usb_host_auto_check(NULL);
 
-#ifdef USBDEVFS_CLAIM_PORT
 if (s-match.bus_num != 0  s-match.port != NULL) {
-char *h, hub_name[64], line[1024];
-int hub_addr, portnr, ret;
-
-snprintf(hub_name, sizeof(hub_name), %d-%s,
- s-match.bus_num, s-match.port);
-
-/* try strip off last .$portnr to get hub */
-h = strrchr(hub_name, '.');
-if (h != NULL) {
-portnr = atoi(h+1);
-*h = '\0';
-} else {
-/* no dot in there - it is the root hub */
-snprintf(hub_name, sizeof(hub_name), usb%d,
- s-match.bus_num);
-portnr = atoi(s-match.port);
-}
-
-if (!usb_host_read_file(line, sizeof(line), devnum,
-hub_name)) {
-goto out;
-}
-if (sscanf(line, %d, hub_addr) != 1) {
-goto out;
-}
-
-if (!usb_host_device_path) {
-goto out;
-}
-snprintf(line, sizeof(line), %s/%03d/%03d,
- usb_host_device_path, s-match.bus_num, hub_addr);
-s-hub_fd = open(line, O_RDWR | O_NONBLOCK);
-if (s-hub_fd  0) {
-goto out;
-}
-
-ret = ioctl(s-hub_fd, USBDEVFS_CLAIM_PORT, portnr);
-if (ret  0) {
-close(s-hub_fd);
-s-hub_fd = -1;
-goto out;
-}
-
-

[Qemu-devel] [PATCH 09/35] atapi/scsi-disk: make mode page values coherent between the two

2011-10-13 Thread Paolo Bonzini
This patch adds to scsi-disk the missing mode page 0x01 for both disk
and CD-ROM drives, and mode page 0x0e for CD drives only.

A few offsets were wrong in atapi.c.  Also change the 2Ah mode page to
expose DVD media read capabilities in the IDE cdrom.  This lets you run
dvd+rw-mediainfo on the virtual DVD drives.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/ide/atapi.c |   12 ++--
 hw/scsi-disk.c |   33 -
 2 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index 10f161f..c6eb8f0 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -751,7 +751,7 @@ static void cmd_mode_sense(IDEState *s, uint8_t *buf)
 
 buf[8] = 0x2a;
 buf[9] = 0x12;
-buf[10] = 0x00;
+buf[10] = 0x3b; /* read CDR/CDRW/DVDROM/DVDR/DVDRAM */
 buf[11] = 0x00;
 
 /* Claim PLAY_AUDIO capability (0x01) since some Linux
@@ -760,14 +760,14 @@ static void cmd_mode_sense(IDEState *s, uint8_t *buf)
 buf[13] = 3  5;
 buf[14] = (1  0) | (1  3) | (1  5);
 if (s-tray_locked) {
-buf[6] |= 1  1;
+buf[14] |= 1  1;
 }
-buf[15] = 0x00;
-cpu_to_ube16(buf[16], 706);
+buf[15] = 0x00; /* No volume  mute control, no changer */
+cpu_to_ube16(buf[16], 704); /* 4x read speed */
 buf[18] = 0;
 buf[19] = 2;
-cpu_to_ube16(buf[20], 512);
-cpu_to_ube16(buf[22], 706);
+cpu_to_ube16(buf[20], 512); /* 512k buffer */
+cpu_to_ube16(buf[22], 704); /* 4x read speed current */
 buf[24] = 0;
 buf[25] = 0;
 buf[26] = 0;
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index a4aadf2..837747f 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -607,6 +607,8 @@ static int mode_sense_page(SCSIDiskState *s, int page, 
uint8_t **p_outbuf,
 [MODE_PAGE_HD_GEOMETRY]= (1  TYPE_DISK),
 [MODE_PAGE_FLEXIBLE_DISK_GEOMETRY] = (1  TYPE_DISK),
 [MODE_PAGE_CACHING]= (1  TYPE_DISK) | (1  
TYPE_ROM),
+[MODE_PAGE_R_W_ERROR]  = (1  TYPE_DISK) | (1  
TYPE_ROM),
+[MODE_PAGE_AUDIO_CTL]  = (1  TYPE_ROM),
 [MODE_PAGE_CAPABILITIES]   = (1  TYPE_ROM),
 };
 
@@ -707,13 +709,26 @@ static int mode_sense_page(SCSIDiskState *s, int page, 
uint8_t **p_outbuf,
 }
 break;
 
+case MODE_PAGE_R_W_ERROR:
+p[1] = 10;
+p[2] = 0x80; /* Automatic Write Reallocation Enabled */
+if (s-qdev.type == TYPE_ROM) {
+p[3] = 0x20; /* Read Retry Count */
+}
+break;
+
+case MODE_PAGE_AUDIO_CTL:
+p[1] = 14;
+break;
+
 case MODE_PAGE_CAPABILITIES:
 p[1] = 0x14;
 if (page_control == 1) { /* Changeable Values */
 break;
 }
-p[2] = 3; // CD-R  CD-RW read
-p[3] = 0; // Writing not supported
+
+p[2] = 0x3b; /* CD-R  CD-RW read */
+p[3] = 0; /* Writing not supported */
 p[4] = 0x7f; /* Audio, composite, digital out,
 mode 2 form 12, multi session */
 p[5] = 0xff; /* CD DA, DA accurate, RW supported,
@@ -723,17 +738,17 @@ static int mode_sense_page(SCSIDiskState *s, int page, 
uint8_t **p_outbuf,
 /* Locking supported, jumper present, eject, tray */
 p[7] = 0; /* no volume  mute control, no
  changer */
-p[8] = (50 * 176)  8; // 50x read speed
+p[8] = (50 * 176)  8; /* 50x read speed */
 p[9] = (50 * 176)  0xff;
-p[10] = 0  8; // No volume
-p[11] = 0  0xff;
-p[12] = 2048  8; // 2M buffer
+p[10] = 0  8; /* Volume */
+p[11] = 2  0xff;
+p[12] = 2048  8; /* 2M buffer */
 p[13] = 2048  0xff;
-p[14] = (16 * 176)  8; // 16x read speed current
+p[14] = (16 * 176)  8; /* 16x read speed current */
 p[15] = (16 * 176)  0xff;
-p[18] = (16 * 176)  8; // 16x write speed
+p[18] = (16 * 176)  8; /* 16x write speed */
 p[19] = (16 * 176)  0xff;
-p[20] = (16 * 176)  8; // 16x write speed current
+p[20] = (16 * 176)  8; /* 16x write speed current */
 p[21] = (16 * 176)  0xff;
 break;
 
-- 
1.7.6





Re: [Qemu-devel] [PATCH 9/9] usb-hub: don't trigger assert on packet completion.

2011-10-13 Thread Gerd Hoffmann

  Hi,


-usb_packet_complete(s-dev, packet);
+s-dev.port-ops-complete(s-dev.port, packet);


Oops, that doesn't compile.  Got sidetracked wile waiting for the test 
build finish, then forgot to check the results :(


Updated patch attached.  Branch for pulling updated inplace.

cheers,
  Gerd
From 80cf7cf74f29a219e02b50f27c12b1c792ebf99b Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann kra...@redhat.com
Date: Thu, 13 Oct 2011 12:52:47 +0200
Subject: [PATCH] usb-hub: don't trigger assert on packet completion.

Calling usb_packet_complete() recursively when passing up the completion
event up the chain for devices connected via usb hub will trigger an
assert.  So don't do that, make the usb hub emulation call the upstream
completion callback directly instead.

Based on a patch from Stefan Hajnoczi stefa...@gmail.com

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/usb-hub.c |8 ++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/hw/usb-hub.c b/hw/usb-hub.c
index 39382c7..09c6516 100644
--- a/hw/usb-hub.c
+++ b/hw/usb-hub.c
@@ -207,10 +207,14 @@ static void usb_hub_complete(USBPort *port, USBPacket 
*packet)
 /*
  * Just pass it along upstream for now.
  *
- * If we ever inplement usb 2.0 split transactions this will
+ * If we ever implement usb 2.0 split transactions this will
  * become a little more complicated ...
+ *
+ * Can't use usb_packet_complete() here because packet-owner is
+ * cleared already, go call the -complete() callback directly
+ * instead.
  */
-usb_packet_complete(s-dev, packet);
+s-dev.port-ops-complete(s-dev.port, packet);
 }
 
 static void usb_hub_handle_reset(USBDevice *dev)
-- 
1.7.1



[Qemu-devel] [PATCH 20/35] scsi-disk: do not complete requests twice

2011-10-13 Thread Paolo Bonzini
When scsi_handle_rw_error reports a CHECK CONDITION code, the
owner should not call scsi_req_complete.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-disk.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index b041fd5..d4f773f 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -231,6 +231,7 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, 
int type)
 bdrv_mon_event(s-bs, BDRV_ACTION_STOP, is_read);
 vm_stop(RUN_STATE_IO_ERROR);
 bdrv_iostatus_set_err(s-bs, error);
+return 1;
 } else {
 switch (error) {
 case ENOMEDIUM:
@@ -247,8 +248,8 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, 
int type)
 break;
 }
 bdrv_mon_event(s-bs, BDRV_ACTION_REPORT, is_read);
+return 0;
 }
-return 1;
 }
 
 static void scsi_write_complete(void * opaque, int ret)
-- 
1.7.6





[Qemu-devel] [PATCH 08/35] scsi-disk: store valid mode pages in a table

2011-10-13 Thread Paolo Bonzini
A small refactoring of the MODE SENSE implementation in scsi-disk.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-disk.c |   25 +
 1 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 95a6b77..a4aadf2 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -603,10 +603,23 @@ static int scsi_emulate_mechanism_status(SCSIDiskState 
*s, uint8_t *outbuf)
 static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf,
int page_control)
 {
+static const int mode_sense_valid[0x3f] = {
+[MODE_PAGE_HD_GEOMETRY]= (1  TYPE_DISK),
+[MODE_PAGE_FLEXIBLE_DISK_GEOMETRY] = (1  TYPE_DISK),
+[MODE_PAGE_CACHING]= (1  TYPE_DISK) | (1  
TYPE_ROM),
+[MODE_PAGE_CAPABILITIES]   = (1  TYPE_ROM),
+};
+
 BlockDriverState *bdrv = s-bs;
 int cylinders, heads, secs;
 uint8_t *p = *p_outbuf;
 
+if ((mode_sense_valid[page]  (1  s-qdev.type)) == 0) {
+return -1;
+}
+
+p[0] = page;
+
 /*
  * If Changeable Values are requested, a mask denoting those mode 
parameters
  * that are changeable shall be returned. As we currently don't support
@@ -615,10 +628,6 @@ static int mode_sense_page(SCSIDiskState *s, int page, 
uint8_t **p_outbuf,
  */
 switch (page) {
 case MODE_PAGE_HD_GEOMETRY:
-if (s-qdev.type == TYPE_ROM) {
-return -1;
-}
-p[0] = 4;
 p[1] = 0x16;
 if (page_control == 1) { /* Changeable Values */
 break;
@@ -650,10 +659,6 @@ static int mode_sense_page(SCSIDiskState *s, int page, 
uint8_t **p_outbuf,
 break;
 
 case MODE_PAGE_FLEXIBLE_DISK_GEOMETRY:
-if (s-qdev.type == TYPE_ROM) {
-return -1;
-}
-p[0] = 5;
 p[1] = 0x1e;
 if (page_control == 1) { /* Changeable Values */
 break;
@@ -703,10 +708,6 @@ static int mode_sense_page(SCSIDiskState *s, int page, 
uint8_t **p_outbuf,
 break;
 
 case MODE_PAGE_CAPABILITIES:
-if (s-qdev.type != TYPE_ROM) {
-return -1;
-}
-p[0] = 0x2a;
 p[1] = 0x14;
 if (page_control == 1) { /* Changeable Values */
 break;
-- 
1.7.6





[Qemu-devel] [PULL] usb patch queue

2011-10-13 Thread Gerd Hoffmann
  Hi,

Here comes the usb patch queue with a bunch of bug fixes.
Check the individual patches for details.

please pull,
  Gerd

The following changes since commit ebffe2afceb1a17b5d134b5debf553955fe5ea1a:

  Merge remote-tracking branch 'qmp/queue/qmp' into staging (2011-10-10 
08:21:46 -0500)

are available in the git repository at:

  git://git.kraxel.org/qemu usb.28

Gerd Hoffmann (7):
  usb-storage: fix NULL pointer dereference.
  usb-hub: need to check dev-attached
  usb: fix port reset
  usb-host: factor out code
  usb-host: handle USBDEVFS_SETCONFIGURATION returning EBUSY
  usb-hid: activate usb tablet / mouse after migration.
  usb-hub: don't trigger assert on packet completion.

Peter Maydell (2):
  hw/usb-ohci: Fix OHCI_TD_T1 bit position definition
  hw/usb-ohci: Honour endpoint maximum packet size

 hw/usb-ehci.c |4 +-
 hw/usb-hid.c  |   11 
 hw/usb-hub.c  |   12 +++-
 hw/usb-msd.c  |5 +-
 hw/usb-ohci.c |   41 +
 hw/usb-uhci.c |2 +-
 hw/usb.c  |   12 
 hw/usb.h  |1 +
 usb-linux.c   |  176 -
 9 files changed, 180 insertions(+), 84 deletions(-)



Re: [Qemu-devel] Buggy SDL Zoom

2011-10-13 Thread Stefano Stabellini
On Wed, 12 Oct 2011, Stefan Weil wrote:
 Hi,
 
 the SDL zoom feature which is implemented in sdl_zoom_template.h
 (and the SDL_rotozoom version which it is based on) accesses memory
 beyond the allocated limits.
 
 This can be easily reproduced using Valgrind and some Linux desktop
 which resizes QEMU's window to fill the whole screen (I did run the tests
 on an Ubuntu netbook).
 
 Another effect can be observed by repeatedly increasing the zoom factor
 with the Alt-Ctrl-+: the image grows up to a certain value and then
 collapses again.
 
 It looks like other programs using SDL_rotozoom also discovered
 out-of-bound problems, and in newer versions, the SDL_rotozoom
 code was totally rewritten.
 
 For security reasons, I suggest disabling the zoom feature until
 either the current code is replaced by a (tested) newer version
 of SDL_rotozoom or fixed.

I am OK with that. 



[Qemu-devel] [PATCH 05/35] scsi: notify the device when unit attention is reported

2011-10-13 Thread Paolo Bonzini
Reporting media change events via unit attention sense codes requires
a small state machine: first report NO MEDIUM, then report MEDIUM MAY
HAVE CHANGED.  Unfortunately there is no good hooking point for the
device to notice that its pending unit attention condition has been
reported.  This patch reworks the generic machinery to add one.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-bus.c |   32 +++-
 hw/scsi.h |2 ++
 2 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index fc2f823..c190509 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -295,6 +295,13 @@ static int32_t scsi_target_send_command(SCSIRequest *req, 
uint8_t *buf)
 r-len = scsi_device_get_sense(r-req.dev, r-buf,
MIN(req-cmd.xfer, sizeof r-buf),
(req-cmd.buf[1]  1) == 0);
+if (r-req.dev-sense_is_ua) {
+if (r-req.dev-info-unit_attention_reported) {
+r-req.dev-info-unit_attention_reported(req-dev);
+}
+r-req.dev-sense_len = 0;
+r-req.dev-sense_is_ua = false;
+}
 break;
 default:
 scsi_req_build_sense(req, SENSE_CODE(LUN_NOT_SUPPORTED));
@@ -383,7 +390,13 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, 
uint32_t lun,
 (buf[0] != INQUIRY 
  buf[0] != REPORT_LUNS 
  buf[0] != GET_CONFIGURATION 
- buf[0] != GET_EVENT_STATUS_NOTIFICATION)) {
+ buf[0] != GET_EVENT_STATUS_NOTIFICATION 
+
+ /*
+  * If we already have a pending unit attention condition,
+  * report this one before triggering another one.
+  */
+ !(buf[0] == REQUEST_SENSE  d-sense_is_ua))) {
 req = scsi_req_alloc(reqops_unit_attention, d, tag, lun,
  hba_private);
 } else if (lun != d-lun ||
@@ -479,10 +492,15 @@ int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, 
int len)
  *
  * We assume UA_INTLCK_CTRL to be 00b for HBAs that support autosense, and
  * 10b for HBAs that do not support it (do not call scsi_req_get_sense).
- * In the latter case, scsi_req_complete clears unit attention conditions
- * after moving them to the device's sense buffer.
+ * Here we handle unit attention clearing for UA_INTLCK_CTRL == 00b.
  */
-scsi_clear_unit_attention(req);
+if (req-dev-sense_is_ua) {
+if (req-dev-info-unit_attention_reported) {
+req-dev-info-unit_attention_reported(req-dev);
+}
+req-dev-sense_len = 0;
+req-dev-sense_is_ua = false;
+}
 return ret;
 }
 
@@ -1082,8 +1100,12 @@ void scsi_req_complete(SCSIRequest *req, int status)
 
 if (req-sense_len) {
 memcpy(req-dev-sense, req-sense, req-sense_len);
+req-dev-sense_len = req-sense_len;
+req-dev-sense_is_ua = (req-ops == reqops_unit_attention);
+} else {
+req-dev-sense_len = 0;
+req-dev-sense_is_ua = false;
 }
-req-dev-sense_len = req-sense_len;
 
 /*
  * Unit attention state is now stored in the device's sense buffer
diff --git a/hw/scsi.h b/hw/scsi.h
index e8dcabf..6d40b8e 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -62,6 +62,7 @@ struct SCSIDevice
 BlockConf conf;
 SCSIDeviceInfo *info;
 SCSISense unit_attention;
+bool sense_is_ua;
 uint8_t sense[SCSI_SENSE_BUF_SIZE];
 uint32_t sense_len;
 QTAILQ_HEAD(, SCSIRequest) requests;
@@ -92,6 +93,7 @@ struct SCSIDeviceInfo {
 void (*destroy)(SCSIDevice *s);
 SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
   void *hba_private);
+void (*unit_attention_reported)(SCSIDevice *s);
 SCSIReqOps reqops;
 };
 
-- 
1.7.6





[Qemu-devel] [PATCH 34/35] scsi: pass cdb to alloc_req

2011-10-13 Thread Paolo Bonzini
This will let scsi-block choose between passthrough and emulation.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-bus.c |2 +-
 hw/scsi-disk.c|4 ++--
 hw/scsi-generic.c |2 +-
 hw/scsi.h |2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 252e903..72c0dd2 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -451,7 +451,7 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, 
uint32_t lun,
 req = scsi_req_alloc(reqops_target_command, d, tag, lun,
  hba_private);
 } else {
-req = d-info-alloc_req(d, tag, lun, hba_private);
+req = d-info-alloc_req(d, tag, lun, buf, hba_private);
 }
 }
 
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 90676fe..418b30d 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1591,8 +1591,8 @@ static const SCSIReqOps scsi_disk_reqops = {
 .get_buf  = scsi_get_buf,
 };
 
-static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag,
- uint32_t lun, void *hba_private)
+static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
+ uint8_t *buf, void *hba_private)
 {
 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
 SCSIRequest *req;
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index c4f928a..582d2a6 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -418,7 +418,7 @@ const SCSIReqOps scsi_generic_req_ops = {
 };
 
 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
- void *hba_private)
+ uint8_t *buf, void *hba_private)
 {
 SCSIRequest *req;
 
diff --git a/hw/scsi.h b/hw/scsi.h
index 01c6655..8ea744a 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -94,7 +94,7 @@ struct SCSIDeviceInfo {
 scsi_qdev_initfn init;
 void (*destroy)(SCSIDevice *s);
 SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
-  void *hba_private);
+  uint8_t *buf, void *hba_private);
 void (*unit_attention_reported)(SCSIDevice *s);
 };
 
-- 
1.7.6





Re: [Qemu-devel] [PATCH] pseries: Update SLOF firmware image

2011-10-13 Thread Alexander Graf

On 10/13/2011 07:10 AM, David Gibson wrote:

This patch is a general update to the SLOF firmware image used on the
pseries machine.  This doesn't contain updates for specific features but
contains a number of bugfixes and enhancements in the main SLOF tree from
Thomas Huth.

Signed-off-by: David Gibsonda...@gibson.dropbear.id.au


Thanks, applied.


Alex




[Qemu-devel] [PATCH 15/35] scsi: remove devs array from SCSIBus

2011-10-13 Thread Paolo Bonzini
Change the devs array into a linked list, and add a scsi_device_find
function to navigate the children list instead.  This lets the SCSI
bus use more complex addressing.

scsi_device_find may return another LUN on the same target if none is
found that matches exactly.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/esp.c |5 +++--
 hw/lsi53c895a.c  |   22 +++---
 hw/qdev.h|2 +-
 hw/scsi-bus.c|   53 ++---
 hw/scsi.h|3 +--
 hw/spapr_vscsi.c |   14 ++
 6 files changed, 48 insertions(+), 51 deletions(-)

diff --git a/hw/esp.c b/hw/esp.c
index d3fb1c6..8e17005 100644
--- a/hw/esp.c
+++ b/hw/esp.c
@@ -217,7 +217,8 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf)
 s-async_len = 0;
 }
 
-if (target = ESP_MAX_DEVS || !s-bus.devs[target]) {
+s-current_dev = scsi_device_find(s-bus, target, 0);
+if (!s-current_dev) {
 // No such drive
 s-rregs[ESP_RSTAT] = 0;
 s-rregs[ESP_RINTR] = INTR_DC;
@@ -225,7 +226,6 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf)
 esp_raise_irq(s);
 return 0;
 }
-s-current_dev = s-bus.devs[target];
 return dmalen;
 }
 
@@ -236,6 +236,7 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t 
busid)
 
 trace_esp_do_busid_cmd(busid);
 lun = busid  7;
+s-current_dev = scsi_device_find(s-bus, s-current_dev-id, lun);
 s-current_req = scsi_req_new(s-current_dev, 0, lun, buf, NULL);
 datalen = scsi_req_enqueue(s-current_req);
 s-ti_size = datalen;
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 4eeb496..c15f167 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -531,7 +531,7 @@ static void lsi_bad_selection(LSIState *s, uint32_t id)
 /* Initiate a SCSI layer data transfer.  */
 static void lsi_do_dma(LSIState *s, int out)
 {
-uint32_t count, id;
+uint32_t count;
 target_phys_addr_t addr;
 SCSIDevice *dev;
 
@@ -542,12 +542,8 @@ static void lsi_do_dma(LSIState *s, int out)
 return;
 }
 
-id = (s-current-tag  8)  0xf;
-dev = s-bus.devs[id];
-if (!dev) {
-lsi_bad_selection(s, id);
-return;
-}
+dev = s-current-req-dev;
+assert(dev);
 
 count = s-dbc;
 if (count  s-current-dma_len)
@@ -771,7 +767,7 @@ static void lsi_do_command(LSIState *s)
 s-command_complete = 0;
 
 id = (s-select_tag  8)  0xf;
-dev = s-bus.devs[id];
+dev = scsi_device_find(s-bus, id, s-current_lun);
 if (!dev) {
 lsi_bad_selection(s, id);
 return;
@@ -1202,7 +1198,7 @@ again:
 }
 s-sstat0 |= LSI_SSTAT0_WOA;
 s-scntl1 = ~LSI_SCNTL1_IARB;
-if (id = LSI_MAX_DEVS || !s-bus.devs[id]) {
+if (!scsi_device_find(s-bus, id, 0)) {
 lsi_bad_selection(s, id);
 break;
 }
@@ -1684,13 +1680,9 @@ static void lsi_reg_writeb(LSIState *s, int offset, 
uint8_t val)
 if (val  LSI_SCNTL1_RST) {
 if (!(s-sstat0  LSI_SSTAT0_RST)) {
 DeviceState *dev;
-int id;
 
-for (id = 0; id  LSI_MAX_DEVS; id++) {
-if (s-bus.devs[id]) {
-dev = s-bus.devs[id]-qdev;
-dev-info-reset(dev);
-}
+QTAILQ_FOREACH(dev, s-bus.qbus.children, sibling) {
+dev-info-reset(dev);
 }
 s-sstat0 |= LSI_SSTAT0_RST;
 lsi_script_scsi_interrupt(s, LSI_SIST0_RST, 0);
diff --git a/hw/qdev.h b/hw/qdev.h
index ff524cb..e5ad781 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -73,7 +73,7 @@ struct BusState {
 const char *name;
 int allow_hotplug;
 int qdev_allocated;
-QTAILQ_HEAD(, DeviceState) children;
+QTAILQ_HEAD(ChildrenHead, DeviceState) children;
 QLIST_ENTRY(BusState) sibling;
 };
 
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index d9d4e18..7104e98 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -37,12 +37,16 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo 
*base)
 SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
 SCSIDeviceInfo *info = DO_UPCAST(SCSIDeviceInfo, qdev, base);
 SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev-qdev.parent_bus);
+SCSIDevice *olddev;
 int rc = -1;
 
 if (dev-id == -1) {
-for (dev-id = 0; dev-id  bus-info-ndev; dev-id++) {
-if (bus-devs[dev-id] == NULL)
+int id;
+for (id = 0; id  bus-info-ndev; id++) {
+if (!scsi_device_find(bus, id, 0)) {
+dev-id = id;
 break;
+}
 }
 }
 if (dev-id = bus-info-ndev) {
@@ -50,17 +54,14 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo 
*base)
 goto err;
 }
 
-if (bus-devs[dev-id]) {
-qdev_free(bus-devs[dev-id]-qdev);
+

[Qemu-devel] [PATCH 28/35] scsi-disk: do not duplicate BlockDriverState member

2011-10-13 Thread Paolo Bonzini
Same as for scsi-generic, avoid duplication even if it causes longer
lines.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-disk.c |   94 +++
 1 files changed, 46 insertions(+), 48 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 860a3bf..5e3ef51 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -65,7 +65,6 @@ typedef struct SCSIDiskReq {
 struct SCSIDiskState
 {
 SCSIDevice qdev;
-BlockDriverState *bs;
 /* The qemu block layer uses a fixed 512 byte sector size.
This is the number of 512 byte blocks in a single scsi sector.  */
 int cluster_size;
@@ -119,7 +118,7 @@ static uint32_t scsi_init_iovec(SCSIDiskReq *r)
 
 if (!r-iov.iov_base) {
 r-buflen = SCSI_DMA_BUF_SIZE;
-r-iov.iov_base = qemu_blockalign(s-bs, r-buflen);
+r-iov.iov_base = qemu_blockalign(s-qdev.conf.bs, r-buflen);
 }
 r-iov.iov_len = MIN(r-sector_count * 512, r-buflen);
 qemu_iovec_init_external(r-qiov, r-iov, 1);
@@ -134,7 +133,7 @@ static void scsi_read_complete(void * opaque, int ret)
 
 if (r-req.aiocb != NULL) {
 r-req.aiocb = NULL;
-bdrv_acct_done(s-bs, r-acct);
+bdrv_acct_done(s-qdev.conf.bs, r-acct);
 }
 
 if (ret) {
@@ -160,7 +159,7 @@ static void scsi_flush_complete(void * opaque, int ret)
 
 if (r-req.aiocb != NULL) {
 r-req.aiocb = NULL;
-bdrv_acct_done(s-bs, r-acct);
+bdrv_acct_done(s-qdev.conf.bs, r-acct);
 }
 
 if (ret  0) {
@@ -210,8 +209,8 @@ static void scsi_read_data(SCSIRequest *req)
 /* Save a ref for scsi_read_complete, in case r is canceled.  */
 scsi_req_ref(r-req);
 n = scsi_init_iovec(r);
-bdrv_acct_start(s-bs, r-acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
-r-req.aiocb = bdrv_aio_readv(s-bs, r-sector, r-qiov, n,
+bdrv_acct_start(s-qdev.conf.bs, r-acct, n * BDRV_SECTOR_SIZE, 
BDRV_ACCT_READ);
+r-req.aiocb = bdrv_aio_readv(s-qdev.conf.bs, r-sector, r-qiov, n,
   scsi_read_complete, r);
 if (r-req.aiocb == NULL) {
 scsi_read_complete(r, -EIO);
@@ -222,10 +221,10 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int 
error, int type)
 {
 int is_read = (type == SCSI_REQ_STATUS_RETRY_READ);
 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r-req.dev);
-BlockErrorAction action = bdrv_get_on_error(s-bs, is_read);
+BlockErrorAction action = bdrv_get_on_error(s-qdev.conf.bs, is_read);
 
 if (action == BLOCK_ERR_IGNORE) {
-bdrv_mon_event(s-bs, BDRV_ACTION_IGNORE, is_read);
+bdrv_mon_event(s-qdev.conf.bs, BDRV_ACTION_IGNORE, is_read);
 return 0;
 }
 
@@ -235,9 +234,9 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, 
int type)
 type = SCSI_REQ_STATUS_RETRY_TYPE_MASK;
 r-status |= SCSI_REQ_STATUS_RETRY | type;
 
-bdrv_mon_event(s-bs, BDRV_ACTION_STOP, is_read);
+bdrv_mon_event(s-qdev.conf.bs, BDRV_ACTION_STOP, is_read);
 vm_stop(RUN_STATE_IO_ERROR);
-bdrv_iostatus_set_err(s-bs, error);
+bdrv_iostatus_set_err(s-qdev.conf.bs, error);
 return 1;
 } else {
 switch (error) {
@@ -254,7 +253,7 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, 
int type)
 scsi_check_condition(r, SENSE_CODE(IO_ERROR));
 break;
 }
-bdrv_mon_event(s-bs, BDRV_ACTION_REPORT, is_read);
+bdrv_mon_event(s-qdev.conf.bs, BDRV_ACTION_REPORT, is_read);
 return 0;
 }
 }
@@ -267,7 +266,7 @@ static void scsi_write_complete(void * opaque, int ret)
 
 if (r-req.aiocb != NULL) {
 r-req.aiocb = NULL;
-bdrv_acct_done(s-bs, r-acct);
+bdrv_acct_done(s-qdev.conf.bs, r-acct);
 }
 
 if (ret) {
@@ -311,8 +310,8 @@ static void scsi_write_data(SCSIRequest *req)
 if (s-tray_open) {
 scsi_write_complete(r, -ENOMEDIUM);
 }
-bdrv_acct_start(s-bs, r-acct, n * BDRV_SECTOR_SIZE, 
BDRV_ACCT_WRITE);
-r-req.aiocb = bdrv_aio_writev(s-bs, r-sector, r-qiov, n,
+bdrv_acct_start(s-qdev.conf.bs, r-acct, n * BDRV_SECTOR_SIZE, 
BDRV_ACCT_WRITE);
+r-req.aiocb = bdrv_aio_writev(s-qdev.conf.bs, r-sector, r-qiov, n,
scsi_write_complete, r);
 if (r-req.aiocb == NULL) {
 scsi_write_complete(r, -ENOMEM);
@@ -450,7 +449,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, 
uint8_t *outbuf)
 case 0x83: /* Device identification page, mandatory */
 {
 int max_len = 255 - 8;
-int id_len = strlen(bdrv_get_device_name(s-bs));
+int id_len = strlen(bdrv_get_device_name(s-qdev.conf.bs));
 
 if (id_len  max_len)
 id_len = max_len;
@@ -463,7 +462,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, 
uint8_t *outbuf)
 outbuf[buflen++] = 0;   // reserved
 

[Qemu-devel] [PATCH 21/35] scsi-disk: bump SCSIRequest reference count until aio completion runs

2011-10-13 Thread Paolo Bonzini
In some cases a request may be canceled before the completion
callback runs.  Keep a reference to the request between starting
an AIO operation, and let scsi_*_complete remove it.

Since scsi_handle_rw_error returns whether something else has to
be done for the request by the caller, it makes sense to transfer
ownership of the ref to scsi_handle_rw_error when it returns 1;
scsi_dma_restart_bh will then free the reference after restarting
the operation.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-disk.c |   14 ++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index d4f773f..3f54891 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -139,6 +139,7 @@ static void scsi_read_complete(void * opaque, int ret)
 
 if (ret) {
 if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_READ)) {
+/* Leave in ref for scsi_dma_restart_bh.  */
 return;
 }
 }
@@ -149,6 +150,7 @@ static void scsi_read_complete(void * opaque, int ret)
 r-sector += n;
 r-sector_count -= n;
 scsi_req_data(r-req, r-qiov.size);
+scsi_req_unref(r-req);
 }
 
 static void scsi_flush_complete(void * opaque, int ret)
@@ -163,11 +165,13 @@ static void scsi_flush_complete(void * opaque, int ret)
 
 if (ret  0) {
 if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_FLUSH)) {
+/* Leave in ref for scsi_dma_restart_bh.  */
 return;
 }
 }
 
 scsi_req_complete(r-req, GOOD);
+scsi_req_unref(r-req);
 }
 
 /* Read more data from scsi device into buffer.  */
@@ -202,6 +206,9 @@ static void scsi_read_data(SCSIRequest *req)
 if (s-tray_open) {
 scsi_read_complete(r, -ENOMEDIUM);
 }
+
+/* Save a ref for scsi_read_complete, in case r is canceled.  */
+scsi_req_ref(r-req);
 n = scsi_init_iovec(r);
 bdrv_acct_start(s-bs, r-acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
 r-req.aiocb = bdrv_aio_readv(s-bs, r-sector, r-qiov, n,
@@ -279,6 +286,7 @@ static void scsi_write_complete(void * opaque, int ret)
 DPRINTF(Write complete tag=0x%x more=%d\n, r-req.tag, r-qiov.size);
 scsi_req_data(r-req, r-qiov.size);
 }
+scsi_req_unref(r-req);
 }
 
 static void scsi_write_data(SCSIRequest *req)
@@ -296,6 +304,8 @@ static void scsi_write_data(SCSIRequest *req)
 return;
 }
 
+/* Save a ref for scsi_write_complete, in case r is canceled.  */
+scsi_req_ref(r-req);
 n = r-qiov.size / 512;
 if (n) {
 if (s-tray_open) {
@@ -344,6 +354,8 @@ static void scsi_dma_restart_bh(void *opaque)
 scsi_req_complete(r-req, GOOD);
 }
 }
+/* This reference was left in by scsi_handle_rw_error.  */
+scsi_req_unref(r-req);
 }
 }
 }
@@ -1325,6 +1337,8 @@ static int32_t scsi_send_command(SCSIRequest *req, 
uint8_t *buf)
 r-iov.iov_len = rc;
 break;
 case SYNCHRONIZE_CACHE:
+/* Save a ref for scsi_flush_complete, in case r is canceled.  */
+scsi_req_ref(r-req);
 bdrv_acct_start(s-bs, r-acct, 0, BDRV_ACCT_FLUSH);
 r-req.aiocb = bdrv_aio_flush(s-bs, scsi_flush_complete, r);
 if (r-req.aiocb == NULL) {
-- 
1.7.6





Re: [Qemu-devel] [0/4] ppc: Implement -host CPU

2011-10-13 Thread Alexander Graf

On 10/13/2011 10:40 AM, David Gibson wrote:

This series of patches implements a -cpu host option for ppc,
analagous to the version that already exists for x86.  For now, only
the basic framework is implement.  In later patches, we will need to
improve the code to override those parts of the cpu spec that can be
queried from the host, and use this mechanism to subsume, for example,
the current advertisement by the pseries machine of KVM CPU
capabilities to the guest.


Thanks, applied all to ppc-next.


Alex




[Qemu-devel] [PATCH 13/35] scsi: move tcq/ndev to SCSIBusOps (now SCSIBusInfo)

2011-10-13 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/esp.c |7 +--
 hw/lsi53c895a.c  |9 ++---
 hw/scsi-bus.c|   27 ---
 hw/scsi-disk.c   |2 +-
 hw/scsi.h|   11 +--
 hw/spapr_vscsi.c |8 +---
 hw/usb-msd.c |7 +--
 7 files changed, 39 insertions(+), 32 deletions(-)

diff --git a/hw/esp.c b/hw/esp.c
index 697c2c5..d3fb1c6 100644
--- a/hw/esp.c
+++ b/hw/esp.c
@@ -720,7 +720,10 @@ void esp_init(target_phys_addr_t espaddr, int it_shift,
 *dma_enable = qdev_get_gpio_in(dev, 1);
 }
 
-static const struct SCSIBusOps esp_scsi_ops = {
+static const struct SCSIBusInfo esp_scsi_info = {
+.tcq = false,
+.ndev = ESP_MAX_DEVS,
+
 .transfer_data = esp_transfer_data,
 .complete = esp_command_complete,
 .cancel = esp_request_cancelled
@@ -740,7 +743,7 @@ static int esp_init1(SysBusDevice *dev)
 
 qdev_init_gpio_in(dev-qdev, esp_gpio_demux, 2);
 
-scsi_bus_new(s-bus, dev-qdev, 0, ESP_MAX_DEVS, esp_scsi_ops);
+scsi_bus_new(s-bus, dev-qdev, esp_scsi_info);
 return scsi_bus_legacy_handle_cmdline(s-bus);
 }
 
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index e077ec0..4eeb496 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -1686,7 +1686,7 @@ static void lsi_reg_writeb(LSIState *s, int offset, 
uint8_t val)
 DeviceState *dev;
 int id;
 
-for (id = 0; id  s-bus.ndev; id++) {
+for (id = 0; id  LSI_MAX_DEVS; id++) {
 if (s-bus.devs[id]) {
 dev = s-bus.devs[id]-qdev;
 dev-info-reset(dev);
@@ -2091,7 +2091,10 @@ static int lsi_scsi_uninit(PCIDevice *d)
 return 0;
 }
 
-static const struct SCSIBusOps lsi_scsi_ops = {
+static const struct SCSIBusInfo lsi_scsi_info = {
+.tcq = true,
+.ndev = LSI_MAX_DEVS,
+
 .transfer_data = lsi_transfer_data,
 .complete = lsi_command_complete,
 .cancel = lsi_request_cancelled
@@ -2118,7 +2121,7 @@ static int lsi_scsi_init(PCIDevice *dev)
 pci_register_bar(s-dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, s-ram_io);
 QTAILQ_INIT(s-queue);
 
-scsi_bus_new(s-bus, dev-qdev, 1, LSI_MAX_DEVS, lsi_scsi_ops);
+scsi_bus_new(s-bus, dev-qdev, lsi_scsi_info);
 if (!dev-qdev.hotplugged) {
 return scsi_bus_legacy_handle_cmdline(s-bus);
 }
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 867b1a8..d9d4e18 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -24,14 +24,11 @@ static struct BusInfo scsi_bus_info = {
 static int next_scsi_bus;
 
 /* Create a scsi bus, and attach devices to it.  */
-void scsi_bus_new(SCSIBus *bus, DeviceState *host, int tcq, int ndev,
-  const SCSIBusOps *ops)
+void scsi_bus_new(SCSIBus *bus, DeviceState *host, const SCSIBusInfo *info)
 {
 qbus_create_inplace(bus-qbus, scsi_bus_info, host, NULL);
 bus-busnr = next_scsi_bus++;
-bus-tcq = tcq;
-bus-ndev = ndev;
-bus-ops = ops;
+bus-info = info;
 bus-qbus.allow_hotplug = 1;
 }
 
@@ -43,12 +40,12 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo 
*base)
 int rc = -1;
 
 if (dev-id == -1) {
-for (dev-id = 0; dev-id  bus-ndev; dev-id++) {
+for (dev-id = 0; dev-id  bus-info-ndev; dev-id++) {
 if (bus-devs[dev-id] == NULL)
 break;
 }
 }
-if (dev-id = bus-ndev) {
+if (dev-id = bus-info-ndev) {
 error_report(bad scsi device id: %d, dev-id);
 goto err;
 }
@@ -120,7 +117,7 @@ int scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
 int res = 0, unit;
 
 loc_push_none(loc);
-for (unit = 0; unit  bus-ndev; unit++) {
+for (unit = 0; unit  bus-info-ndev; unit++) {
 dinfo = drive_get(IF_SCSI, bus-busnr, unit);
 if (dinfo == NULL) {
 continue;
@@ -265,7 +262,7 @@ static bool scsi_target_emulate_inquiry(SCSITargetReq *r)
 r-buf[2] = 5; /* Version */
 r-buf[3] = 2 | 0x10; /* HiSup, response data format */
 r-buf[4] = r-len - 5; /* Additional Length = (Len - 1) - 4 */
-r-buf[7] = 0x10 | (r-req.bus-tcq ? 0x02 : 0); /* Sync, TCQ.  */
+r-buf[7] = 0x10 | (r-req.bus-info-tcq ? 0x02 : 0); /* Sync, TCQ.  
*/
 memcpy(r-buf[8], QEMU, 8);
 memcpy(r-buf[16], QEMU TARGET , 16);
 strncpy((char *) r-buf[32], QEMU_VERSION, 4);
@@ -1062,7 +1059,7 @@ void scsi_req_continue(SCSIRequest *req)
 void scsi_req_data(SCSIRequest *req, int len)
 {
 trace_scsi_req_data(req-dev-id, req-lun, req-tag, len);
-req-bus-ops-transfer_data(req, len);
+req-bus-info-transfer_data(req, len);
 }
 
 void scsi_req_print(SCSIRequest *req)
@@ -1121,7 +1118,7 @@ void scsi_req_complete(SCSIRequest *req, int status)
 
 scsi_req_ref(req);
 scsi_req_dequeue(req);
-req-bus-ops-complete(req, req-status);
+req-bus-info-complete(req, req-status);
 scsi_req_unref(req);
 }
 
@@ -1132,8 +1129,8 @@ void 

Re: [Qemu-devel] [PATCH 07/11] audio/spice: add support for volume control

2011-10-13 Thread Marc-André Lureau
Hi

On Tue, Oct 11, 2011 at 10:49 AM, Gerd Hoffmann kra...@redhat.com wrote:
 +#else
 +#warning Spice playback volume unsupported
 +#endif

 +#else
 +#warning Spice record volume unsupported
 +#endif

 One warning is enougth.  But given that qemu builds with -Werror by default
 printing a warning just because of an older spice-server version is a bad
 idea IMHO.

There were 2 warnings, because the interfaces checked are different.
But since qemu build with -Werror, let's just remove them.

 @@ -337,6 +379,7 @@ struct audio_driver spice_audio_driver = {
      .max_voices_in  = 1,
      .voice_size_out = sizeof (SpiceVoiceOut),
      .voice_size_in  = sizeof (SpiceVoiceIn),
 +    .ctl_caps       = VOICE_VOLUME_CAP

 This should be #ifdef'ed too I guess?

Agreed, to fallback on mixemu volume in that case.

-- 
Marc-André Lureau



[Qemu-devel] [PATCH v2 4/5] block: mark blocks dirty on coroutine write completion

2011-10-13 Thread Stefan Hajnoczi
The aio write operation marks blocks dirty when the write operation
completes.  The coroutine write operation marks blocks dirty before
issuing the write operation.

It seems safest to mark the block dirty when the operation completes so
that anything tracking dirty blocks will not act before the change has
been made to the image file.

Make the coroutine write operation dirty blocks on write completion.

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 block.c |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/block.c b/block.c
index e94fa61..02e15ca 100644
--- a/block.c
+++ b/block.c
@@ -1311,6 +1311,7 @@ static int coroutine_fn 
bdrv_co_do_writev(BlockDriverState *bs,
 int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
 {
 BlockDriver *drv = bs-drv;
+int ret;
 
 if (!bs-drv) {
 return -ENOMEDIUM;
@@ -1322,6 +1323,8 @@ static int coroutine_fn 
bdrv_co_do_writev(BlockDriverState *bs,
 return -EIO;
 }
 
+ret = drv-bdrv_co_writev(bs, sector_num, nb_sectors, qiov);
+
 if (bs-dirty_bitmap) {
 set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
 }
@@ -1330,7 +1333,7 @@ static int coroutine_fn 
bdrv_co_do_writev(BlockDriverState *bs,
 bs-wr_highest_sector = sector_num + nb_sectors - 1;
 }
 
-return drv-bdrv_co_writev(bs, sector_num, nb_sectors, qiov);
+return ret;
 }
 
 int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num,
-- 
1.7.6.3




[Qemu-devel] [PATCH v2 0/5] block: do request processing in a coroutine

2011-10-13 Thread Stefan Hajnoczi
Note: this version applies against Kevin's block tree

Block layer features like dirty block tracing, I/O throttling, and live block
copy are forced to duplicate code due to the three different interfaces:
synchronous, asynchronous, and coroutines.

Since there are bdrv_read(), bdrv_aio_readv(), and bdrv_co_readv() interfaces
for read (and similar for write), per-request processing needs to be duplicated
for each of these execution contexts.  For example, dirty block tracking code
is duplicated across these three interfaces.

This patch series unifies request processing so that there is only one code
path.  I see this as a prerequisite to the live block copy (image streaming)
code I am working on, so I'm pushing it now.

The short-term win from this series is that it becomes easy to add live block
copy and other features.  We now have a single code path where the perf-request
processing is done.

The longer-term win will be dropping the BlockDriver .bdrv_read(),
.bdrv_write(), .bdrv_aio_readv(), and .bdrv_aio_writev() interfaces.  By doing
that we can bring all BlockDrivers onto a common interface, namely
.bdrv_co_readv() and .bdrv_co_writev().  It will also allow us to drop most of
the sync and aio emulation code.

A consequence of this patch series is that every I/O request goes through at
least one coroutine.  There is no longer a direct .bdrv_read(), .bdrv_write(),
.bdrv_aio_readv(), or .bdrv_aio_writev() call - we're trying to phase out those
interfaces.  I have not noticed performance degradation in correctness tests
but we need to confirm that there has not been a performance regression.

v2:
 * Fixed bdrv_read()/bdrv_write() infinite loop [Kevin]

Stefan Hajnoczi (5):
  block: directly invoke .bdrv_* from emulation functions
  block: switch bdrv_read()/bdrv_write() to coroutines
  block: switch bdrv_aio_readv() to coroutines
  block: mark blocks dirty on coroutine write completion
  block: switch bdrv_aio_writev() to coroutines

 block.c |  245 --
 1 files changed, 111 insertions(+), 134 deletions(-)

-- 
1.7.6.3




[Qemu-devel] [PATCH v2 5/5] block: switch bdrv_aio_writev() to coroutines

2011-10-13 Thread Stefan Hajnoczi
More sync, aio, and coroutine unification.  Make bdrv_aio_writev() go
through coroutine request processing.

Remove the dirty block callback mechanism which was needed only for aio
processing and can be done more naturally in coroutine context.

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 block.c |   66 +-
 1 files changed, 2 insertions(+), 64 deletions(-)

diff --git a/block.c b/block.c
index 02e15ca..8c7d05e 100644
--- a/block.c
+++ b/block.c
@@ -2385,76 +2385,14 @@ BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, 
int64_t sector_num,
  cb, opaque, false, bdrv_co_do_rw);
 }
 
-typedef struct BlockCompleteData {
-BlockDriverCompletionFunc *cb;
-void *opaque;
-BlockDriverState *bs;
-int64_t sector_num;
-int nb_sectors;
-} BlockCompleteData;
-
-static void block_complete_cb(void *opaque, int ret)
-{
-BlockCompleteData *b = opaque;
-
-if (b-bs-dirty_bitmap) {
-set_dirty_bitmap(b-bs, b-sector_num, b-nb_sectors, 1);
-}
-b-cb(b-opaque, ret);
-g_free(b);
-}
-
-static BlockCompleteData *blk_dirty_cb_alloc(BlockDriverState *bs,
- int64_t sector_num,
- int nb_sectors,
- BlockDriverCompletionFunc *cb,
- void *opaque)
-{
-BlockCompleteData *blkdata = g_malloc0(sizeof(BlockCompleteData));
-
-blkdata-bs = bs;
-blkdata-cb = cb;
-blkdata-opaque = opaque;
-blkdata-sector_num = sector_num;
-blkdata-nb_sectors = nb_sectors;
-
-return blkdata;
-}
-
 BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
   QEMUIOVector *qiov, int nb_sectors,
   BlockDriverCompletionFunc *cb, void *opaque)
 {
-BlockDriver *drv = bs-drv;
-BlockDriverAIOCB *ret;
-BlockCompleteData *blk_cb_data;
-
 trace_bdrv_aio_writev(bs, sector_num, nb_sectors, opaque);
 
-if (!drv)
-return NULL;
-if (bs-read_only)
-return NULL;
-if (bdrv_check_request(bs, sector_num, nb_sectors))
-return NULL;
-
-if (bs-dirty_bitmap) {
-blk_cb_data = blk_dirty_cb_alloc(bs, sector_num, nb_sectors, cb,
- opaque);
-cb = block_complete_cb;
-opaque = blk_cb_data;
-}
-
-ret = drv-bdrv_aio_writev(bs, sector_num, qiov, nb_sectors,
-   cb, opaque);
-
-if (ret) {
-if (bs-wr_highest_sector  sector_num + nb_sectors - 1) {
-bs-wr_highest_sector = sector_num + nb_sectors - 1;
-}
-}
-
-return ret;
+return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors,
+ cb, opaque, true, bdrv_co_do_rw);
 }
 
 
-- 
1.7.6.3




[Qemu-devel] [PATCH v2 3/5] block: switch bdrv_aio_readv() to coroutines

2011-10-13 Thread Stefan Hajnoczi
More sync, aio, and coroutine unification.  Make bdrv_aio_readv() go
through coroutine request processing.

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 block.c |   48 +++-
 1 files changed, 35 insertions(+), 13 deletions(-)

diff --git a/block.c b/block.c
index ae8fc80..e94fa61 100644
--- a/block.c
+++ b/block.c
@@ -78,6 +78,15 @@ static int coroutine_fn bdrv_co_do_readv(BlockDriverState 
*bs,
 int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
 static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
 int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
+static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
+   int64_t sector_num,
+   QEMUIOVector *qiov,
+   int nb_sectors,
+   BlockDriverCompletionFunc *cb,
+   void *opaque,
+   bool is_write,
+   CoroutineEntry *entry);
+static void coroutine_fn bdrv_co_do_rw(void *opaque);
 
 static QTAILQ_HEAD(, BlockDriverState) bdrv_states =
 QTAILQ_HEAD_INITIALIZER(bdrv_states);
@@ -2367,17 +2376,10 @@ BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, 
int64_t sector_num,
  QEMUIOVector *qiov, int nb_sectors,
  BlockDriverCompletionFunc *cb, void *opaque)
 {
-BlockDriver *drv = bs-drv;
-
 trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque);
 
-if (!drv)
-return NULL;
-if (bdrv_check_request(bs, sector_num, nb_sectors))
-return NULL;
-
-return drv-bdrv_aio_readv(bs, sector_num, qiov, nb_sectors,
-   cb, opaque);
+return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors,
+ cb, opaque, false, bdrv_co_do_rw);
 }
 
 typedef struct BlockCompleteData {
@@ -2824,6 +2826,7 @@ static void bdrv_co_rw_bh(void *opaque)
 qemu_aio_release(acb);
 }
 
+/* Invoke .bdrv_co_readv/.bdrv_co_writev */
 static void coroutine_fn bdrv_co_rw(void *opaque)
 {
 BlockDriverAIOCBCoroutine *acb = opaque;
@@ -2841,13 +2844,32 @@ static void coroutine_fn bdrv_co_rw(void *opaque)
 qemu_bh_schedule(acb-bh);
 }
 
+/* Invoke bdrv_co_do_readv/bdrv_co_do_writev */
+static void coroutine_fn bdrv_co_do_rw(void *opaque)
+{
+BlockDriverAIOCBCoroutine *acb = opaque;
+BlockDriverState *bs = acb-common.bs;
+
+if (!acb-is_write) {
+acb-req.error = bdrv_co_do_readv(bs, acb-req.sector,
+acb-req.nb_sectors, acb-req.qiov);
+} else {
+acb-req.error = bdrv_co_do_writev(bs, acb-req.sector,
+acb-req.nb_sectors, acb-req.qiov);
+}
+
+acb-bh = qemu_bh_new(bdrv_co_rw_bh, acb);
+qemu_bh_schedule(acb-bh);
+}
+
 static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
int64_t sector_num,
QEMUIOVector *qiov,
int nb_sectors,
BlockDriverCompletionFunc *cb,
void *opaque,
-   bool is_write)
+   bool is_write,
+   CoroutineEntry *entry)
 {
 Coroutine *co;
 BlockDriverAIOCBCoroutine *acb;
@@ -2858,7 +2880,7 @@ static BlockDriverAIOCB 
*bdrv_co_aio_rw_vector(BlockDriverState *bs,
 acb-req.qiov = qiov;
 acb-is_write = is_write;
 
-co = qemu_coroutine_create(bdrv_co_rw);
+co = qemu_coroutine_create(entry);
 qemu_coroutine_enter(co, acb);
 
 return acb-common;
@@ -2869,7 +2891,7 @@ static BlockDriverAIOCB 
*bdrv_co_aio_readv_em(BlockDriverState *bs,
 BlockDriverCompletionFunc *cb, void *opaque)
 {
 return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque,
- false);
+ false, bdrv_co_rw);
 }
 
 static BlockDriverAIOCB *bdrv_co_aio_writev_em(BlockDriverState *bs,
@@ -2877,7 +2899,7 @@ static BlockDriverAIOCB 
*bdrv_co_aio_writev_em(BlockDriverState *bs,
 BlockDriverCompletionFunc *cb, void *opaque)
 {
 return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque,
- true);
+ true, bdrv_co_rw);
 }
 
 static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs,
-- 
1.7.6.3




[Qemu-devel] [PATCH v2 1/5] block: directly invoke .bdrv_* from emulation functions

2011-10-13 Thread Stefan Hajnoczi
The emulation functions which supply default BlockDriver .bdrv_*()
functions given another implemented .bdrv_*() function should not use
public bdrv_*() interfaces.  This patch ensures they invoke .bdrv_*()
directly to avoid adding an extra layer of coroutine request processing
and possibly entering an infinite loop.

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 block.c |   14 --
 1 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/block.c b/block.c
index 62903dd..f4731ec 100644
--- a/block.c
+++ b/block.c
@@ -2759,9 +2759,9 @@ static BlockDriverAIOCB 
*bdrv_aio_rw_vector(BlockDriverState *bs,
 
 if (is_write) {
 qemu_iovec_to_buffer(acb-qiov, acb-bounce);
-acb-ret = bdrv_write(bs, sector_num, acb-bounce, nb_sectors);
+acb-ret = bs-drv-bdrv_write(bs, sector_num, acb-bounce, 
nb_sectors);
 } else {
-acb-ret = bdrv_read(bs, sector_num, acb-bounce, nb_sectors);
+acb-ret = bs-drv-bdrv_read(bs, sector_num, acb-bounce, nb_sectors);
 }
 
 qemu_bh_schedule(acb-bh);
@@ -2926,8 +2926,9 @@ static int bdrv_read_em(BlockDriverState *bs, int64_t 
sector_num,
 iov.iov_base = (void *)buf;
 iov.iov_len = nb_sectors * BDRV_SECTOR_SIZE;
 qemu_iovec_init_external(qiov, iov, 1);
-acb = bdrv_aio_readv(bs, sector_num, qiov, nb_sectors,
-bdrv_rw_em_cb, async_ret);
+
+acb = bs-drv-bdrv_aio_readv(bs, sector_num, qiov, nb_sectors,
+  bdrv_rw_em_cb, async_ret);
 if (acb == NULL) {
 async_ret = -1;
 goto fail;
@@ -2954,8 +2955,9 @@ static int bdrv_write_em(BlockDriverState *bs, int64_t 
sector_num,
 iov.iov_base = (void *)buf;
 iov.iov_len = nb_sectors * BDRV_SECTOR_SIZE;
 qemu_iovec_init_external(qiov, iov, 1);
-acb = bdrv_aio_writev(bs, sector_num, qiov, nb_sectors,
-bdrv_rw_em_cb, async_ret);
+
+acb = bs-drv-bdrv_aio_writev(bs, sector_num, qiov, nb_sectors,
+   bdrv_rw_em_cb, async_ret);
 if (acb == NULL) {
 async_ret = -1;
 goto fail;
-- 
1.7.6.3




[Qemu-devel] [PATCH v2 2/5] block: switch bdrv_read()/bdrv_write() to coroutines

2011-10-13 Thread Stefan Hajnoczi
The bdrv_read()/bdrv_write() functions call .bdrv_read()/.bdrv_write().
They should go through bdrv_co_do_readv() and bdrv_co_do_writev()
instead in order to unify request processing code across sync, aio, and
coroutine interfaces.  This is also an important step towards removing
BlockDriverState .bdrv_read()/.bdrv_write() in the future.

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 block.c |  112 +++
 1 files changed, 62 insertions(+), 50 deletions(-)

diff --git a/block.c b/block.c
index f4731ec..ae8fc80 100644
--- a/block.c
+++ b/block.c
@@ -44,6 +44,8 @@
 #include windows.h
 #endif
 
+#define NOT_DONE 0x7fff /* used while emulated sync operation in progress 
*/
+
 static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load);
 static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
 int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
@@ -74,6 +76,8 @@ static int coroutine_fn bdrv_co_writev_em(BlockDriverState 
*bs,
 static int coroutine_fn bdrv_co_flush_em(BlockDriverState *bs);
 static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
 int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
+static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
+int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
 
 static QTAILQ_HEAD(, BlockDriverState) bdrv_states =
 QTAILQ_HEAD_INITIALIZER(bdrv_states);
@@ -1042,30 +1046,69 @@ static inline bool bdrv_has_async_flush(BlockDriver 
*drv)
 return drv-bdrv_aio_flush != bdrv_aio_flush_em;
 }
 
-/* return  0 if error. See bdrv_write() for the return codes */
-int bdrv_read(BlockDriverState *bs, int64_t sector_num,
-  uint8_t *buf, int nb_sectors)
+typedef struct RwCo {
+BlockDriverState *bs;
+int64_t sector_num;
+int nb_sectors;
+QEMUIOVector *qiov;
+bool is_write;
+int ret;
+} RwCo;
+
+static void coroutine_fn bdrv_rw_co_entry(void *opaque)
 {
-BlockDriver *drv = bs-drv;
+RwCo *rwco = opaque;
 
-if (!drv)
-return -ENOMEDIUM;
+if (!rwco-is_write) {
+rwco-ret = bdrv_co_do_readv(rwco-bs, rwco-sector_num,
+ rwco-nb_sectors, rwco-qiov);
+} else {
+rwco-ret = bdrv_co_do_writev(rwco-bs, rwco-sector_num,
+  rwco-nb_sectors, rwco-qiov);
+}
+}
 
-if (bdrv_has_async_rw(drv)  qemu_in_coroutine()) {
-QEMUIOVector qiov;
-struct iovec iov = {
-.iov_base = (void *)buf,
-.iov_len = nb_sectors * BDRV_SECTOR_SIZE,
-};
+/*
+ * Process a synchronous request using coroutines
+ */
+static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
+  int nb_sectors, bool is_write)
+{
+QEMUIOVector qiov;
+struct iovec iov = {
+.iov_base = (void *)buf,
+.iov_len = nb_sectors * BDRV_SECTOR_SIZE,
+};
+Coroutine *co;
+RwCo rwco = {
+.bs = bs,
+.sector_num = sector_num,
+.nb_sectors = nb_sectors,
+.qiov = qiov,
+.is_write = is_write,
+.ret = NOT_DONE,
+};
 
-qemu_iovec_init_external(qiov, iov, 1);
-return bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
-}
+qemu_iovec_init_external(qiov, iov, 1);
 
-if (bdrv_check_request(bs, sector_num, nb_sectors))
-return -EIO;
+if (qemu_in_coroutine()) {
+/* Fast-path if already in coroutine context */
+bdrv_rw_co_entry(rwco);
+} else {
+co = qemu_coroutine_create(bdrv_rw_co_entry);
+qemu_coroutine_enter(co, rwco);
+while (rwco.ret == NOT_DONE) {
+qemu_aio_wait();
+}
+}
+return rwco.ret;
+}
 
-return drv-bdrv_read(bs, sector_num, buf, nb_sectors);
+/* return  0 if error. See bdrv_write() for the return codes */
+int bdrv_read(BlockDriverState *bs, int64_t sector_num,
+  uint8_t *buf, int nb_sectors)
+{
+return bdrv_rw_co(bs, sector_num, buf, nb_sectors, false);
 }
 
 static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num,
@@ -1105,36 +1148,7 @@ static void set_dirty_bitmap(BlockDriverState *bs, 
int64_t sector_num,
 int bdrv_write(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors)
 {
-BlockDriver *drv = bs-drv;
-
-if (!bs-drv)
-return -ENOMEDIUM;
-
-if (bdrv_has_async_rw(drv)  qemu_in_coroutine()) {
-QEMUIOVector qiov;
-struct iovec iov = {
-.iov_base = (void *)buf,
-.iov_len = nb_sectors * BDRV_SECTOR_SIZE,
-};
-
-qemu_iovec_init_external(qiov, iov, 1);
-return bdrv_co_writev(bs, sector_num, nb_sectors, qiov);
-}
-
-if (bs-read_only)
-return -EACCES;
-if (bdrv_check_request(bs, sector_num, nb_sectors))
-return -EIO;
-
-if (bs-dirty_bitmap) {
-set_dirty_bitmap(bs, sector_num, 

[Qemu-devel] [PATCH 6/9] hw/usb-ohci: Fix OHCI_TD_T1 bit position definition

2011-10-13 Thread Gerd Hoffmann
From: Peter Maydell peter.mayd...@linaro.org

The OHCI Transfer Descriptor T (DataToggle) bits are 24 and 25;
fix an error which accidentally overlaid them both on the same bit.

Signed-off-by: Peter Maydell peter.mayd...@linaro.org
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/usb-ohci.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index 5e10e21..e14ced8 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -150,7 +150,7 @@ static void ohci_async_cancel_device(OHCIState *ohci, 
USBDevice *dev);
 #define OHCI_TD_DI_SHIFT  21
 #define OHCI_TD_DI_MASK   (7OHCI_TD_DI_SHIFT)
 #define OHCI_TD_T0(124)
-#define OHCI_TD_T1(124)
+#define OHCI_TD_T1(125)
 #define OHCI_TD_EC_SHIFT  26
 #define OHCI_TD_EC_MASK   (3OHCI_TD_EC_SHIFT)
 #define OHCI_TD_CC_SHIFT  28
-- 
1.7.1




[Qemu-devel] [PATCH 31/35] scsi: move max_lba to SCSIDevice

2011-10-13 Thread Paolo Bonzini
The field was only in scsi-disk until now.  Moving it up to SCSIDevice
will make it easier to reuse the scsi-generic reqops elsewhere.  In
the future, range checking of LBA arguments might also be pushed up
to SCSIDevice.

At the same time, make scsi-generic get max_lba from the guest's READ
CAPACITY commands, as well.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-disk.c|   15 +++
 hw/scsi-generic.c |2 ++
 hw/scsi.h |1 +
 3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index cc3998e..26aa46a 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -66,7 +66,6 @@ struct SCSIDiskState
 {
 SCSIDevice qdev;
 uint32_t removable;
-uint64_t max_lba;
 bool media_changed;
 bool media_event;
 QEMUBH *bh;
@@ -1172,7 +1171,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
 /* Returned value is the address of the last sector.  */
 nb_sectors--;
 /* Remember the new size for read/write sanity checking. */
-s-max_lba = nb_sectors;
+s-qdev.max_lba = nb_sectors;
 /* Clip to 2TB, instead of returning capacity modulo 2TB. */
 if (nb_sectors  UINT32_MAX)
 nb_sectors = UINT32_MAX;
@@ -1222,7 +1221,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
 /* Returned value is the address of the last sector.  */
 nb_sectors--;
 /* Remember the new size for read/write sanity checking. */
-s-max_lba = nb_sectors;
+s-qdev.max_lba = nb_sectors;
 outbuf[0] = (nb_sectors  56)  0xff;
 outbuf[1] = (nb_sectors  48)  0xff;
 outbuf[2] = (nb_sectors  40)  0xff;
@@ -1339,7 +1338,7 @@ static int32_t scsi_send_command(SCSIRequest *req, 
uint8_t *buf)
 case READ_16:
 len = r-req.cmd.xfer / s-qdev.blocksize;
 DPRINTF(Read (sector % PRId64 , count %d)\n, r-req.cmd.lba, len);
-if (r-req.cmd.lba  s-max_lba)
+if (r-req.cmd.lba  s-qdev.max_lba)
 goto illegal_lba;
 r-sector = r-req.cmd.lba * (s-qdev.blocksize / 512);
 r-sector_count = len * (s-qdev.blocksize / 512);
@@ -1355,7 +1354,7 @@ static int32_t scsi_send_command(SCSIRequest *req, 
uint8_t *buf)
 DPRINTF(Write %s(sector % PRId64 , count %d)\n,
 (command  0xe) == 0xe ? And Verify  : ,
 r-req.cmd.lba, len);
-if (r-req.cmd.lba  s-max_lba)
+if (r-req.cmd.lba  s-qdev.max_lba)
 goto illegal_lba;
 r-sector = r-req.cmd.lba * (s-qdev.blocksize / 512);
 r-sector_count = len * (s-qdev.blocksize / 512);
@@ -1380,7 +1379,7 @@ static int32_t scsi_send_command(SCSIRequest *req, 
uint8_t *buf)
 case SEEK_10:
 DPRINTF(Seek(%d) (sector % PRId64 )\n, command == SEEK_6 ? 6 : 10,
 r-req.cmd.lba);
-if (r-req.cmd.lba  s-max_lba) {
+if (r-req.cmd.lba  s-qdev.max_lba) {
 goto illegal_lba;
 }
 break;
@@ -1390,7 +1389,7 @@ static int32_t scsi_send_command(SCSIRequest *req, 
uint8_t *buf)
 DPRINTF(WRITE SAME(16) (sector % PRId64 , count %d)\n,
 r-req.cmd.lba, len);
 
-if (r-req.cmd.lba  s-max_lba) {
+if (r-req.cmd.lba  s-qdev.max_lba) {
 goto illegal_lba;
 }
 
@@ -1449,7 +1448,7 @@ static void scsi_disk_reset(DeviceState *dev)
 if (nb_sectors) {
 nb_sectors--;
 }
-s-max_lba = nb_sectors;
+s-qdev.max_lba = nb_sectors;
 }
 }
 
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index cb02a7e..06089ab 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -174,9 +174,11 @@ static void scsi_read_complete(void * opaque, int ret)
 /* Snoop READ CAPACITY output to set the blocksize.  */
 if (r-req.cmd.buf[0] == READ_CAPACITY_10) {
 s-blocksize = ldl_be_p(r-buf[4]);
+s-max_lba = ldl_be_p(r-buf[0]);
 } else if (r-req.cmd.buf[0] == SERVICE_ACTION_IN_16 
(r-req.cmd.buf[1]  31) == SAI_READ_CAPACITY_16) {
 s-blocksize = ldl_be_p(r-buf[8]);
+s-max_lba = ldq_be_p(r-buf[0]);
 }
 bdrv_set_buffer_alignment(s-conf.bs, s-blocksize);
 
diff --git a/hw/scsi.h b/hw/scsi.h
index c8649cf..d56e875 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -70,6 +70,7 @@ struct SCSIDevice
 uint32_t lun;
 int blocksize;
 int type;
+uint64_t max_lba;
 };
 
 /* cdrom.c */
-- 
1.7.6





[Qemu-devel] [PATCH 04/35] atapi: fill in AUDIO_CTL page correctly

2011-10-13 Thread Paolo Bonzini
The page is not anymore in MMC, but at least keep the values sane.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/ide/atapi.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index 347c38d..10f161f 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -731,6 +731,8 @@ static void cmd_mode_sense(IDEState *s, uint8_t *buf)
 buf[7] = 0;
 
 /* Fill with CDROM audio volume */
+buf[8] = 0x0e;
+buf[9] = 0x0e;
 buf[17] = 0;
 buf[19] = 0;
 buf[21] = 0;
-- 
1.7.6





[Qemu-devel] [PATCH 23/35] scsi-generic: drop SCSIGenericState

2011-10-13 Thread Paolo Bonzini
It is not needed, because s-bs is already stored in SCSIDevice, and
can be reached from the conf.bs member.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-generic.c |   85 +++--
 1 files changed, 37 insertions(+), 48 deletions(-)

diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 8f6b70d..cea4fca 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -46,8 +46,6 @@ do { fprintf(stderr, scsi-generic:  fmt , ## __VA_ARGS__); 
} while (0)
 #define MAX_UINT ((unsigned int)-1)
 #endif
 
-typedef struct SCSIGenericState SCSIGenericState;
-
 typedef struct SCSIGenericReq {
 SCSIRequest req;
 uint8_t *buf;
@@ -56,12 +54,6 @@ typedef struct SCSIGenericReq {
 sg_io_hdr_t io_header;
 } SCSIGenericReq;
 
-struct SCSIGenericState
-{
-SCSIDevice qdev;
-BlockDriverState *bs;
-};
-
 static void scsi_free_request(SCSIRequest *req)
 {
 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
@@ -174,7 +166,7 @@ static void scsi_read_complete(void * opaque, int ret)
 static void scsi_read_data(SCSIRequest *req)
 {
 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
-SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r-req.dev);
+SCSIDevice *s = r-req.dev;
 int ret;
 
 DPRINTF(scsi_read_data 0x%x\n, req-tag);
@@ -183,7 +175,7 @@ static void scsi_read_data(SCSIRequest *req)
 return;
 }
 
-ret = execute_command(s-bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
+ret = execute_command(s-conf.bs, r, SG_DXFER_FROM_DEV, 
scsi_read_complete);
 if (ret  0) {
 scsi_command_complete(r, ret);
 return;
@@ -193,7 +185,7 @@ static void scsi_read_data(SCSIRequest *req)
 static void scsi_write_complete(void * opaque, int ret)
 {
 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
-SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r-req.dev);
+SCSIDevice *s = r-req.dev;
 
 DPRINTF(scsi_write_complete() ret = %d\n, ret);
 r-req.aiocb = NULL;
@@ -204,9 +196,9 @@ static void scsi_write_complete(void * opaque, int ret)
 }
 
 if (r-req.cmd.buf[0] == MODE_SELECT  r-req.cmd.buf[4] == 12 
-s-qdev.type == TYPE_TAPE) {
-s-qdev.blocksize = (r-buf[9]  16) | (r-buf[10]  8) | r-buf[11];
-DPRINTF(block size %d\n, s-qdev.blocksize);
+s-type == TYPE_TAPE) {
+s-blocksize = (r-buf[9]  16) | (r-buf[10]  8) | r-buf[11];
+DPRINTF(block size %d\n, s-blocksize);
 }
 
 scsi_command_complete(r, ret);
@@ -216,8 +208,8 @@ static void scsi_write_complete(void * opaque, int ret)
The transfer may complete asynchronously.  */
 static void scsi_write_data(SCSIRequest *req)
 {
-SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req-dev);
 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
+SCSIDevice *s = r-req.dev;
 int ret;
 
 DPRINTF(scsi_write_data 0x%x\n, req-tag);
@@ -227,7 +219,7 @@ static void scsi_write_data(SCSIRequest *req)
 return;
 }
 
-ret = execute_command(s-bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
+ret = execute_command(s-conf.bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
 if (ret  0) {
 scsi_command_complete(r, ret);
 }
@@ -261,8 +253,8 @@ static void scsi_req_fixup(SCSIRequest *req)
 
 static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
 {
-SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req-dev);
 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
+SCSIDevice *s = r-req.dev;
 int ret;
 
 scsi_req_fixup(r-req);
@@ -285,7 +277,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t 
*cmd)
 g_free(r-buf);
 r-buflen = 0;
 r-buf = NULL;
-ret = execute_command(s-bs, r, SG_DXFER_NONE, scsi_command_complete);
+ret = execute_command(s-conf.bs, r, SG_DXFER_NONE, 
scsi_command_complete);
 if (ret  0) {
 scsi_command_complete(r, ret);
 return 0;
@@ -373,77 +365,74 @@ static int get_stream_blocksize(BlockDriverState *bdrv)
 
 static void scsi_generic_reset(DeviceState *dev)
 {
-SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev.qdev, dev);
+SCSIDevice *s = DO_UPCAST(SCSIDevice, qdev, dev);
 
-scsi_device_purge_requests(s-qdev, SENSE_CODE(RESET));
+scsi_device_purge_requests(s, SENSE_CODE(RESET));
 }
 
-static void scsi_destroy(SCSIDevice *d)
+static void scsi_destroy(SCSIDevice *s)
 {
-SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
-
-scsi_device_purge_requests(s-qdev, SENSE_CODE(NO_SENSE));
-blockdev_mark_auto_del(s-qdev.conf.bs);
+scsi_device_purge_requests(s, SENSE_CODE(NO_SENSE));
+blockdev_mark_auto_del(s-conf.bs);
 }
 
-static int scsi_generic_initfn(SCSIDevice *dev)
+static int scsi_generic_initfn(SCSIDevice *s)
 {
-SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
 int sg_version;
 struct sg_scsi_id scsiid;
 
-if (!s-qdev.conf.bs) 

[Qemu-devel] [PATCH 7/9] hw/usb-ohci: Honour endpoint maximum packet size

2011-10-13 Thread Gerd Hoffmann
From: Peter Maydell peter.mayd...@linaro.org

Honour the maximum packet size for endpoints; this applies when
sending non-isochronous data and means we transfer only as
much as the endpoint allows, leaving the transfer descriptor
on the list for another go next time around. This allows
usb-net to work when connected to an OHCI controller model.

Signed-off-by: Peter Maydell peter.mayd...@linaro.org
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/usb-ohci.c |   37 +++--
 1 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index e14ced8..c2981c5 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -872,7 +872,7 @@ static int ohci_service_iso_td(OHCIState *ohci, struct 
ohci_ed *ed,
 static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
 {
 int dir;
-size_t len = 0;
+size_t len = 0, pktlen = 0;
 #ifdef DEBUG_PACKET
 const char *str = NULL;
 #endif
@@ -940,20 +940,30 @@ static int ohci_service_td(OHCIState *ohci, struct 
ohci_ed *ed)
 len = (td.be - td.cbp) + 1;
 }
 
-if (len  dir != OHCI_TD_DIR_IN  !completion) {
-ohci_copy_td(ohci, td, ohci-usb_buf, len, 0);
+pktlen = len;
+if (len  dir != OHCI_TD_DIR_IN) {
+/* The endpoint may not allow us to transfer it all now */
+pktlen = (ed-flags  OHCI_ED_MPS_MASK)  OHCI_ED_MPS_SHIFT;
+if (pktlen  len) {
+pktlen = len;
+}
+if (!completion) {
+ohci_copy_td(ohci, td, ohci-usb_buf, pktlen, 0);
+}
 }
 }
 
 flag_r = (td.flags  OHCI_TD_R) != 0;
 #ifdef DEBUG_PACKET
-DPRINTF( TD @ 0x%.8x % PRId64  bytes %s r=%d cbp=0x%.8x be=0x%.8x\n,
-addr, (int64_t)len, str, flag_r, td.cbp, td.be);
+DPRINTF( TD @ 0x%.8x % PRId64  of % PRId64
+ bytes %s r=%d cbp=0x%.8x be=0x%.8x\n,
+addr, (int64_t)pktlen, (int64_t)len, str, flag_r, td.cbp, td.be);
 
-if (len  0  dir != OHCI_TD_DIR_IN) {
+if (pktlen  0  dir != OHCI_TD_DIR_IN) {
 DPRINTF(  data:);
-for (i = 0; i  len; i++)
+for (i = 0; i  pktlen; i++) {
 printf( %.2x, ohci-usb_buf[i]);
+}
 DPRINTF(\n);
 }
 #endif
@@ -982,7 +992,7 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed 
*ed)
 usb_packet_setup(ohci-usb_packet, pid,
  OHCI_BM(ed-flags, ED_FA),
  OHCI_BM(ed-flags, ED_EN));
-usb_packet_addbuf(ohci-usb_packet, ohci-usb_buf, len);
+usb_packet_addbuf(ohci-usb_packet, ohci-usb_buf, pktlen);
 ret = usb_handle_packet(dev, ohci-usb_packet);
 if (ret != USB_RET_NODEV)
 break;
@@ -1005,12 +1015,12 @@ static int ohci_service_td(OHCIState *ohci, struct 
ohci_ed *ed)
 DPRINTF(\n);
 #endif
 } else {
-ret = len;
+ret = pktlen;
 }
 }
 
 /* Writeback */
-if (ret == len || (dir == OHCI_TD_DIR_IN  ret = 0  flag_r)) {
+if (ret == pktlen || (dir == OHCI_TD_DIR_IN  ret = 0  flag_r)) {
 /* Transmission succeeded.  */
 if (ret == len) {
 td.cbp = 0;
@@ -1026,6 +1036,12 @@ static int ohci_service_td(OHCIState *ohci, struct 
ohci_ed *ed)
 OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_NOERROR);
 OHCI_SET_BM(td.flags, TD_EC, 0);
 
+if ((dir != OHCI_TD_DIR_IN)  (ret != len)) {
+/* Partial packet transfer: TD not ready to retire yet */
+goto exit_no_retire;
+}
+
+/* Setting ED_C is part of the TD retirement process */
 ed-head = ~OHCI_ED_C;
 if (td.flags  OHCI_TD_T0)
 ed-head |= OHCI_ED_C;
@@ -1066,6 +1082,7 @@ static int ohci_service_td(OHCIState *ohci, struct 
ohci_ed *ed)
 i = OHCI_BM(td.flags, TD_DI);
 if (i  ohci-done_count)
 ohci-done_count = i;
+exit_no_retire:
 ohci_put_td(ohci, addr, td);
 return OHCI_BM(td.flags, TD_CC) != OHCI_CC_NOERROR;
 }
-- 
1.7.1




[Qemu-devel] [PATCH 03/35] atapi: move GESN definitions to scsi-defs.h

2011-10-13 Thread Paolo Bonzini
As a complement to the previous patch, move definitions for GET EVENT
STATUS NOTIFICATION from the two functions to scsi-defs.h.

The NCR_* constants are just bit values corresponding to the ENC_*
values, with no offsets even, so keep just one copy.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/ide/atapi.c |   43 ++-
 hw/scsi-defs.h |   21 +
 2 files changed, 27 insertions(+), 37 deletions(-)

diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index be3b728..347c38d 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -505,19 +505,6 @@ static int ide_dvd_read_structure(IDEState *s, int format,
 static unsigned int event_status_media(IDEState *s,
uint8_t *buf)
 {
-enum media_event_code {
-MEC_NO_CHANGE = 0,   /* Status unchanged */
-MEC_EJECT_REQUESTED, /* received a request from user to eject */
-MEC_NEW_MEDIA,   /* new media inserted and ready for access */
-MEC_MEDIA_REMOVAL,   /* only for media changers */
-MEC_MEDIA_CHANGED,   /* only for media changers */
-MEC_BG_FORMAT_COMPLETED, /* MRW or DVD+RW b/g format completed */
-MEC_BG_FORMAT_RESTARTED, /* MRW or DVD+RW b/g format restarted */
-};
-enum media_status {
-MS_TRAY_OPEN = 1,
-MS_MEDIA_PRESENT = 2,
-};
 uint8_t event_code, media_status;
 
 media_status = 0;
@@ -564,27 +551,6 @@ static void cmd_get_event_status_notification(IDEState *s,
 uint8_t notification_class;
 uint8_t supported_events;
 } QEMU_PACKED *gesn_event_header;
-
-enum notification_class_request_type {
-NCR_RESERVED1 = 1  0,
-NCR_OPERATIONAL_CHANGE = 1  1,
-NCR_POWER_MANAGEMENT = 1  2,
-NCR_EXTERNAL_REQUEST = 1  3,
-NCR_MEDIA = 1  4,
-NCR_MULTI_HOST = 1  5,
-NCR_DEVICE_BUSY = 1  6,
-NCR_RESERVED2 = 1  7,
-};
-enum event_notification_class_field {
-ENC_NO_EVENTS = 0,
-ENC_OPERATIONAL_CHANGE,
-ENC_POWER_MANAGEMENT,
-ENC_EXTERNAL_REQUEST,
-ENC_MEDIA,
-ENC_MULTIPLE_HOSTS,
-ENC_DEVICE_BUSY,
-ENC_RESERVED,
-};
 unsigned int max_len, used_len;
 
 gesn_cdb = (void *)packet;
@@ -606,8 +572,11 @@ static void cmd_get_event_status_notification(IDEState *s,
  * These are the supported events.
  *
  * We currently only support requests of the 'media' type.
+ * Notification class requests and supported event classes are bitmasks,
+ * but they are build from the same values as the notification class
+ * field.
  */
-gesn_event_header-supported_events = NCR_MEDIA;
+gesn_event_header-supported_events = 1  GESN_MEDIA;
 
 /*
  * We use |= below to set the class field; other bits in this byte
@@ -621,8 +590,8 @@ static void cmd_get_event_status_notification(IDEState *s,
  * notification_class_request_type enum above specifies the
  * priority: upper elements are higher prio than lower ones.
  */
-if (gesn_cdb-class  NCR_MEDIA) {
-gesn_event_header-notification_class |= ENC_MEDIA;
+if (gesn_cdb-class  (1  GESN_MEDIA)) {
+gesn_event_header-notification_class |= GESN_MEDIA;
 used_len = event_status_media(s, buf);
 } else {
 gesn_event_header-notification_class = 0x80; /* No event available */
diff --git a/hw/scsi-defs.h b/hw/scsi-defs.h
index dfa3095..8094698 100644
--- a/hw/scsi-defs.h
+++ b/hw/scsi-defs.h
@@ -203,6 +203,27 @@
  * of MODE_PAGE_SENSE_POWER */
 #define MODE_PAGE_CDROM0x0d
 
+/* Event notification classes for GET EVENT STATUS NOTIFICATION */
+#define GESN_NO_EVENTS 0
+#define GESN_OPERATIONAL_CHANGE1
+#define GESN_POWER_MANAGEMENT  2
+#define GESN_EXTERNAL_REQUEST  3
+#define GESN_MEDIA 4
+#define GESN_MULTIPLE_HOSTS5
+#define GESN_DEVICE_BUSY   6
+
+/* Event codes for MEDIA event status notification */
+#define MEC_NO_CHANGE  0
+#define MEC_EJECT_REQUESTED1
+#define MEC_NEW_MEDIA  2
+#define MEC_MEDIA_REMOVAL  3 /* only for media changers */
+#define MEC_MEDIA_CHANGED  4 /* only for media changers */
+#define MEC_BG_FORMAT_COMPLETED5 /* MRW or DVD+RW b/g format completed 
*/
+#define MEC_BG_FORMAT_RESTARTED6 /* MRW or DVD+RW b/g format restarted 
*/
+
+#define MS_TRAY_OPEN   1
+#define MS_MEDIA_PRESENT   2
+
 /*
  * Based on values from linux/cdrom.h but extending CD_MINS
  * to the maximum common size allowed by the Orange's Book ATIP
-- 
1.7.6





[Qemu-devel] [PATCH 29/35] scsi-disk: remove cluster_size

2011-10-13 Thread Paolo Bonzini
This field is redundant, and its presence makes it more complicated
to share reqops between the upcoming scsi-block and scsi-generic.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-disk.c |   45 ++---
 1 files changed, 22 insertions(+), 23 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 5e3ef51..7f2f67f 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -65,9 +65,6 @@ typedef struct SCSIDiskReq {
 struct SCSIDiskState
 {
 SCSIDevice qdev;
-/* The qemu block layer uses a fixed 512 byte sector size.
-   This is the number of 512 byte blocks in a single scsi sector.  */
-int cluster_size;
 uint32_t removable;
 uint64_t max_lba;
 bool media_changed;
@@ -862,7 +859,7 @@ static int mode_sense_page(SCSIDiskState *s, int page, 
uint8_t **p_outbuf,
 bdrv_get_geometry_hint(bdrv, cylinders, heads, secs);
 p[4] = heads  0xff;
 p[5] = secs  0xff;
-p[6] = s-cluster_size * 2;
+p[6] = s-qdev.blocksize  8;
 p[8] = (cylinders  8)  0xff;
 p[9] = cylinders  0xff;
 /* Write precomp start cylinder, disabled */
@@ -991,7 +988,7 @@ static int scsi_disk_emulate_mode_sense(SCSIDiskReq *r, 
uint8_t *outbuf)
 } else { /* MODE_SENSE_10 */
 outbuf[7] = 8; /* Block descriptor length  */
 }
-nb_sectors /= s-cluster_size;
+nb_sectors /= (s-qdev.blocksize / 512);
 if (nb_sectors  0xff)
 nb_sectors = 0;
 p[0] = 0; /* media density code */
@@ -1000,7 +997,7 @@ static int scsi_disk_emulate_mode_sense(SCSIDiskReq *r, 
uint8_t *outbuf)
 p[3] = nb_sectors  0xff;
 p[4] = 0; /* reserved */
 p[5] = 0; /* bytes 5-7 are the sector size in bytes */
-p[6] = s-cluster_size * 2;
+p[6] = s-qdev.blocksize  8;
 p[7] = 0;
 p += 8;
 }
@@ -1050,7 +1047,7 @@ static int scsi_disk_emulate_read_toc(SCSIRequest *req, 
uint8_t *outbuf)
 start_track = req-cmd.buf[6];
 bdrv_get_geometry(s-qdev.conf.bs, nb_sectors);
 DPRINTF(Read TOC (track %d format %d msf %d)\n, start_track, format, msf 
 1);
-nb_sectors /= s-cluster_size;
+nb_sectors /= s-qdev.blocksize / 512;
 switch (format) {
 case 0:
 toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);
@@ -1176,7 +1173,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
 if ((req-cmd.buf[8]  1) == 0  req-cmd.lba) {
 goto illegal_request;
 }
-nb_sectors /= s-cluster_size;
+nb_sectors /= s-qdev.blocksize / 512;
 /* Returned value is the address of the last sector.  */
 nb_sectors--;
 /* Remember the new size for read/write sanity checking. */
@@ -1190,7 +1187,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
 outbuf[3] = nb_sectors  0xff;
 outbuf[4] = 0;
 outbuf[5] = 0;
-outbuf[6] = s-cluster_size * 2;
+outbuf[6] = s-qdev.blocksize  8;
 outbuf[7] = 0;
 buflen = 8;
 break;
@@ -1226,7 +1223,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
 if ((req-cmd.buf[14]  1) == 0  req-cmd.lba) {
 goto illegal_request;
 }
-nb_sectors /= s-cluster_size;
+nb_sectors /= s-qdev.blocksize / 512;
 /* Returned value is the address of the last sector.  */
 nb_sectors--;
 /* Remember the new size for read/write sanity checking. */
@@ -1241,7 +1238,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
 outbuf[7] = nb_sectors  0xff;
 outbuf[8] = 0;
 outbuf[9] = 0;
-outbuf[10] = s-cluster_size * 2;
+outbuf[10] = s-qdev.blocksize  8;
 outbuf[11] = 0;
 outbuf[12] = 0;
 outbuf[13] = get_physical_block_exp(s-qdev.conf);
@@ -1349,8 +1346,8 @@ static int32_t scsi_send_command(SCSIRequest *req, 
uint8_t *buf)
 DPRINTF(Read (sector % PRId64 , count %d)\n, r-req.cmd.lba, len);
 if (r-req.cmd.lba  s-max_lba)
 goto illegal_lba;
-r-sector = r-req.cmd.lba * s-cluster_size;
-r-sector_count = len * s-cluster_size;
+r-sector = r-req.cmd.lba * (s-qdev.blocksize / 512);
+r-sector_count = len * (s-qdev.blocksize / 512);
 break;
 case WRITE_6:
 case WRITE_10:
@@ -1365,8 +1362,8 @@ static int32_t scsi_send_command(SCSIRequest *req, 
uint8_t *buf)
 r-req.cmd.lba, len);
 if (r-req.cmd.lba  s-max_lba)
 goto illegal_lba;
-r-sector = r-req.cmd.lba * s-cluster_size;
-r-sector_count = len * s-cluster_size;
+r-sector = r-req.cmd.lba * (s-qdev.blocksize / 512);
+r-sector_count = len * (s-qdev.blocksize / 512);
 break;
 case MODE_SELECT:
 DPRINTF(Mode Select(6) (len %lu)\n, (long)r-req.cmd.xfer);
@@ -1409,8 +1406,9 @@ static int32_t 

[Qemu-devel] [PATCH 16/35] scsi: implement REPORT LUNS for arbitrary LUNs

2011-10-13 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-bus.c |   49 +++--
 1 files changed, 39 insertions(+), 10 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 7104e98..a2d57a7 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -170,7 +170,7 @@ typedef struct SCSITargetReq SCSITargetReq;
 struct SCSITargetReq {
 SCSIRequest req;
 int len;
-uint8_t buf[64];
+uint8_t buf[2056];
 };
 
 static void store_lun(uint8_t *outbuf, int lun)
@@ -185,23 +185,52 @@ static void store_lun(uint8_t *outbuf, int lun)
 
 static bool scsi_target_emulate_report_luns(SCSITargetReq *r)
 {
-int len;
+DeviceState *qdev;
+int i, len, n;
+int id;
+bool found_lun0;
+
 if (r-req.cmd.xfer  16) {
 return false;
 }
 if (r-req.cmd.buf[2]  2) {
 return false;
 }
-len = MIN(sizeof r-buf, r-req.cmd.xfer);
+id = r-req.dev-id;
+found_lun0 = false;
+n = 0;
+QTAILQ_FOREACH(qdev, r-req.bus-qbus.children, sibling) {
+SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
+
+if (dev-id == id) {
+if (dev-lun == 0) {
+found_lun0 = true;
+}
+n += 8;
+}
+}
+if (!found_lun0) {
+n += 8;
+}
+len = MIN(n + 8, r-req.cmd.xfer  ~7);
+if (len  sizeof(r-buf)) {
+/* TODO:  256 LUNs? */
+return false;
+}
+
 memset(r-buf, 0, len);
-if (r-req.dev-lun != 0) {
-r-buf[3] = 16;
-r-len = 24;
-store_lun(r-buf[16], r-req.dev-lun);
-} else {
-r-buf[3] = 8;
-r-len = 16;
+stl_be_p(r-buf, n);
+i = found_lun0 ? 8 : 16;
+QTAILQ_FOREACH(qdev, r-req.bus-qbus.children, sibling) {
+SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
+
+if (dev-id == id) {
+store_lun(r-buf[i], dev-lun);
+i += 8;
+}
 }
+assert(i == n + 8);
+r-len = len;
 return true;
 }
 
-- 
1.7.6





[Qemu-devel] [PATCH 02/11] audio: don't apply volume effect if backend has VOICE_VOLUME_CAP

2011-10-13 Thread Marc-André Lureau
---
 audio/audio.c  |9 +++--
 audio/audio_int.h  |5 +
 audio/audio_template.h |2 ++
 3 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index c759c1f..f830bb2 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -954,7 +954,9 @@ int audio_pcm_sw_read (SWVoiceIn *sw, void *buf, int size)
 total += isamp;
 }
 
-mixeng_volume (sw-buf, ret, sw-vol);
+if (!(hw-ctl_caps  VOICE_VOLUME_CAP)) {
+mixeng_volume (sw-buf, ret, sw-vol);
+}
 
 sw-clip (buf, sw-buf, ret);
 sw-total_hw_samples_acquired += total;
@@ -1038,7 +1040,10 @@ int audio_pcm_sw_write (SWVoiceOut *sw, void *buf, int 
size)
 swlim = audio_MIN (swlim, samples);
 if (swlim) {
 sw-conv (sw-buf, buf, swlim);
-mixeng_volume (sw-buf, swlim, sw-vol);
+
+if (!(sw-hw-ctl_caps  VOICE_VOLUME_CAP)) {
+mixeng_volume (sw-buf, swlim, sw-vol);
+}
 }
 
 while (swlim) {
diff --git a/audio/audio_int.h b/audio/audio_int.h
index 117f95e..b9b0676 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -82,6 +82,7 @@ typedef struct HWVoiceOut {
 int samples;
 QLIST_HEAD (sw_out_listhead, SWVoiceOut) sw_head;
 QLIST_HEAD (sw_cap_listhead, SWVoiceCap) cap_head;
+int ctl_caps;
 struct audio_pcm_ops *pcm_ops;
 QLIST_ENTRY (HWVoiceOut) entries;
 } HWVoiceOut;
@@ -101,6 +102,7 @@ typedef struct HWVoiceIn {
 
 int samples;
 QLIST_HEAD (sw_in_listhead, SWVoiceIn) sw_head;
+int ctl_caps;
 struct audio_pcm_ops *pcm_ops;
 QLIST_ENTRY (HWVoiceIn) entries;
 } HWVoiceIn;
@@ -150,6 +152,7 @@ struct audio_driver {
 int max_voices_in;
 int voice_size_out;
 int voice_size_in;
+int ctl_caps;
 };
 
 struct audio_pcm_ops {
@@ -233,6 +236,8 @@ void audio_run (const char *msg);
 #define VOICE_DISABLE 2
 #define VOICE_VOLUME 3
 
+#define VOICE_VOLUME_CAP (1  VOICE_VOLUME)
+
 static inline int audio_ring_dist (int dst, int src, int len)
 {
 return (dst = src) ? (dst - src) : (len - src + dst);
diff --git a/audio/audio_template.h b/audio/audio_template.h
index e62a713..519432a 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -263,6 +263,8 @@ static HW *glue (audio_pcm_hw_add_new_, TYPE) (struct 
audsettings *as)
 }
 
 hw-pcm_ops = drv-pcm_ops;
+hw-ctl_caps = drv-ctl_caps;
+
 QLIST_INIT (hw-sw_head);
 #ifdef DAC
 QLIST_INIT (hw-cap_head);
-- 
1.7.6.2




[Qemu-devel] [PULL 00/35] SCSI uber-patch

2011-10-13 Thread Paolo Bonzini
Kevin,

the following changes since commit 77d5aa8ade3aac7ee3cec0ab05fb538055e01a48:

  block: split out bdrv_co_do_readv() and bdrv_co_do_writev() (2011-10-12 
14:42:11 +0200)

are available in the git repository at:
  git://github.com/bonzini/qemu.git scsi-for-kevin

Patches 1-12 have been sent before as part of the scsi-disk: Add DVD-ROM
support and media change + atapi: nitpicking series (Sep 20 2011).  I
tested them with various versions of client operating systems, mostly
RHEL6 and Fedora 16.

Patches 13-18 have been sent before as part of the introduce SCSI
channel/target/LUN addressing series (Sep 30 2011).  I tested them
mostly with the pSeries machine.

Patches 19-22 have been sent before as part of the scsi: miscellaneous
fixes series (Oct 7 2011), and are rebased here.

Patches 23-35 have been sent yesterday as part of the scsi: add
specialized block device passthrough, but are slightly different here
to support passthrough of 4k-sector disks, and to improve the behavior
of CD-ROM passthrough (both scsi-block and scsi-generic) when no disk
is present in the physical drive.

Paolo Bonzini (35):
  scsi: pass correct sense code for ENOMEDIUM
  atapi/scsi: unify definitions for MMC
  atapi: move GESN definitions to scsi-defs.h
  atapi: fill in AUDIO_CTL page correctly
  scsi: notify the device when unit attention is reported
  scsi-disk: report media changed via unit attention sense codes
  scsi-disk: add stubs for more MMC commands
  scsi-disk: store valid mode pages in a table
  atapi/scsi-disk: make mode page values coherent between the two
  scsi-disk: support DVD profile in GET CONFIGURATION
  scsi-disk: support READ DVD STRUCTURE
  scsi-disk: report media changed via GET EVENT STATUS NOTIFICATION
  scsi: move tcq/ndev to SCSIBusOps (now SCSIBusInfo)
  qdev: switch children device list to QTAILQ
  scsi: remove devs array from SCSIBus
  scsi: implement REPORT LUNS for arbitrary LUNs
  scsi: allow arbitrary LUNs
  scsi: add channel to addressing
  scsi-disk: fail READ CAPACITY if LBA != 0 but PMI == 0
  scsi-disk: do not complete requests twice
  scsi-disk: bump SCSIRequest reference count until aio completion runs
  scsi-disk: fix retrying a flush
  scsi-generic: drop SCSIGenericState
  scsi-generic: remove scsi_req_fixup
  scsi-generic: check ioctl statuses when SG_IO succeeds
  scsi-generic: look at host status
  scsi-generic: snoop READ CAPACITY commands to get block size
  scsi-disk: do not duplicate BlockDriverState member
  scsi-disk: remove cluster_size
  scsi-disk: small clean up to INQUIRY
  scsi: move max_lba to SCSIDevice
  scsi: make reqops const
  scsi: export scsi_generic_reqops
  scsi: pass cdb to alloc_req
  scsi-disk: add scsi-block for device passthrough

 hw/acpi_piix4.c  |4 +-
 hw/esp.c |   13 +-
 hw/i2c.c |2 +-
 hw/ide/atapi.c   |  109 +++-
 hw/ide/core.c|4 +-
 hw/ide/internal.h|   71 +--
 hw/ide/macio.c   |2 +-
 hw/intel-hda.c   |6 +-
 hw/lsi53c895a.c  |   30 +--
 hw/qdev.c|   24 +-
 hw/qdev.h|4 +-
 hw/s390-virtio-bus.c |4 +-
 hw/scsi-bus.c|  204 +++-
 hw/scsi-defs.h   |   90 +++
 hw/scsi-disk.c   |  674 --
 hw/scsi-generic.c|  168 +
 hw/scsi.h|   33 ++-
 hw/spapr_vio.c   |6 +-
 hw/spapr_vscsi.c |   54 +++-
 hw/ssi.c |6 +-
 hw/usb-msd.c |8 +-
 21 files changed, 997 insertions(+), 519 deletions(-)
-- 
1.7.6




[Qemu-devel] [PATCH 04/11] hw/ac97: remove USE_MIXER code

2011-10-13 Thread Marc-André Lureau
It doesn't compile. The interesting bits for volume control are going
to be rewritten.
---
 hw/ac97.c |  121 -
 1 files changed, 0 insertions(+), 121 deletions(-)

diff --git a/hw/ac97.c b/hw/ac97.c
index 541d9a4..4d4a658 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -432,99 +432,6 @@ static void reset_voices (AC97LinkState *s, uint8_t 
active[LAST_INDEX])
 AUD_set_active_in (s-voice_mc, active[MC_INDEX]);
 }
 
-#ifdef USE_MIXER
-static void set_volume (AC97LinkState *s, int index,
-audmixerctl_t mt, uint32_t val)
-{
-int mute = (val  MUTE_SHIFT)  1;
-uint8_t rvol = VOL_MASK - (val  VOL_MASK);
-uint8_t lvol = VOL_MASK - ((val  8)  VOL_MASK);
-rvol = 255 * rvol / VOL_MASK;
-lvol = 255 * lvol / VOL_MASK;
-
-#ifdef SOFT_VOLUME
-if (index == AC97_Master_Volume_Mute) {
-AUD_set_volume_out (s-voice_po, mute, lvol, rvol);
-}
-else {
-AUD_set_volume (mt, mute, lvol, rvol);
-}
-#else
-AUD_set_volume (mt, mute, lvol, rvol);
-#endif
-
-rvol = VOL_MASK - ((VOL_MASK * rvol) / 255);
-lvol = VOL_MASK - ((VOL_MASK * lvol) / 255);
-mixer_store (s, index, val);
-}
-
-static audrecsource_t ac97_to_aud_record_source (uint8_t i)
-{
-switch (i) {
-case REC_MIC:
-return AUD_REC_MIC;
-
-case REC_CD:
-return AUD_REC_CD;
-
-case REC_VIDEO:
-return AUD_REC_VIDEO;
-
-case REC_AUX:
-return AUD_REC_AUX;
-
-case REC_LINE_IN:
-return AUD_REC_LINE_IN;
-
-case REC_PHONE:
-return AUD_REC_PHONE;
-
-default:
-dolog (Unknown record source %d, using MIC\n, i);
-return AUD_REC_MIC;
-}
-}
-
-static uint8_t aud_to_ac97_record_source (audrecsource_t rs)
-{
-switch (rs) {
-case AUD_REC_MIC:
-return REC_MIC;
-
-case AUD_REC_CD:
-return REC_CD;
-
-case AUD_REC_VIDEO:
-return REC_VIDEO;
-
-case AUD_REC_AUX:
-return REC_AUX;
-
-case AUD_REC_LINE_IN:
-return REC_LINE_IN;
-
-case AUD_REC_PHONE:
-return REC_PHONE;
-
-default:
-dolog (Unknown audio recording source %d using MIC\n, rs);
-return REC_MIC;
-}
-}
-
-static void record_select (AC97LinkState *s, uint32_t val)
-{
-uint8_t rs = val  REC_MASK;
-uint8_t ls = (val  8)  REC_MASK;
-audrecsource_t ars = ac97_to_aud_record_source (rs);
-audrecsource_t als = ac97_to_aud_record_source (ls);
-AUD_set_record_source (als, ars);
-rs = aud_to_ac97_record_source (ars);
-ls = aud_to_ac97_record_source (als);
-mixer_store (s, AC97_Record_Select, rs | (ls  8));
-}
-#endif
-
 static void mixer_reset (AC97LinkState *s)
 {
 uint8_t active[LAST_INDEX];
@@ -559,12 +466,6 @@ static void mixer_reset (AC97LinkState *s)
 mixer_store (s, AC97_PCM_LR_ADC_Rate , 0xbb80);
 mixer_store (s, AC97_MIC_ADC_Rate, 0xbb80);
 
-#ifdef USE_MIXER
-record_select (s, 0);
-set_volume (s, AC97_Master_Volume_Mute, AUD_MIXER_VOLUME  , 0x8000);
-set_volume (s, AC97_PCM_Out_Volume_Mute, AUD_MIXER_PCM, 0x8808);
-set_volume (s, AC97_Line_In_Volume_Mute, AUD_MIXER_LINE_IN, 0x8808);
-#endif
 reset_voices (s, active);
 }
 
@@ -623,20 +524,6 @@ static void nam_writew (void *opaque, uint32_t addr, 
uint32_t val)
 val |= mixer_load (s, index)  0xf;
 mixer_store (s, index, val);
 break;
-#ifdef USE_MIXER
-case AC97_Master_Volume_Mute:
-set_volume (s, index, AUD_MIXER_VOLUME, val);
-break;
-case AC97_PCM_Out_Volume_Mute:
-set_volume (s, index, AUD_MIXER_PCM, val);
-break;
-case AC97_Line_In_Volume_Mute:
-set_volume (s, index, AUD_MIXER_LINE_IN, val);
-break;
-case AC97_Record_Select:
-record_select (s, val);
-break;
-#endif
 case AC97_Vendor_ID1:
 case AC97_Vendor_ID2:
 dolog (Attempt to write vendor ID to %#x\n, val);
@@ -1189,14 +1076,6 @@ static int ac97_post_load (void *opaque, int version_id)
 uint8_t active[LAST_INDEX];
 AC97LinkState *s = opaque;
 
-#ifdef USE_MIXER
-record_select (s, mixer_load (s, AC97_Record_Select));
-#define V_(a, b) set_volume (s, a, b, mixer_load (s, a))
-V_ (AC97_Master_Volume_Mute, AUD_MIXER_VOLUME);
-V_ (AC97_PCM_Out_Volume_Mute, AUD_MIXER_PCM);
-V_ (AC97_Line_In_Volume_Mute, AUD_MIXER_LINE_IN);
-#undef V_
-#endif
 active[PI_INDEX] = !!(s-bm_regs[PI_INDEX].cr  CR_RPBM);
 active[PO_INDEX] = !!(s-bm_regs[PO_INDEX].cr  CR_RPBM);
 active[MC_INDEX] = !!(s-bm_regs[MC_INDEX].cr  CR_RPBM);
-- 
1.7.6.2




[Qemu-devel] [PATCH 06/11] hw/ac97: new support for volume control

2011-10-13 Thread Marc-André Lureau
---
 hw/ac97.c |   79 +
 1 files changed, 79 insertions(+), 0 deletions(-)

diff --git a/hw/ac97.c b/hw/ac97.c
index ba94835..4a7c4ed 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -431,6 +431,63 @@ static void reset_voices (AC97LinkState *s, uint8_t 
active[LAST_INDEX])
 AUD_set_active_in (s-voice_mc, active[MC_INDEX]);
 }
 
+static void get_volume (uint16_t vol, uint16_t mask, int inverse,
+int *mute, uint8_t *lvol, uint8_t *rvol)
+{
+  *mute = (vol  MUTE_SHIFT)  1;
+  *rvol = (255 * (vol  mask)) / mask;
+  *lvol = (255 * ((vol  8)  mask)) / mask;
+  if (inverse) {
+*rvol = 255 - *rvol;
+*lvol = 255 - *lvol;
+  }
+}
+
+static void update_combined_volume_out (AC97LinkState *s)
+{
+uint8_t lvol, rvol, plvol, prvol;
+int mute, pmute;
+
+get_volume (mixer_load (s, AC97_Master_Volume_Mute), 0x3f, 1,
+mute, lvol, rvol);
+/* FIXME: should be 1f according to spec */
+get_volume (mixer_load (s, AC97_PCM_Out_Volume_Mute), 0x3f, 1,
+pmute, plvol, prvol);
+
+mute = mute | pmute;
+lvol = (lvol * plvol) / 255;
+rvol = (rvol * prvol) / 255;
+
+AUD_set_volume_out (s-voice_po, mute, lvol, rvol);
+}
+
+static void update_volume_in(AC97LinkState *s)
+{
+uint8_t lvol, rvol;
+int mute;
+
+get_volume (mixer_load (s, AC97_Record_Gain_Mute), 0x0f, 0,
+mute, lvol, rvol);
+
+AUD_set_volume_in (s-voice_pi, mute, lvol, rvol);
+}
+
+static void set_volume (AC97LinkState *s, int index, uint32_t val)
+{
+mixer_store (s, index, val);
+if (index == AC97_Master_Volume_Mute || index == AC97_PCM_Out_Volume_Mute)
+  update_combined_volume_out (s);
+else if (index == AC97_Record_Gain_Mute)
+  update_volume_in (s);
+}
+
+static void record_select (AC97LinkState *s, uint32_t val)
+{
+uint8_t rs = val  REC_MASK;
+uint8_t ls = (val  8)  REC_MASK;
+mixer_store (s, AC97_Record_Select, rs | (ls  8));
+}
+
 static void mixer_reset (AC97LinkState *s)
 {
 uint8_t active[LAST_INDEX];
@@ -465,6 +522,11 @@ static void mixer_reset (AC97LinkState *s)
 mixer_store (s, AC97_PCM_LR_ADC_Rate , 0xbb80);
 mixer_store (s, AC97_MIC_ADC_Rate, 0xbb80);
 
+record_select (s, 0);
+set_volume (s, AC97_Master_Volume_Mute, 0x8000);
+set_volume (s, AC97_PCM_Out_Volume_Mute, 0x8808);
+set_volume (s, AC97_Line_In_Volume_Mute, 0x8808);
+
 reset_voices (s, active);
 }
 
@@ -523,6 +585,15 @@ static void nam_writew (void *opaque, uint32_t addr, 
uint32_t val)
 val |= mixer_load (s, index)  0xf;
 mixer_store (s, index, val);
 break;
+case AC97_PCM_Out_Volume_Mute:
+case AC97_Master_Volume_Mute:
+case AC97_Record_Gain_Mute:
+case AC97_Line_In_Volume_Mute:
+set_volume (s, index, val);
+break;
+case AC97_Record_Select:
+record_select (s, val);
+break;
 case AC97_Vendor_ID1:
 case AC97_Vendor_ID2:
 dolog (Attempt to write vendor ID to %#x\n, val);
@@ -1075,6 +1146,14 @@ static int ac97_post_load (void *opaque, int version_id)
 uint8_t active[LAST_INDEX];
 AC97LinkState *s = opaque;
 
+record_select (s, mixer_load (s, AC97_Record_Select));
+set_volume (s, AC97_Master_Volume_Mute,
+mixer_load (s, AC97_Master_Volume_Mute));
+set_volume (s, AC97_PCM_Out_Volume_Mute,
+mixer_load (s, AC97_PCM_Out_Volume_Mute));
+set_volume (s, AC97_Line_In_Volume_Mute,
+mixer_load (s, AC97_Line_In_Volume_Mute));
+
 active[PI_INDEX] = !!(s-bm_regs[PI_INDEX].cr  CR_RPBM);
 active[PO_INDEX] = !!(s-bm_regs[PO_INDEX].cr  CR_RPBM);
 active[MC_INDEX] = !!(s-bm_regs[MC_INDEX].cr  CR_RPBM);
-- 
1.7.6.2




[Qemu-devel] [PATCH 10/11] audio: allow controlling volume with PulseAudio backend

2011-10-13 Thread Marc-André Lureau
---
 audio/paaudio.c |   96 ---
 1 files changed, 91 insertions(+), 5 deletions(-)

diff --git a/audio/paaudio.c b/audio/paaudio.c
index beed434..7ddc16d 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -664,15 +664,100 @@ static void qpa_fini_in (HWVoiceIn *hw)
 
 static int qpa_ctl_out (HWVoiceOut *hw, int cmd, ...)
 {
-(void) hw;
-(void) cmd;
+PAVoiceOut *pa = (PAVoiceOut *) hw;
+pa_operation *op;
+pa_cvolume v;
+paaudio *g = glob_paaudio;
+
+pa_cvolume_init (v);
+
+switch (cmd) {
+case VOICE_VOLUME:
+{
+SWVoiceOut *sw;
+va_list ap;
+
+va_start (ap, cmd);
+sw = va_arg (ap, SWVoiceOut *);
+va_end (ap);
+
+v.channels = 2;
+v.values[0] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw-vol.l) / 
UINT32_MAX;
+v.values[1] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw-vol.r) / 
UINT32_MAX;
+
+pa_threaded_mainloop_lock (g-mainloop);
+
+op = pa_context_set_sink_input_volume (g-context,
+pa_stream_get_index (pa-stream),
+v, NULL, NULL);
+if (!op)
+qpa_logerr (pa_context_errno (g-context),
+set_sink_input_volume() failed\n);
+else
+pa_operation_unref (op);
+
+op = pa_context_set_sink_input_mute (g-context,
+pa_stream_get_index (pa-stream),
+   sw-vol.mute, NULL, NULL);
+if (!op)
+qpa_logerr (pa_context_errno (g-context),
+set_sink_input_mute() failed\n);
+else
+pa_operation_unref (op);
+
+pa_threaded_mainloop_unlock (g-mainloop);
+}
+}
 return 0;
 }
 
 static int qpa_ctl_in (HWVoiceIn *hw, int cmd, ...)
 {
-(void) hw;
-(void) cmd;
+PAVoiceIn *pa = (PAVoiceIn *) hw;
+pa_operation *op;
+pa_cvolume v;
+paaudio *g = glob_paaudio;
+
+pa_cvolume_init (v);
+
+switch (cmd) {
+case VOICE_VOLUME:
+{
+SWVoiceIn *sw;
+va_list ap;
+
+va_start (ap, cmd);
+sw = va_arg (ap, SWVoiceIn *);
+va_end (ap);
+
+v.channels = 2;
+v.values[0] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw-vol.l) / 
UINT32_MAX;
+v.values[1] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * sw-vol.r) / 
UINT32_MAX;
+
+pa_threaded_mainloop_lock (g-mainloop);
+
+/* FIXME: use the upcoming set_source_output_{volume,mute} */
+op = pa_context_set_source_volume_by_index (g-context,
+pa_stream_get_device_index (pa-stream),
+v, NULL, NULL);
+if (!op)
+qpa_logerr (pa_context_errno (g-context),
+set_source_volume() failed\n);
+else
+pa_operation_unref(op);
+
+op = pa_context_set_source_mute_by_index (g-context,
+pa_stream_get_index (pa-stream),
+sw-vol.mute, NULL, NULL);
+if (!op)
+qpa_logerr (pa_context_errno (g-context),
+set_source_mute() failed\n);
+else
+pa_operation_unref (op);
+
+pa_threaded_mainloop_unlock (g-mainloop);
+}
+}
 return 0;
 }
 
@@ -801,5 +886,6 @@ struct audio_driver pa_audio_driver = {
 .max_voices_out = INT_MAX,
 .max_voices_in  = INT_MAX,
 .voice_size_out = sizeof (PAVoiceOut),
-.voice_size_in  = sizeof (PAVoiceIn)
+.voice_size_in  = sizeof (PAVoiceIn),
+.ctl_caps   = VOICE_VOLUME_CAP
 };
-- 
1.7.6.2




[Qemu-devel] [PATCH 05/11] hw/ac97: the volume mask was not always 0x1f

2011-10-13 Thread Marc-André Lureau
It's a case by case, which will be added appropriately.
---
 hw/ac97.c |1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/hw/ac97.c b/hw/ac97.c
index 4d4a658..ba94835 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -114,7 +114,6 @@ enum {
 #define EACS_VRA 1
 #define EACS_VRM 8
 
-#define VOL_MASK 0x1f
 #define MUTE_SHIFT 15
 
 #define REC_MASK 7
-- 
1.7.6.2




[Qemu-devel] [PATCH 07/11] audio/spice: add support for volume control

2011-10-13 Thread Marc-André Lureau
Changes since v1:
- remove #warning since qemu has -Werror by default
- do not claim VOICE_VOLUME_CAP if spice doesn't support it
---
 audio/spiceaudio.c |   41 +
 1 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c
index f972110..92964ae 100644
--- a/audio/spiceaudio.c
+++ b/audio/spiceaudio.c
@@ -202,7 +202,26 @@ static int line_out_ctl (HWVoiceOut *hw, int cmd, ...)
 }
 spice_server_playback_stop (out-sin);
 break;
+case VOICE_VOLUME:
+{
+#if ((SPICE_INTERFACE_PLAYBACK_MAJOR = 1)  (SPICE_INTERFACE_PLAYBACK_MINOR 
= 2))
+SWVoiceOut *sw;
+va_list ap;
+uint16_t vol[2];
+
+va_start (ap, cmd);
+sw = va_arg (ap, SWVoiceOut *);
+va_end (ap);
+
+vol[0] = sw-vol.l  16;
+vol[1] = sw-vol.r  16;
+spice_server_playback_set_volume (out-sin, 2, vol);
+spice_server_playback_set_mute (out-sin, sw-vol.mute);
+#endif
+break;
+}
 }
+
 return 0;
 }
 
@@ -304,7 +323,26 @@ static int line_in_ctl (HWVoiceIn *hw, int cmd, ...)
 in-active = 0;
 spice_server_record_stop (in-sin);
 break;
+case VOICE_VOLUME:
+{
+#if ((SPICE_INTERFACE_RECORD_MAJOR = 2)  (SPICE_INTERFACE_RECORD_MINOR = 
2))
+SWVoiceIn *sw;
+va_list ap;
+uint16_t vol[2];
+
+va_start (ap, cmd);
+sw = va_arg (ap, SWVoiceIn *);
+va_end (ap);
+
+vol[0] = sw-vol.l  16;
+vol[1] = sw-vol.r  16;
+spice_server_record_set_volume (in-sin, 2, vol);
+spice_server_record_set_mute (in-sin, sw-vol.mute);
+#endif
+break;
+}
 }
+
 return 0;
 }
 
@@ -337,6 +375,9 @@ struct audio_driver spice_audio_driver = {
 .max_voices_in  = 1,
 .voice_size_out = sizeof (SpiceVoiceOut),
 .voice_size_in  = sizeof (SpiceVoiceIn),
+#if ((SPICE_INTERFACE_PLAYBACK_MAJOR = 1)  (SPICE_INTERFACE_PLAYBACK_MINOR 
= 2))
+.ctl_caps   = VOICE_VOLUME_CAP
+#endif
 };
 
 void qemu_spice_audio_init (void)
-- 
1.7.6.2




[Qemu-devel] [PATCH 18/35] scsi: add channel to addressing

2011-10-13 Thread Paolo Bonzini
This also requires little more than adding the new argument to
scsi_device_find, and the qdev property.  All devices by default
end up on channel 0.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/esp.c |4 ++--
 hw/lsi53c895a.c  |4 ++--
 hw/scsi-bus.c|   24 +++-
 hw/scsi.h|5 +++--
 hw/spapr_vscsi.c |9 +++--
 5 files changed, 25 insertions(+), 21 deletions(-)

diff --git a/hw/esp.c b/hw/esp.c
index 0ebc181..9b97a84 100644
--- a/hw/esp.c
+++ b/hw/esp.c
@@ -217,7 +217,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf)
 s-async_len = 0;
 }
 
-s-current_dev = scsi_device_find(s-bus, target, 0);
+s-current_dev = scsi_device_find(s-bus, 0, target, 0);
 if (!s-current_dev) {
 // No such drive
 s-rregs[ESP_RSTAT] = 0;
@@ -236,7 +236,7 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t 
busid)
 
 trace_esp_do_busid_cmd(busid);
 lun = busid  7;
-s-current_dev = scsi_device_find(s-bus, s-current_dev-id, lun);
+s-current_dev = scsi_device_find(s-bus, 0, s-current_dev-id, lun);
 s-current_req = scsi_req_new(s-current_dev, 0, lun, buf, NULL);
 datalen = scsi_req_enqueue(s-current_req);
 s-ti_size = datalen;
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index d26e442..2984cea 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -767,7 +767,7 @@ static void lsi_do_command(LSIState *s)
 s-command_complete = 0;
 
 id = (s-select_tag  8)  0xf;
-dev = scsi_device_find(s-bus, id, s-current_lun);
+dev = scsi_device_find(s-bus, 0, id, s-current_lun);
 if (!dev) {
 lsi_bad_selection(s, id);
 return;
@@ -1198,7 +1198,7 @@ again:
 }
 s-sstat0 |= LSI_SSTAT0_WOA;
 s-scntl1 = ~LSI_SCNTL1_IARB;
-if (!scsi_device_find(s-bus, id, 0)) {
+if (!scsi_device_find(s-bus, 0, id, 0)) {
 lsi_bad_selection(s, id);
 break;
 }
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index cec06db..bdd6e94 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -16,6 +16,7 @@ static struct BusInfo scsi_bus_info = {
 .size  = sizeof(SCSIBus),
 .get_fw_dev_path = scsibus_get_fw_dev_path,
 .props = (Property[]) {
+DEFINE_PROP_UINT32(channel, SCSIDevice, channel, 0),
 DEFINE_PROP_UINT32(scsi-id, SCSIDevice, id, -1),
 DEFINE_PROP_UINT32(lun, SCSIDevice, lun, -1),
 DEFINE_PROP_END_OF_LIST(),
@@ -40,6 +41,10 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo 
*base)
 SCSIDevice *d;
 int rc = -1;
 
+if (dev-channel  bus-info-max_channel) {
+error_report(bad scsi channel id: %d, dev-channel);
+goto err;
+}
 if (dev-id != -1  dev-id  bus-info-max_target) {
 error_report(bad scsi device id: %d, dev-id);
 goto err;
@@ -51,7 +56,7 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
 dev-lun = 0;
 }
 do {
-d = scsi_device_find(bus, ++id, dev-lun);
+d = scsi_device_find(bus, dev-channel, ++id, dev-lun);
 } while (d  d-lun == dev-lun  id = bus-info-max_target);
 if (id  bus-info-max_target) {
 error_report(no free target);
@@ -61,7 +66,7 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
 } else if (dev-lun == -1) {
 int lun = -1;
 do {
-d = scsi_device_find(bus, dev-id, ++lun);
+d = scsi_device_find(bus, dev-channel, dev-id, ++lun);
 } while (d  d-lun == lun  lun  bus-info-max_lun);
 if (lun  bus-info-max_lun) {
 error_report(no free lun);
@@ -69,7 +74,7 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
 }
 dev-lun = lun;
 } else {
-d = scsi_device_find(bus, dev-id, dev-lun);
+d = scsi_device_find(bus, dev-channel, dev-id, dev-lun);
 if (dev-lun == d-lun  dev != d) {
 qdev_free(d-qdev);
 }
@@ -203,7 +208,7 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq 
*r)
 {
 DeviceState *qdev;
 int i, len, n;
-int id;
+int channel, id;
 bool found_lun0;
 
 if (r-req.cmd.xfer  16) {
@@ -212,13 +217,14 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq 
*r)
 if (r-req.cmd.buf[2]  2) {
 return false;
 }
+channel = r-req.dev-channel;
 id = r-req.dev-id;
 found_lun0 = false;
 n = 0;
 QTAILQ_FOREACH(qdev, r-req.bus-qbus.children, sibling) {
 SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
 
-if (dev-id == id) {
+if (dev-channel == channel  dev-id == id) {
 if (dev-lun == 0) {
 found_lun0 = true;
 }
@@ -240,7 +246,7 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq 
*r)
 QTAILQ_FOREACH(qdev, r-req.bus-qbus.children, sibling) {
 SCSIDevice *dev = 

[Qemu-devel] [PATCH 2/9] usb-hub: need to check dev-attached

2011-10-13 Thread Gerd Hoffmann
commit 891fb2cd4592b6fe76106a69e0ca40efbf82726a did that for all host
controllers, the usb hub was left out by accident.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/usb-hub.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/usb-hub.c b/hw/usb-hub.c
index 286e3ad..39382c7 100644
--- a/hw/usb-hub.c
+++ b/hw/usb-hub.c
@@ -289,7 +289,7 @@ static int usb_hub_handle_control(USBDevice *dev, USBPacket 
*p,
 port-wPortStatus |= PORT_STAT_SUSPEND;
 break;
 case PORT_RESET:
-if (dev) {
+if (dev  dev-attached) {
 usb_send_msg(dev, USB_MSG_RESET);
 port-wPortChange |= PORT_STAT_C_RESET;
 /* set enable bit */
@@ -429,7 +429,7 @@ static int usb_hub_broadcast_packet(USBHubState *s, 
USBPacket *p)
 for(i = 0; i  NUM_PORTS; i++) {
 port = s-ports[i];
 dev = port-port.dev;
-if (dev  (port-wPortStatus  PORT_STAT_ENABLE)) {
+if (dev  dev-attached  (port-wPortStatus  PORT_STAT_ENABLE)) {
 ret = usb_handle_packet(dev, p);
 if (ret != USB_RET_NODEV) {
 return ret;
-- 
1.7.1




[Qemu-devel] [PATCH 01/35] scsi: pass correct sense code for ENOMEDIUM

2011-10-13 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-disk.c |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 6909578..9c62569 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -231,6 +231,9 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, 
int type)
 bdrv_iostatus_set_err(s-bs, error);
 } else {
 switch (error) {
+case ENOMEDIUM:
+scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
+break;
 case ENOMEM:
 scsi_check_condition(r, SENSE_CODE(TARGET_FAILURE));
 break;
-- 
1.7.6





[Qemu-devel] [PATCH 01/11] audio: add VOICE_VOLUME ctl

2011-10-13 Thread Marc-André Lureau
---
 audio/audio.c |   12 
 audio/audio_int.h |1 +
 2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index 5649075..c759c1f 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -2050,17 +2050,29 @@ void AUD_del_capture (CaptureVoiceOut *cap, void 
*cb_opaque)
 void AUD_set_volume_out (SWVoiceOut *sw, int mute, uint8_t lvol, uint8_t rvol)
 {
 if (sw) {
+HWVoiceOut *hw = sw-hw;
+
 sw-vol.mute = mute;
 sw-vol.l = nominal_volume.l * lvol / 255;
 sw-vol.r = nominal_volume.r * rvol / 255;
+
+if (hw-pcm_ops-ctl_out) {
+hw-pcm_ops-ctl_out (hw, VOICE_VOLUME, sw);
+}
 }
 }
 
 void AUD_set_volume_in (SWVoiceIn *sw, int mute, uint8_t lvol, uint8_t rvol)
 {
 if (sw) {
+HWVoiceIn *hw = sw-hw;
+
 sw-vol.mute = mute;
 sw-vol.l = nominal_volume.l * lvol / 255;
 sw-vol.r = nominal_volume.r * rvol / 255;
+
+if (hw-pcm_ops-ctl_in) {
+hw-pcm_ops-ctl_in (hw, VOICE_VOLUME, sw);
+}
 }
 }
diff --git a/audio/audio_int.h b/audio/audio_int.h
index 2003f8b..117f95e 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -231,6 +231,7 @@ void audio_run (const char *msg);
 
 #define VOICE_ENABLE 1
 #define VOICE_DISABLE 2
+#define VOICE_VOLUME 3
 
 static inline int audio_ring_dist (int dst, int src, int len)
 {
-- 
1.7.6.2




[Qemu-devel] [PATCH 07/35] scsi-disk: add stubs for more MMC commands

2011-10-13 Thread Paolo Bonzini
This patch adds a few stub implementations for MMC commands to
scsi-disk, to be filled in later in the series.  It also adds to
scsi-defs.h constants for commands implemented by ide/atapi.c,
when missing.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-defs.h |3 ++
 hw/scsi-disk.c |   63 +++
 2 files changed, 61 insertions(+), 5 deletions(-)

diff --git a/hw/scsi-defs.h b/hw/scsi-defs.h
index 8094698..030d4c2 100644
--- a/hw/scsi-defs.h
+++ b/hw/scsi-defs.h
@@ -113,6 +113,7 @@
 #define READ_12   0xa8
 #define WRITE_12  0xaa
 #define SERVICE_ACTION_IN_12  0xab
+#define READ_DVD_STRUCTURE0xad
 #define WRITE_VERIFY_12   0xae
 #define VERIFY_12 0xaf
 #define SEARCH_HIGH_120xb0
@@ -122,6 +123,8 @@
 #define SEND_VOLUME_TAG   0xb6
 #define READ_DEFECT_DATA_12   0xb7
 #define SET_CD_SPEED  0xbb
+#define MECHANISM_STATUS  0xbd
+#define READ_CD   0xbe
 
 /*
  * SERVICE ACTION IN subcodes
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 880cb22..95a6b77 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -563,6 +563,43 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, 
uint8_t *outbuf)
 return buflen;
 }
 
+static int scsi_read_dvd_structure(SCSIDiskState *s, SCSIDiskReq *r,
+   uint8_t *outbuf)
+{
+scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
+return -1;
+}
+
+static int scsi_get_event_status_notification(SCSIDiskState *s,
+  SCSIDiskReq *r, uint8_t *outbuf)
+{
+scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
+return -1;
+}
+
+static int scsi_get_configuration(SCSIDiskState *s, SCSIDiskReq *r,
+  uint8_t *outbuf)
+{
+if (s-qdev.type != TYPE_ROM) {
+return -1;
+}
+memset(outbuf, 0, 8);
+/* ??? This should probably return much more information.  For now
+   just return the basic header indicating the CD-ROM profile.  */
+outbuf[7] = 8; // CD-ROM
+return 8;
+}
+
+static int scsi_emulate_mechanism_status(SCSIDiskState *s, uint8_t *outbuf)
+{
+if (s-qdev.type != TYPE_ROM) {
+return -1;
+}
+memset(outbuf, 0, 8);
+outbuf[5] = 1; // CD-ROM
+return 8;
+}
+
 static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf,
int page_control)
 {
@@ -947,12 +984,25 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
 outbuf[7] = 0;
 buflen = 8;
 break;
+case MECHANISM_STATUS:
+buflen = scsi_emulate_mechanism_status(s, outbuf);
+if (buflen  0)
+goto illegal_request;
+break;
 case GET_CONFIGURATION:
-memset(outbuf, 0, 8);
-/* ??? This should probably return much more information.  For now
-   just return the basic header indicating the CD-ROM profile.  */
-outbuf[7] = 8; // CD-ROM
-buflen = 8;
+buflen = scsi_get_configuration(s, r, outbuf);
+if (buflen  0)
+goto illegal_request;
+break;
+case GET_EVENT_STATUS_NOTIFICATION:
+buflen = scsi_get_event_status_notification(s, r, outbuf);
+if (buflen  0)
+goto illegal_request;
+break;
+case READ_DVD_STRUCTURE:
+buflen = scsi_read_dvd_structure(s, r, outbuf);
+if (buflen  0)
+goto illegal_request;
 break;
 case SERVICE_ACTION_IN_16:
 /* Service Action In subcommands. */
@@ -1055,7 +1105,10 @@ static int32_t scsi_send_command(SCSIRequest *req, 
uint8_t *buf)
 case ALLOW_MEDIUM_REMOVAL:
 case READ_CAPACITY_10:
 case READ_TOC:
+case READ_DVD_STRUCTURE:
 case GET_CONFIGURATION:
+case GET_EVENT_STATUS_NOTIFICATION:
+case MECHANISM_STATUS:
 case SERVICE_ACTION_IN_16:
 case VERIFY_10:
 rc = scsi_disk_emulate_command(r);
-- 
1.7.6





[Qemu-devel] [PATCH 3/9] usb: fix port reset

2011-10-13 Thread Gerd Hoffmann
commit 891fb2cd4592b6fe76106a69e0ca40efbf82726a removed the implicit
detach before (re-)attaching in usb_attach().  Some usb host controllers
used that behavior though to do a port reset by a detach+attach
sequence.

This patch establishes old behavior by adding a new usb_reset() function
for port resets and putting it into use, thereby also unifying port
reset behavior of all host controllers.  The patch also adds asserts to
usb_attach() and usb_detach() to make sure the calls are symmetrical.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/usb-ehci.c |4 ++--
 hw/usb-ohci.c |2 +-
 hw/usb-uhci.c |2 +-
 hw/usb.c  |   12 
 hw/usb.h  |1 +
 5 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index 27376a2..bd374c1 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -880,6 +880,7 @@ static void ehci_reset(void *opaque)
 }
 if (devs[i]  devs[i]-attached) {
 usb_attach(s-ports[i]);
+usb_send_msg(devs[i], USB_MSG_RESET);
 }
 }
 ehci_queues_rip_all(s);
@@ -978,8 +979,7 @@ static void handle_port_status_write(EHCIState *s, int 
port, uint32_t val)
 if (!(val  PORTSC_PRESET) (*portsc  PORTSC_PRESET)) {
 trace_usb_ehci_port_reset(port, 0);
 if (dev  dev-attached) {
-usb_attach(s-ports[port]);
-usb_send_msg(dev, USB_MSG_RESET);
+usb_reset(s-ports[port]);
 *portsc = ~PORTSC_CSC;
 }
 
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index c3be65a..5e10e21 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -449,7 +449,7 @@ static void ohci_reset(void *opaque)
 port = ohci-rhport[i];
 port-ctrl = 0;
 if (port-port.dev  port-port.dev-attached) {
-usb_attach(port-port);
+usb_reset(port-port);
 }
   }
 if (ohci-async_td) {
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 17992cf..171d787 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -341,7 +341,7 @@ static void uhci_reset(void *opaque)
 port = s-ports[i];
 port-ctrl = 0x0080;
 if (port-port.dev  port-port.dev-attached) {
-usb_attach(port-port);
+usb_reset(port-port);
 }
 }
 
diff --git a/hw/usb.c b/hw/usb.c
index fa90204..2216efe 100644
--- a/hw/usb.c
+++ b/hw/usb.c
@@ -33,6 +33,7 @@ void usb_attach(USBPort *port)
 
 assert(dev != NULL);
 assert(dev-attached);
+assert(dev-state == USB_STATE_NOTATTACHED);
 port-ops-attach(port);
 usb_send_msg(dev, USB_MSG_ATTACH);
 }
@@ -42,10 +43,21 @@ void usb_detach(USBPort *port)
 USBDevice *dev = port-dev;
 
 assert(dev != NULL);
+assert(dev-state != USB_STATE_NOTATTACHED);
 port-ops-detach(port);
 usb_send_msg(dev, USB_MSG_DETACH);
 }
 
+void usb_reset(USBPort *port)
+{
+USBDevice *dev = port-dev;
+
+assert(dev != NULL);
+usb_detach(port);
+usb_attach(port);
+usb_send_msg(dev, USB_MSG_RESET);
+}
+
 void usb_wakeup(USBDevice *dev)
 {
 if (dev-remote_wakeup  dev-port  dev-port-ops-wakeup) {
diff --git a/hw/usb.h b/hw/usb.h
index c08d469..c6e1870 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -306,6 +306,7 @@ void usb_cancel_packet(USBPacket * p);
 
 void usb_attach(USBPort *port);
 void usb_detach(USBPort *port);
+void usb_reset(USBPort *port);
 void usb_wakeup(USBDevice *dev);
 int usb_generic_handle_packet(USBDevice *s, USBPacket *p);
 void usb_generic_async_ctrl_complete(USBDevice *s, USBPacket *p);
-- 
1.7.1




[Qemu-devel] [PATCH 17/35] scsi: allow arbitrary LUNs

2011-10-13 Thread Paolo Bonzini
This only requires changes in two places: in SCSIBus, we need to look
for a free LUN if somebody creates a device with a pre-existing scsi-id
but the default LUN (-1, meaning search for a free spot); in vSCSI,
we need to actually parse the LUN according to the SCSI spec.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/esp.c |3 ++-
 hw/lsi53c895a.c  |3 ++-
 hw/scsi-bus.c|   48 
 hw/scsi.h|3 ++-
 hw/spapr_vscsi.c |   39 +++
 hw/usb-msd.c |3 ++-
 6 files changed, 75 insertions(+), 24 deletions(-)

diff --git a/hw/esp.c b/hw/esp.c
index 8e17005..0ebc181 100644
--- a/hw/esp.c
+++ b/hw/esp.c
@@ -723,7 +723,8 @@ void esp_init(target_phys_addr_t espaddr, int it_shift,
 
 static const struct SCSIBusInfo esp_scsi_info = {
 .tcq = false,
-.ndev = ESP_MAX_DEVS,
+.max_target = ESP_MAX_DEVS,
+.max_lun = 7,
 
 .transfer_data = esp_transfer_data,
 .complete = esp_command_complete,
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index c15f167..d26e442 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -2085,7 +2085,8 @@ static int lsi_scsi_uninit(PCIDevice *d)
 
 static const struct SCSIBusInfo lsi_scsi_info = {
 .tcq = true,
-.ndev = LSI_MAX_DEVS,
+.max_target = LSI_MAX_DEVS,
+.max_lun = 0,  /* LUN support is buggy */
 
 .transfer_data = lsi_transfer_data,
 .complete = lsi_command_complete,
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index a2d57a7..cec06db 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -17,7 +17,7 @@ static struct BusInfo scsi_bus_info = {
 .get_fw_dev_path = scsibus_get_fw_dev_path,
 .props = (Property[]) {
 DEFINE_PROP_UINT32(scsi-id, SCSIDevice, id, -1),
-DEFINE_PROP_UINT32(lun, SCSIDevice, lun, 0),
+DEFINE_PROP_UINT32(lun, SCSIDevice, lun, -1),
 DEFINE_PROP_END_OF_LIST(),
 },
 };
@@ -37,26 +37,42 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo 
*base)
 SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
 SCSIDeviceInfo *info = DO_UPCAST(SCSIDeviceInfo, qdev, base);
 SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev-qdev.parent_bus);
-SCSIDevice *olddev;
+SCSIDevice *d;
 int rc = -1;
 
-if (dev-id == -1) {
-int id;
-for (id = 0; id  bus-info-ndev; id++) {
-if (!scsi_device_find(bus, id, 0)) {
-dev-id = id;
-break;
-}
-}
-}
-if (dev-id = bus-info-ndev) {
+if (dev-id != -1  dev-id  bus-info-max_target) {
 error_report(bad scsi device id: %d, dev-id);
 goto err;
 }
 
-olddev = scsi_device_find(bus, dev-id, dev-lun);
-if (olddev  dev-lun == olddev-lun) {
-qdev_free(olddev-qdev);
+if (dev-id == -1) {
+int id = -1;
+if (dev-lun == -1) {
+dev-lun = 0;
+}
+do {
+d = scsi_device_find(bus, ++id, dev-lun);
+} while (d  d-lun == dev-lun  id = bus-info-max_target);
+if (id  bus-info-max_target) {
+error_report(no free target);
+goto err;
+}
+dev-id = id;
+} else if (dev-lun == -1) {
+int lun = -1;
+do {
+d = scsi_device_find(bus, dev-id, ++lun);
+} while (d  d-lun == lun  lun  bus-info-max_lun);
+if (lun  bus-info-max_lun) {
+error_report(no free lun);
+goto err;
+}
+dev-lun = lun;
+} else {
+d = scsi_device_find(bus, dev-id, dev-lun);
+if (dev-lun == d-lun  dev != d) {
+qdev_free(d-qdev);
+}
 }
 
 dev-info = info;
@@ -115,7 +131,7 @@ int scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
 int res = 0, unit;
 
 loc_push_none(loc);
-for (unit = 0; unit  bus-info-ndev; unit++) {
+for (unit = 0; unit  bus-info-max_target; unit++) {
 dinfo = drive_get(IF_SCSI, bus-busnr, unit);
 if (dinfo == NULL) {
 continue;
diff --git a/hw/scsi.h b/hw/scsi.h
index add3d2d..401d8d3 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -98,7 +98,8 @@ struct SCSIDeviceInfo {
 };
 
 struct SCSIBusInfo {
-int tcq, ndev;
+int tcq;
+int max_target, max_lun;
 void (*transfer_data)(SCSIRequest *req, uint32_t arg);
 void (*complete)(SCSIRequest *req, uint32_t arg);
 void (*cancel)(SCSIRequest *req);
diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
index aae845a..334b2e6 100644
--- a/hw/spapr_vscsi.c
+++ b/hw/spapr_vscsi.c
@@ -131,9 +131,39 @@ static void vscsi_put_req(vscsi_req *req)
 
 static SCSIDevice *vscsi_device_find(SCSIBus *bus, uint64_t srp_lun, int *lun)
 {
-/* XXX Figure that one out properly ! This is crackpot */
-int id = (srp_lun  56)  0x7f;
-*lun = (srp_lun  48)  0xff;
+int channel = 0, id = 0;
+
+retry:
+switch (srp_lun  62) {
+case 0:
+if ((srp_lun  56) != 0) {
+channel = (srp_lun  56)  0x3f;
+

[Qemu-devel] [PATCH 06/35] scsi-disk: report media changed via unit attention sense codes

2011-10-13 Thread Paolo Bonzini
Building on the previous patch, this one adds a media change callback
to scsi-disk.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-bus.c  |5 +
 hw/scsi-disk.c |   29 -
 hw/scsi.h  |2 ++
 3 files changed, 35 insertions(+), 1 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index c190509..867b1a8 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -847,6 +847,11 @@ const struct SCSISense sense_code_RESET = {
 .key = UNIT_ATTENTION, .asc = 0x29, .ascq = 0x00
 };
 
+/* Unit attention, No medium */
+const struct SCSISense sense_code_UNIT_ATTENTION_NO_MEDIUM = {
+.key = UNIT_ATTENTION, .asc = 0x3a, .ascq = 0x00
+};
+
 /* Unit attention, Medium may have changed */
 const struct SCSISense sense_code_MEDIUM_CHANGED = {
 .key = UNIT_ATTENTION, .asc = 0x28, .ascq = 0x00
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index a6ef060..880cb22 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -71,6 +71,7 @@ struct SCSIDiskState
 int cluster_size;
 uint32_t removable;
 uint64_t max_lba;
+bool media_changed;
 QEMUBH *bh;
 char *version;
 char *serial;
@@ -1198,7 +1199,21 @@ static void scsi_destroy(SCSIDevice *dev)
 
 static void scsi_cd_change_media_cb(void *opaque, bool load)
 {
-((SCSIDiskState *)opaque)-tray_open = !load;
+SCSIDiskState *s = opaque;
+
+/*
+ * When a CD gets changed, we have to report an ejected state and
+ * then a loaded state to guests so that they detect tray
+ * open/close and media change events.  Guests that do not use
+ * GET_EVENT_STATUS_NOTIFICATION to detect such tray open/close
+ * states rely on this behavior.
+ *
+ * media_changed governs the state machine used for unit attention
+ * report.  media_event is used by GET EVENT STATUS NOTIFICATION.
+ */
+s-media_changed = load;
+s-tray_open = !load;
+s-qdev.unit_attention = SENSE_CODE(UNIT_ATTENTION_NO_MEDIUM);
 }
 
 static bool scsi_cd_is_tray_open(void *opaque)
@@ -1217,6 +1232,15 @@ static const BlockDevOps scsi_cd_block_ops = {
 .is_medium_locked = scsi_cd_is_medium_locked,
 };
 
+static void scsi_disk_unit_attention_reported(SCSIDevice *dev)
+{
+SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
+if (s-media_changed) {
+s-media_changed = false;
+s-qdev.unit_attention = SENSE_CODE(MEDIUM_CHANGED);
+}
+}
+
 static int scsi_initfn(SCSIDevice *dev, uint8_t scsi_type)
 {
 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
@@ -1329,6 +1353,7 @@ static SCSIDeviceInfo scsi_disk_info[] = {
 .init = scsi_hd_initfn,
 .destroy  = scsi_destroy,
 .alloc_req= scsi_new_request,
+.unit_attention_reported = scsi_disk_unit_attention_reported,
 .qdev.props   = (Property[]) {
 DEFINE_SCSI_DISK_PROPERTIES(),
 DEFINE_PROP_BIT(removable, SCSIDiskState, removable, 0, false),
@@ -1343,6 +1368,7 @@ static SCSIDeviceInfo scsi_disk_info[] = {
 .init = scsi_cd_initfn,
 .destroy  = scsi_destroy,
 .alloc_req= scsi_new_request,
+.unit_attention_reported = scsi_disk_unit_attention_reported,
 .qdev.props   = (Property[]) {
 DEFINE_SCSI_DISK_PROPERTIES(),
 DEFINE_PROP_END_OF_LIST(),
@@ -1356,6 +1382,7 @@ static SCSIDeviceInfo scsi_disk_info[] = {
 .init = scsi_disk_initfn,
 .destroy  = scsi_destroy,
 .alloc_req= scsi_new_request,
+.unit_attention_reported = scsi_disk_unit_attention_reported,
 .qdev.props   = (Property[]) {
 DEFINE_SCSI_DISK_PROPERTIES(),
 DEFINE_PROP_BIT(removable, SCSIDiskState, removable, 0, false),
diff --git a/hw/scsi.h b/hw/scsi.h
index 6d40b8e..7004aaa 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -161,6 +161,8 @@ extern const struct SCSISense sense_code_IO_ERROR;
 extern const struct SCSISense sense_code_I_T_NEXUS_LOSS;
 /* Command aborted, Logical Unit failure */
 extern const struct SCSISense sense_code_LUN_FAILURE;
+/* LUN not ready, Medium not present */
+extern const struct SCSISense sense_code_UNIT_ATTENTION_NO_MEDIUM;
 /* Unit attention, Power on, reset or bus device reset occurred */
 extern const struct SCSISense sense_code_RESET;
 /* Unit attention, Medium may have changed*/
-- 
1.7.6





[Qemu-devel] [PATCH 10/35] scsi-disk: support DVD profile in GET CONFIGURATION

2011-10-13 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-disk.c |   50 ++
 1 files changed, 42 insertions(+), 8 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 837747f..1786c37 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -563,6 +563,19 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, 
uint8_t *outbuf)
 return buflen;
 }
 
+static inline bool media_is_dvd(SCSIDiskState *s)
+{
+uint64_t nb_sectors;
+if (s-qdev.type != TYPE_ROM) {
+return false;
+}
+if (!bdrv_is_inserted(s-bs)) {
+return false;
+}
+bdrv_get_geometry(s-bs, nb_sectors);
+return nb_sectors  CD_MAX_SECTORS;
+}
+
 static int scsi_read_dvd_structure(SCSIDiskState *s, SCSIDiskReq *r,
uint8_t *outbuf)
 {
@@ -577,17 +590,38 @@ static int 
scsi_get_event_status_notification(SCSIDiskState *s,
 return -1;
 }
 
-static int scsi_get_configuration(SCSIDiskState *s, SCSIDiskReq *r,
-  uint8_t *outbuf)
+static int scsi_get_configuration(SCSIDiskState *s, uint8_t *outbuf)
 {
+int current;
+
 if (s-qdev.type != TYPE_ROM) {
 return -1;
 }
-memset(outbuf, 0, 8);
-/* ??? This should probably return much more information.  For now
-   just return the basic header indicating the CD-ROM profile.  */
-outbuf[7] = 8; // CD-ROM
-return 8;
+current = media_is_dvd(s) ? MMC_PROFILE_DVD_ROM : MMC_PROFILE_CD_ROM;
+memset(outbuf, 0, 40);
+stl_be_p(outbuf[0], 36); /* Bytes after the data length field */
+/* outbuf[4] - outbuf[19]: Feature 0 - Profile list */
+stw_be_p(outbuf[6], current);
+outbuf[10] = 0x03; /* persistent, current */
+outbuf[11] = 8; /* two profiles */
+stw_be_p(outbuf[12], MMC_PROFILE_DVD_ROM);
+outbuf[14] = (current == MMC_PROFILE_DVD_ROM);
+stw_be_p(outbuf[16], MMC_PROFILE_CD_ROM);
+outbuf[18] = (current == MMC_PROFILE_CD_ROM);
+/* outbuf[20] - outbuf[31]: Feature 1 - Core feature */
+stw_be_p(outbuf[20], 1);
+outbuf[22] = 0x08 | 0x03; /* version 2, persistent, current */
+outbuf[23] = 8;
+stl_be_p(outbuf[24], 1); /* SCSI */
+outbuf[28] = 1; /* DBE = 1, mandatory */
+/* outbuf[32] - outbuf[39]: Feature 3 - Removable media feature */
+stw_be_p(outbuf[32], 3);
+outbuf[34] = 0x08 | 0x03; /* version 2, persistent, current */
+outbuf[35] = 4;
+outbuf[36] = 0x39; /* tray, load=1, eject=1, unlocked at powerup, lock=1 */
+/* TODO: Random readable, CD read, DVD read, drive serial number,
+   power management */
+return 40;
 }
 
 static int scsi_emulate_mechanism_status(SCSIDiskState *s, uint8_t *outbuf)
@@ -1006,7 +1040,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r)
 goto illegal_request;
 break;
 case GET_CONFIGURATION:
-buflen = scsi_get_configuration(s, r, outbuf);
+buflen = scsi_get_configuration(s, outbuf);
 if (buflen  0)
 goto illegal_request;
 break;
-- 
1.7.6





[Qemu-devel] [PATCH 27/35] scsi-generic: snoop READ CAPACITY commands to get block size

2011-10-13 Thread Paolo Bonzini
Instead of guessing the block size when there is no medium in the
drive, wait for the guest to send a READ CAPACITY command and retrieve
it from there.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-generic.c |   50 +++---
 1 files changed, 11 insertions(+), 39 deletions(-)

diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 787c581..cb02a7e 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -155,6 +155,7 @@ static int execute_command(BlockDriverState *bdrv,
 static void scsi_read_complete(void * opaque, int ret)
 {
 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
+SCSIDevice *s = r-req.dev;
 int len;
 
 r-req.aiocb = NULL;
@@ -170,6 +171,15 @@ static void scsi_read_complete(void * opaque, int ret)
 if (len == 0) {
 scsi_command_complete(r, 0);
 } else {
+/* Snoop READ CAPACITY output to set the blocksize.  */
+if (r-req.cmd.buf[0] == READ_CAPACITY_10) {
+s-blocksize = ldl_be_p(r-buf[4]);
+} else if (r-req.cmd.buf[0] == SERVICE_ACTION_IN_16 
+   (r-req.cmd.buf[1]  31) == SAI_READ_CAPACITY_16) {
+s-blocksize = ldl_be_p(r-buf[8]);
+}
+bdrv_set_buffer_alignment(s-conf.bs, s-blocksize);
+
 scsi_req_data(r-req, len);
 }
 }
@@ -299,36 +309,6 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t 
*cmd)
 }
 }
 
-static int get_blocksize(BlockDriverState *bdrv)
-{
-uint8_t cmd[10];
-uint8_t buf[8];
-uint8_t sensebuf[8];
-sg_io_hdr_t io_header;
-int ret;
-
-memset(cmd, 0, sizeof(cmd));
-memset(buf, 0, sizeof(buf));
-cmd[0] = READ_CAPACITY_10;
-
-memset(io_header, 0, sizeof(io_header));
-io_header.interface_id = 'S';
-io_header.dxfer_direction = SG_DXFER_FROM_DEV;
-io_header.dxfer_len = sizeof(buf);
-io_header.dxferp = buf;
-io_header.cmdp = cmd;
-io_header.cmd_len = sizeof(cmd);
-io_header.mx_sb_len = sizeof(sensebuf);
-io_header.sbp = sensebuf;
-io_header.timeout = 6000; /* XXX */
-
-ret = bdrv_ioctl(bdrv, SG_IO, io_header);
-if (ret  0 || io_header.driver_status || io_header.host_status)
-return -1;
-
-return (buf[4]  24) | (buf[5]  16) | (buf[6]  8) | buf[7];
-}
-
 static int get_stream_blocksize(BlockDriverState *bdrv)
 {
 uint8_t cmd[6];
@@ -413,20 +393,12 @@ static int scsi_generic_initfn(SCSIDevice *s)
 
 /* define device state */
 s-type = scsiid.scsi_type;
+s-blocksize = 0;
 DPRINTF(device type %d\n, s-type);
 if (s-type == TYPE_TAPE) {
 s-blocksize = get_stream_blocksize(s-conf.bs);
 if (s-blocksize == -1)
 s-blocksize = 0;
-} else {
-s-blocksize = get_blocksize(s-conf.bs);
-/* removable media returns 0 if not present */
-if (s-blocksize = 0) {
-if (s-type == TYPE_ROM || s-type  == TYPE_WORM)
-s-blocksize = 2048;
-else
-s-blocksize = 512;
-}
 }
 
 DPRINTF(block size %d\n, s-blocksize);
-- 
1.7.6





[Qemu-devel] [PATCH 5/9] usb-host: handle USBDEVFS_SETCONFIGURATION returning EBUSY

2011-10-13 Thread Gerd Hoffmann
In case the host uses the usb device usbfs will refuse to set the
configuration due to the device being busy.  Handle this case by
disconnection the interfaces, then trying again.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 usb-linux.c |   36 +++-
 1 files changed, 35 insertions(+), 1 deletions(-)

diff --git a/usb-linux.c b/usb-linux.c
index ff1a29c..7d4d1d7 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -485,6 +485,26 @@ static int usb_host_disconnect_ifaces(USBHostDevice *dev, 
int nb_interfaces)
 return 0;
 }
 
+static int usb_linux_get_num_interfaces(USBHostDevice *s)
+{
+char device_name[64], line[1024];
+int num_interfaces = 0;
+
+if (usb_fs_type != USB_FS_SYS) {
+return -1;
+}
+
+sprintf(device_name, %d-%s, s-bus_num, s-port);
+if (!usb_host_read_file(line, sizeof(line), bNumInterfaces,
+device_name)) {
+return -1;
+}
+if (sscanf(line, %d, num_interfaces) != 1) {
+return -1;
+}
+return num_interfaces;
+}
+
 static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration)
 {
 const char *op = NULL;
@@ -901,14 +921,28 @@ static int usb_host_set_address(USBHostDevice *s, int 
addr)
 
 static int usb_host_set_config(USBHostDevice *s, int config)
 {
+int ret, first = 1;
+
 trace_usb_host_set_config(s-bus_num, s-addr, config);
 
 usb_host_release_interfaces(s);
 
-int ret = ioctl(s-fd, USBDEVFS_SETCONFIGURATION, config);
+again:
+ret = ioctl(s-fd, USBDEVFS_SETCONFIGURATION, config);
 
 DPRINTF(husb: ctrl set config %d ret %d errno %d\n, config, ret, errno);
 
+if (ret  0  errno == EBUSY  first) {
+/* happens if usb device is in use by host drivers */
+int count = usb_linux_get_num_interfaces(s);
+if (count  0) {
+DPRINTF(husb: busy - disconnecting %d interfaces\n, count);
+usb_host_disconnect_ifaces(s, count);
+first = 0;
+goto again;
+}
+}
+
 if (ret  0) {
 return ctrl_error();
 }
-- 
1.7.1




[Qemu-devel] [PATCH 26/35] scsi-generic: look at host status

2011-10-13 Thread Paolo Bonzini
Pass down the host status so that failing transport can be detected
by the guest.  Similar treatment of host status could be done in
virtio-blk, too.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-generic.c |   20 
 1 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 9043eea..787c581 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -39,8 +39,13 @@ do { fprintf(stderr, scsi-generic:  fmt , ## __VA_ARGS__); 
} while (0)
 
 #define SCSI_SENSE_BUF_SIZE 96
 
-#define SG_ERR_DRIVER_TIMEOUT 0x06
-#define SG_ERR_DRIVER_SENSE 0x08
+#define SG_ERR_DRIVER_TIMEOUT  0x06
+#define SG_ERR_DRIVER_SENSE0x08
+
+#define SG_ERR_DID_OK  0x00
+#define SG_ERR_DID_NO_CONNECT  0x01
+#define SG_ERR_DID_BUS_BUSY0x02
+#define SG_ERR_DID_TIME_OUT0x03
 
 #ifndef MAX_UINT
 #define MAX_UINT ((unsigned int)-1)
@@ -68,8 +73,9 @@ static void scsi_command_complete(void *opaque, int ret)
 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
 
 r-req.aiocb = NULL;
-if (r-io_header.driver_status  SG_ERR_DRIVER_SENSE)
+if (r-io_header.driver_status  SG_ERR_DRIVER_SENSE) {
 r-req.sense_len = r-io_header.sb_len_wr;
+}
 
 if (ret != 0) {
 switch (ret) {
@@ -86,9 +92,15 @@ static void scsi_command_complete(void *opaque, int ret)
 break;
 }
 } else {
-if (r-io_header.driver_status  SG_ERR_DRIVER_TIMEOUT) {
+if (r-io_header.host_status == SG_ERR_DID_NO_CONNECT ||
+r-io_header.host_status == SG_ERR_DID_BUS_BUSY ||
+r-io_header.host_status == SG_ERR_DID_TIME_OUT ||
+(r-io_header.driver_status  SG_ERR_DRIVER_TIMEOUT)) {
 status = BUSY;
 BADF(Driver Timeout\n);
+} else if (r-io_header.host_status) {
+status = CHECK_CONDITION;
+scsi_req_build_sense(r-req, SENSE_CODE(I_T_NEXUS_LOSS));
 } else if (r-io_header.status) {
 status = r-io_header.status;
 } else if (r-io_header.driver_status  SG_ERR_DRIVER_SENSE) {
-- 
1.7.6





[Qemu-devel] [PATCH 11/11] audio: make mixemu mandatory

2011-10-13 Thread Marc-André Lureau
- we need the QEMU_HDA_AMP_CAPS for Spice to handle the volume of HDA

- without MIXEMU, volume control on the guest just feels wrong because
  it has no effect (when it is not applied by the guest)

- after all, it's the role of qemu to emulate devices, and volume
  effect shouldn't be excluded
---
 audio/mixeng.c |6 --
 configure  |8 
 hw/hda-audio.c |4 
 3 files changed, 0 insertions(+), 18 deletions(-)

diff --git a/audio/mixeng.c b/audio/mixeng.c
index 5446be6..0b060e3 100644
--- a/audio/mixeng.c
+++ b/audio/mixeng.c
@@ -336,7 +336,6 @@ void mixeng_clear (struct st_sample *buf, int len)
 
 void mixeng_volume (struct st_sample *buf, int len, struct mixeng_volume *vol)
 {
-#ifdef CONFIG_MIXEMU
 if (vol-mute) {
 mixeng_clear (buf, len);
 return;
@@ -352,9 +351,4 @@ void mixeng_volume (struct st_sample *buf, int len, struct 
mixeng_volume *vol)
 #endif
 buf += 1;
 }
-#else
-(void) buf;
-(void) len;
-(void) vol;
-#endif
 }
diff --git a/configure b/configure
index 4278eb1..eadea22 100755
--- a/configure
+++ b/configure
@@ -165,7 +165,6 @@ darwin_user=no
 bsd_user=no
 guest_base=
 uname_release=
-mixemu=no
 aix=no
 blobs=yes
 pkgversion=
@@ -716,8 +715,6 @@ for opt do
   ;;
   --enable-nptl) nptl=yes
   ;;
-  --enable-mixemu) mixemu=yes
-  ;;
   --disable-linux-aio) linux_aio=no
   ;;
   --enable-linux-aio) linux_aio=yes
@@ -967,7 +964,6 @@ echo   --audio-card-list=LIST   set list of emulated audio 
cards [$audio_card_l
 echoAvailable cards: $audio_possible_cards
 echo   --block-drv-whitelist=L  set block driver whitelist
 echo(affects only QEMU, not qemu-img)
-echo   --enable-mixemu  enable mixer emulation
 echo   --disable-xendisable xen backend driver support
 echo   --enable-xen enable xen backend driver support
 echo   --disable-brlapi disable BrlAPI
@@ -2687,7 +2683,6 @@ echo mingw32 support   $mingw32
 echo Audio drivers $audio_drv_list
 echo Extra audio cards $audio_card_list
 echo Block whitelist   $block_drv_whitelist
-echo Mixer emulation   $mixemu
 echo VNC support   $vnc
 if test $vnc = yes ; then
 echo VNC TLS support   $vnc_tls
@@ -2848,9 +2843,6 @@ if test $audio_win_int = yes ; then
   echo CONFIG_AUDIO_WIN_INT=y  $config_host_mak
 fi
 echo CONFIG_BDRV_WHITELIST=$block_drv_whitelist  $config_host_mak
-if test $mixemu = yes ; then
-  echo CONFIG_MIXEMU=y  $config_host_mak
-fi
 if test $vnc = yes ; then
   echo CONFIG_VNC=y  $config_host_mak
 fi
diff --git a/hw/hda-audio.c b/hw/hda-audio.c
index c699d6f..03c0a24 100644
--- a/hw/hda-audio.c
+++ b/hw/hda-audio.c
@@ -121,15 +121,11 @@ static void hda_codec_parse_fmt(uint32_t format, struct 
audsettings *as)
 #define QEMU_HDA_AMP_NONE(0)
 #define QEMU_HDA_AMP_STEPS   0x4a
 
-#ifdef CONFIG_MIXEMU
 #define QEMU_HDA_AMP_CAPS   \
 (AC_AMPCAP_MUTE |   \
  (QEMU_HDA_AMP_STEPS  AC_AMPCAP_OFFSET_SHIFT)|\
  (QEMU_HDA_AMP_STEPS  AC_AMPCAP_NUM_STEPS_SHIFT) |\
  (3   AC_AMPCAP_STEP_SIZE_SHIFT))
-#else
-#define QEMU_HDA_AMP_CAPSQEMU_HDA_AMP_NONE
-#endif
 
 /* common: audio output widget */
 static const desc_param common_params_audio_dac[] = {
-- 
1.7.6.2




[Qemu-devel] [PATCH 09/11] configure: pa_simple is not needed anymore

2011-10-13 Thread Marc-André Lureau
---
 configure |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/configure b/configure
index c3044c7..4278eb1 100755
--- a/configure
+++ b/configure
@@ -1682,9 +1682,9 @@ for drv in $audio_drv_list; do
 ;;
 
 pa)
-audio_drv_probe $drv pulse/simple.h -lpulse-simple -lpulse \
-pa_simple *s = 0; pa_simple_free(s); return 0;
-libs_softmmu=-lpulse -lpulse-simple $libs_softmmu
+audio_drv_probe $drv pulse/mainloop.h -lpulse \
+pa_mainloop *m = 0; pa_mainloop_free (m); return 0;
+libs_softmmu=-lpulse $libs_softmmu
 audio_pt_int=yes
 ;;
 
-- 
1.7.6.2




[Qemu-devel] [PATCH 32/35] scsi: make reqops static const

2011-10-13 Thread Paolo Bonzini
Also delete a stale occurrence of SCSIReqOps inside SCSIDeviceInfo.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-bus.c |   10 +-
 hw/scsi-disk.c|2 +-
 hw/scsi-generic.c |2 +-
 hw/scsi.h |7 +++
 4 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index bdd6e94..252e903 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -160,7 +160,7 @@ static int32_t scsi_invalid_command(SCSIRequest *req, 
uint8_t *buf)
 return 0;
 }
 
-struct SCSIReqOps reqops_invalid_opcode = {
+static const struct SCSIReqOps reqops_invalid_opcode = {
 .size = sizeof(SCSIRequest),
 .send_command = scsi_invalid_command
 };
@@ -178,7 +178,7 @@ static int32_t scsi_unit_attention(SCSIRequest *req, 
uint8_t *buf)
 return 0;
 }
 
-struct SCSIReqOps reqops_unit_attention = {
+static const struct SCSIReqOps reqops_unit_attention = {
 .size = sizeof(SCSIRequest),
 .send_command = scsi_unit_attention
 };
@@ -386,7 +386,7 @@ static uint8_t *scsi_target_get_buf(SCSIRequest *req)
 return r-buf;
 }
 
-struct SCSIReqOps reqops_target_command = {
+static const struct SCSIReqOps reqops_target_command = {
 .size = sizeof(SCSITargetReq),
 .send_command = scsi_target_send_command,
 .read_data= scsi_target_read_data,
@@ -394,8 +394,8 @@ struct SCSIReqOps reqops_target_command = {
 };
 
 
-SCSIRequest *scsi_req_alloc(SCSIReqOps *reqops, SCSIDevice *d, uint32_t tag,
-uint32_t lun, void *hba_private)
+SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d,
+uint32_t tag, uint32_t lun, void *hba_private)
 {
 SCSIRequest *req;
 
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 26aa46a..90676fe 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1581,7 +1581,7 @@ static int scsi_disk_initfn(SCSIDevice *dev)
 }
 }
 
-static SCSIReqOps scsi_disk_reqops = {
+static const SCSIReqOps scsi_disk_reqops = {
 .size = sizeof(SCSIDiskReq),
 .free_req = scsi_free_request,
 .send_command = scsi_send_command,
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 06089ab..abe92fa 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -407,7 +407,7 @@ static int scsi_generic_initfn(SCSIDevice *s)
 return 0;
 }
 
-static SCSIReqOps scsi_generic_req_ops = {
+static const SCSIReqOps scsi_generic_req_ops = {
 .size = sizeof(SCSIGenericReq),
 .free_req = scsi_free_request,
 .send_command = scsi_send_command,
diff --git a/hw/scsi.h b/hw/scsi.h
index d56e875..af558c3 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -41,7 +41,7 @@ struct SCSICommand {
 struct SCSIRequest {
 SCSIBus   *bus;
 SCSIDevice*dev;
-SCSIReqOps*ops;
+const SCSIReqOps  *ops;
 uint32_t  refcount;
 uint32_t  tag;
 uint32_t  lun;
@@ -96,7 +96,6 @@ struct SCSIDeviceInfo {
 SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
   void *hba_private);
 void (*unit_attention_reported)(SCSIDevice *s);
-SCSIReqOps reqops;
 };
 
 struct SCSIBusInfo {
@@ -176,8 +175,8 @@ extern const struct SCSISense 
sense_code_DEVICE_INTERNAL_RESET;
 
 int scsi_sense_valid(SCSISense sense);
 
-SCSIRequest *scsi_req_alloc(SCSIReqOps *reqops, SCSIDevice *d, uint32_t tag,
-uint32_t lun, void *hba_private);
+SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d,
+uint32_t tag, uint32_t lun, void *hba_private);
 SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
   uint8_t *buf, void *hba_private);
 int32_t scsi_req_enqueue(SCSIRequest *req);
-- 
1.7.6





[Qemu-devel] [PATCH 08/11] audio: use full PulseAudio API, largely adapted from pa_simple*

2011-10-13 Thread Marc-André Lureau
Unfortunately, pa_simple is a very limited API which doesn't let
us retrieve the associated pa_stream. It is needed to control the
volume of the stream.
---
 audio/paaudio.c |  356 +--
 1 files changed, 318 insertions(+), 38 deletions(-)

diff --git a/audio/paaudio.c b/audio/paaudio.c
index d1f3912..beed434 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -2,8 +2,7 @@
 #include qemu-common.h
 #include audio.h
 
-#include pulse/simple.h
-#include pulse/error.h
+#include pulse/pulseaudio.h
 
 #define AUDIO_CAP pulseaudio
 #include audio_int.h
@@ -15,7 +14,7 @@ typedef struct {
 int live;
 int decr;
 int rpos;
-pa_simple *s;
+pa_stream *stream;
 void *pcm_buf;
 struct audio_pt pt;
 } PAVoiceOut;
@@ -26,17 +25,23 @@ typedef struct {
 int dead;
 int incr;
 int wpos;
-pa_simple *s;
+pa_stream *stream;
 void *pcm_buf;
 struct audio_pt pt;
+const void *read_data;
+size_t read_index, read_length;
 } PAVoiceIn;
 
-static struct {
+typedef struct {
 int samples;
 char *server;
 char *sink;
 char *source;
-} conf = {
+pa_threaded_mainloop *mainloop;
+pa_context *context;
+} paaudio;
+
+static paaudio glob_paaudio = {
 .samples = 4096,
 };
 
@@ -51,6 +56,120 @@ static void GCC_FMT_ATTR (2, 3) qpa_logerr (int err, const 
char *fmt, ...)
 AUD_log (AUDIO_CAP, Reason: %s\n, pa_strerror (err));
 }
 
+#define CHECK_SUCCESS_GOTO(c, rerror, expression, label)\
+do {\
+if (!(expression)) {\
+if (rerror) \
+*(rerror) = pa_context_errno((c)-context); \
+goto label; \
+}   \
+} while(0);
+
+#define CHECK_DEAD_GOTO(c, stream, rerror, label)   \
+do {\
+if (!(c)-context || 
!PA_CONTEXT_IS_GOOD(pa_context_get_state((c)-context)) || \
+!(stream) || !PA_STREAM_IS_GOOD(pa_stream_get_state((stream { \
+if (((c)-context  pa_context_get_state((c)-context) == 
PA_CONTEXT_FAILED) || \
+((stream)  pa_stream_get_state((stream)) == 
PA_STREAM_FAILED)) { \
+if (rerror) \
+*(rerror) = pa_context_errno((c)-context); \
+} else  \
+if (rerror) \
+*(rerror) = PA_ERR_BADSTATE;\
+goto label; \
+}   \
+} while(0);
+
+static int qpa_simple_read (PAVoiceIn *p, void *data, size_t length, int 
*rerror)
+{
+paaudio *g = glob_paaudio;
+
+pa_threaded_mainloop_lock (g-mainloop);
+
+CHECK_DEAD_GOTO (g, p-stream, rerror, unlock_and_fail);
+
+while (length  0) {
+size_t l;
+
+while (!p-read_data) {
+int r;
+
+r = pa_stream_peek (p-stream, p-read_data, p-read_length);
+CHECK_SUCCESS_GOTO (g, rerror, r == 0, unlock_and_fail);
+
+if (!p-read_data) {
+pa_threaded_mainloop_wait (g-mainloop);
+CHECK_DEAD_GOTO (g, p-stream, rerror, unlock_and_fail);
+} else
+p-read_index = 0;
+}
+
+l = p-read_length  length ? p-read_length : length;
+memcpy (data, (const uint8_t*) p-read_data+p-read_index, l);
+
+data = (uint8_t*) data + l;
+length -= l;
+
+p-read_index += l;
+p-read_length -= l;
+
+if (!p-read_length) {
+int r;
+
+r = pa_stream_drop (p-stream);
+p-read_data = NULL;
+p-read_length = 0;
+p-read_index = 0;
+
+CHECK_SUCCESS_GOTO (g, rerror, r == 0, unlock_and_fail);
+}
+}
+
+pa_threaded_mainloop_unlock (g-mainloop);
+return 0;
+
+unlock_and_fail:
+pa_threaded_mainloop_unlock (g-mainloop);
+return -1;
+}
+
+static int qpa_simple_write (PAVoiceOut *p, const void *data, size_t length, 
int *rerror)
+{
+paaudio *g = glob_paaudio;
+
+pa_threaded_mainloop_lock(g-mainloop);
+
+CHECK_DEAD_GOTO (g, p-stream, rerror, unlock_and_fail);
+
+while (length  0) {
+size_t l;
+int r;
+
+while (!(l = pa_stream_writable_size (p-stream))) {
+pa_threaded_mainloop_wait (g-mainloop);
+CHECK_DEAD_GOTO (g, p-stream, rerror, unlock_and_fail);
+}
+
+CHECK_SUCCESS_GOTO (g, rerror, l != (size_t) -1, unlock_and_fail);
+
+if (l  length)
+l = 

[Qemu-devel] [PATCH 11/35] scsi-disk: support READ DVD STRUCTURE

2011-10-13 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-disk.c |  101 +++-
 1 files changed, 100 insertions(+), 1 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 1786c37..14db6a0 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -576,10 +576,109 @@ static inline bool media_is_dvd(SCSIDiskState *s)
 return nb_sectors  CD_MAX_SECTORS;
 }
 
+static inline bool media_is_cd(SCSIDiskState *s)
+{
+uint64_t nb_sectors;
+if (s-qdev.type != TYPE_ROM) {
+return false;
+}
+if (!bdrv_is_inserted(s-bs)) {
+return false;
+}
+bdrv_get_geometry(s-bs, nb_sectors);
+return nb_sectors = CD_MAX_SECTORS;
+}
+
 static int scsi_read_dvd_structure(SCSIDiskState *s, SCSIDiskReq *r,
uint8_t *outbuf)
 {
-scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
+static const int rds_caps_size[5] = {
+[0] = 2048 + 4,
+[1] = 4 + 4,
+[3] = 188 + 4,
+[4] = 2048 + 4,
+};
+
+uint8_t media = r-req.cmd.buf[1];
+uint8_t layer = r-req.cmd.buf[6];
+uint8_t format = r-req.cmd.buf[7];
+int size = -1;
+
+if (s-qdev.type != TYPE_ROM || !bdrv_is_inserted(s-bs)) {
+return -1;
+}
+if (s-tray_open || !bdrv_is_inserted(s-bs)) {
+scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
+return -1;
+}
+if (media_is_cd(s)) {
+scsi_check_condition(r, SENSE_CODE(INCOMPATIBLE_FORMAT));
+return -1;
+}
+if (media != 0) {
+scsi_check_condition(r, SENSE_CODE(INCOMPATIBLE_FORMAT));
+return -1;
+}
+
+if (format != 0xff) {
+if (format = sizeof(rds_caps_size) / sizeof(rds_caps_size[0])) {
+return -1;
+}
+size = rds_caps_size[format];
+memset(outbuf, 0, size);
+}
+
+switch (format) {
+case 0x00: {
+/* Physical format information */
+uint64_t nb_sectors;
+if (layer != 0)
+goto fail;
+bdrv_get_geometry(s-bs, nb_sectors);
+
+outbuf[4] = 1;   /* DVD-ROM, part version 1 */
+outbuf[5] = 0xf; /* 120mm disc, minimum rate unspecified */
+outbuf[6] = 1;   /* one layer, read-only (per MMC-2 spec) */
+outbuf[7] = 0;   /* default densities */
+
+stl_be_p(outbuf[12], (nb_sectors  2) - 1); /* end sector */
+stl_be_p(outbuf[16], (nb_sectors  2) - 1); /* l0 end sector */
+break;
+}
+
+case 0x01: /* DVD copyright information, all zeros */
+break;
+
+case 0x03: /* BCA information - invalid field for no BCA info */
+return -1;
+
+case 0x04: /* DVD disc manufacturing information, all zeros */
+break;
+
+case 0xff: { /* List capabilities */
+int i;
+size = 4;
+for (i = 0; i  sizeof(rds_caps_size) / sizeof(rds_caps_size[0]); i++) 
{
+if (!rds_caps_size[i]) {
+continue;
+}
+outbuf[size] = i;
+outbuf[size + 1] = 0x40; /* Not writable, readable */
+stw_be_p(outbuf[size + 2], rds_caps_size[i]);
+size += 4;
+}
+break;
+ }
+
+default:
+return -1;
+}
+
+/* Size of buffer, not including 2 byte size field */
+stw_be_p(outbuf, size - 2);
+return size;
+
+fail:
 return -1;
 }
 
-- 
1.7.6





[Qemu-devel] [PATCH 03/11] audio: use a nominal volume of 1^32-1

2011-10-13 Thread Marc-André Lureau
So we can easily fit it into smaller int.

We can just 16 to fit it into a 16bits volume range for example.
---
 audio/audio.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/audio/audio.c b/audio/audio.c
index f830bb2..33b6c23 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -110,8 +110,8 @@ const struct mixeng_volume nominal_volume = {
 .r = 1.0,
 .l = 1.0,
 #else
-.r = 1ULL  32,
-.l = 1ULL  32,
+.r = (1ULL  32) - 1,
+.l = (1ULL  32) - 1,
 #endif
 };
 
-- 
1.7.6.2




[Qemu-devel] [PATCH 14/35] qdev: switch children device list to QTAILQ

2011-10-13 Thread Paolo Bonzini
SCSI buses will need to read the children list first-to-last.  This
requires using a QTAILQ, because hell breaks loose if you just try
inserting at the tail (thus reversing the order of all existing
visits from last-to-first to first-to-tail).

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/acpi_piix4.c  |4 ++--
 hw/i2c.c |2 +-
 hw/intel-hda.c   |6 +++---
 hw/qdev.c|   24 
 hw/qdev.h|4 ++--
 hw/s390-virtio-bus.c |4 ++--
 hw/spapr_vio.c   |6 +++---
 hw/ssi.c |6 +++---
 8 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 29f0f76..d9075e6 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -276,7 +276,7 @@ static void piix4_update_hotplug(PIIX4PMState *s)
 
 s-pci0_hotplug_enable = ~0;
 
-QLIST_FOREACH_SAFE(qdev, bus-children, sibling, next) {
+QTAILQ_FOREACH_SAFE(qdev, bus-children, sibling, next) {
 PCIDeviceInfo *info = container_of(qdev-info, PCIDeviceInfo, qdev);
 PCIDevice *pdev = DO_UPCAST(PCIDevice, qdev, qdev);
 int slot = PCI_SLOT(pdev-devfn);
@@ -486,7 +486,7 @@ static void pciej_write(void *opaque, uint32_t addr, 
uint32_t val)
 PCIDeviceInfo *info;
 int slot = ffs(val) - 1;
 
-QLIST_FOREACH_SAFE(qdev, bus-children, sibling, next) {
+QTAILQ_FOREACH_SAFE(qdev, bus-children, sibling, next) {
 dev = DO_UPCAST(PCIDevice, qdev, qdev);
 info = container_of(qdev-info, PCIDeviceInfo, qdev);
 if (PCI_SLOT(dev-devfn) == slot  !info-no_hotplug) {
diff --git a/hw/i2c.c b/hw/i2c.c
index 49b9ecb..9bcf3e1 100644
--- a/hw/i2c.c
+++ b/hw/i2c.c
@@ -84,7 +84,7 @@ int i2c_start_transfer(i2c_bus *bus, uint8_t address, int 
recv)
 DeviceState *qdev;
 i2c_slave *slave = NULL;
 
-QLIST_FOREACH(qdev, bus-qbus.children, sibling) {
+QTAILQ_FOREACH(qdev, bus-qbus.children, sibling) {
 i2c_slave *candidate = I2C_SLAVE_FROM_QDEV(qdev);
 if (candidate-address == address) {
 slave = candidate;
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 4272204..c4e8c51 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -86,7 +86,7 @@ HDACodecDevice *hda_codec_find(HDACodecBus *bus, uint32_t cad)
 DeviceState *qdev;
 HDACodecDevice *cdev;
 
-QLIST_FOREACH(qdev, bus-qbus.children, sibling) {
+QTAILQ_FOREACH(qdev, bus-qbus.children, sibling) {
 cdev = DO_UPCAST(HDACodecDevice, qdev, qdev);
 if (cdev-cad == cad) {
 return cdev;
@@ -489,7 +489,7 @@ static void intel_hda_notify_codecs(IntelHDAState *d, 
uint32_t stream, bool runn
 DeviceState *qdev;
 HDACodecDevice *cdev;
 
-QLIST_FOREACH(qdev, d-codecs.qbus.children, sibling) {
+QTAILQ_FOREACH(qdev, d-codecs.qbus.children, sibling) {
 cdev = DO_UPCAST(HDACodecDevice, qdev, qdev);
 if (cdev-info-stream) {
 cdev-info-stream(cdev, stream, running);
@@ -1112,7 +1112,7 @@ static void intel_hda_reset(DeviceState *dev)
 d-wall_base_ns = qemu_get_clock_ns(vm_clock);
 
 /* reset codecs */
-QLIST_FOREACH(qdev, d-codecs.qbus.children, sibling) {
+QTAILQ_FOREACH(qdev, d-codecs.qbus.children, sibling) {
 cdev = DO_UPCAST(HDACodecDevice, qdev, qdev);
 if (qdev-info-reset) {
 qdev-info-reset(qdev);
diff --git a/hw/qdev.c b/hw/qdev.c
index a223d41..50976dd 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -91,7 +91,7 @@ static DeviceState *qdev_create_from_info(BusState *bus, 
DeviceInfo *info)
 qdev_prop_set_defaults(dev, dev-info-props);
 qdev_prop_set_defaults(dev, dev-parent_bus-info-props);
 qdev_prop_set_globals(dev);
-QLIST_INSERT_HEAD(bus-children, dev, sibling);
+QTAILQ_INSERT_HEAD(bus-children, dev, sibling);
 if (qdev_hotplug) {
 assert(bus-allow_hotplug);
 dev-hotplugged = 1;
@@ -408,7 +408,7 @@ void qdev_free(DeviceState *dev)
 if (dev-opts)
 qemu_opts_del(dev-opts);
 }
-QLIST_REMOVE(dev, sibling);
+QTAILQ_REMOVE(dev-parent_bus-children, dev, sibling);
 for (prop = dev-info-props; prop  prop-name; prop++) {
 if (prop-info-free) {
 prop-info-free(dev, prop);
@@ -510,7 +510,7 @@ int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
 }
 }
 
-QLIST_FOREACH(dev, bus-children, sibling) {
+QTAILQ_FOREACH(dev, bus-children, sibling) {
 err = qdev_walk_children(dev, devfn, busfn, opaque);
 if (err  0) {
 return err;
@@ -560,7 +560,7 @@ static BusState *qbus_find_recursive(BusState *bus, const 
char *name,
 return bus;
 }
 
-QLIST_FOREACH(dev, bus-children, sibling) {
+QTAILQ_FOREACH(dev, bus-children, sibling) {
 QLIST_FOREACH(child, dev-child_bus, sibling) {
 ret = qbus_find_recursive(child, name, info);
 if (ret) {
@@ -576,7 +576,7 @@ DeviceState *qdev_find_recursive(BusState *bus, const 

Re: [Qemu-devel] 2 MiB alignment in qemu_vmalloc()

2011-10-13 Thread Paolo Bonzini

On 10/13/2011 09:56 AM, Gerd Hoffmann wrote:


Is there some way for apps to figure they are running in valgrind?
Then we could choose a different alignment automagically.


Yes, valgrind.h (on RH distros that's in package valgrind-devel; there 
is a valgrind.pc file to add the correct include path) provides a 
RUNNING_ON_VALGRIND macro.


Paolo




[Qemu-devel] [PATCH 02/35] atapi/scsi: unify definitions for MMC

2011-10-13 Thread Paolo Bonzini
The definitions in ide/internal.h are duplicates, since ATAPI commands
actually come from SCSI.  Use the ones in scsi-defs.h and move the
missing ones there.  Two exceptions:

- MODE_PAGE_WRITE_PARMS conflicts with the flexible disk geometry
page in scsi-disk.c.  It is unused, so pick the latter.

- GPCMD_* is left in ide/internal.h, at least for now.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/ide/atapi.c|   52 +++---
 hw/ide/core.c |4 +-
 hw/ide/internal.h |   71 +
 hw/ide/macio.c|2 +-
 hw/scsi-bus.c |2 +-
 hw/scsi-defs.h|   66 +
 hw/scsi-disk.c|8 +++---
 7 files changed, 101 insertions(+), 104 deletions(-)

diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index 3f909c3..be3b728 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -154,10 +154,10 @@ void ide_atapi_io_error(IDEState *s, int ret)
 {
 /* XXX: handle more errors */
 if (ret == -ENOMEDIUM) {
-ide_atapi_cmd_error(s, SENSE_NOT_READY,
+ide_atapi_cmd_error(s, NOT_READY,
 ASC_MEDIUM_NOT_PRESENT);
 } else {
-ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+ide_atapi_cmd_error(s, ILLEGAL_REQUEST,
 ASC_LOGICAL_BLOCK_OOR);
 }
 }
@@ -282,7 +282,7 @@ static void ide_atapi_cmd_check_status(IDEState *s)
 #ifdef DEBUG_IDE_ATAPI
 printf(atapi_cmd_check_status\n);
 #endif
-s-error = MC_ERR | (SENSE_UNIT_ATTENTION  4);
+s-error = MC_ERR | (UNIT_ATTENTION  4);
 s-status = ERR_STAT;
 s-nsector = 0;
 ide_set_irq(s-bus);
@@ -354,7 +354,7 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
ide_atapi_cmd_read_dma_cb, s);
 if (!s-bus-dma-aiocb) {
 /* Note: media not present is the most likely case */
-ide_atapi_cmd_error(s, SENSE_NOT_READY,
+ide_atapi_cmd_error(s, NOT_READY,
 ASC_MEDIUM_NOT_PRESENT);
 goto eot;
 }
@@ -595,7 +595,7 @@ static void cmd_get_event_status_notification(IDEState *s,
 /* It is fine by the MMC spec to not support async mode operations */
 if (!(gesn_cdb-polled  0x01)) { /* asynchronous mode */
 /* Only polling is supported, asynchronous mode is not. */
-ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+ide_atapi_cmd_error(s, ILLEGAL_REQUEST,
 ASC_INV_FIELD_IN_CMD_PACKET);
 return;
 }
@@ -643,8 +643,8 @@ static void cmd_request_sense(IDEState *s, uint8_t *buf)
 buf[7] = 10;
 buf[12] = s-asc;
 
-if (s-sense_key == SENSE_UNIT_ATTENTION) {
-s-sense_key = SENSE_NONE;
+if (s-sense_key == UNIT_ATTENTION) {
+s-sense_key = NO_SENSE;
 }
 
 ide_atapi_cmd_reply(s, 18, max_len);
@@ -676,7 +676,7 @@ static void cmd_get_configuration(IDEState *s, uint8_t *buf)
 
 /* only feature 0 is supported */
 if (buf[2] != 0 || buf[3] != 0) {
-ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+ide_atapi_cmd_error(s, ILLEGAL_REQUEST,
 ASC_INV_FIELD_IN_CMD_PACKET);
 return;
 }
@@ -733,7 +733,7 @@ static void cmd_mode_sense(IDEState *s, uint8_t *buf)
 switch(action) {
 case 0: /* current values */
 switch(code) {
-case GPMODE_R_W_ERROR_PAGE: /* error recovery */
+case MODE_PAGE_R_W_ERROR: /* error recovery */
 cpu_to_ube16(buf[0], 16 + 6);
 buf[2] = 0x70;
 buf[3] = 0;
@@ -752,7 +752,7 @@ static void cmd_mode_sense(IDEState *s, uint8_t *buf)
 buf[15] = 0x00;
 ide_atapi_cmd_reply(s, 16, max_len);
 break;
-case GPMODE_AUDIO_CTL_PAGE:
+case MODE_PAGE_AUDIO_CTL:
 cpu_to_ube16(buf[0], 24 + 6);
 buf[2] = 0x70;
 buf[3] = 0;
@@ -769,7 +769,7 @@ static void cmd_mode_sense(IDEState *s, uint8_t *buf)
 
 ide_atapi_cmd_reply(s, 24, max_len);
 break;
-case GPMODE_CAPABILITIES_PAGE:
+case MODE_PAGE_CAPABILITIES:
 cpu_to_ube16(buf[0], 28 + 6);
 buf[2] = 0x70;
 buf[3] = 0;
@@ -813,14 +813,14 @@ static void cmd_mode_sense(IDEState *s, uint8_t *buf)
 goto error_cmd;
 default:
 case 3: /* saved values */
-ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
+ide_atapi_cmd_error(s, ILLEGAL_REQUEST,
 ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
 break;
 }
 return;
 
 error_cmd:
-ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
+ide_atapi_cmd_error(s, ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
 }
 
 static void cmd_test_unit_ready(IDEState *s, uint8_t *buf)
@@ -883,7 +883,7 @@ static void cmd_read_cd(IDEState *s, uint8_t* buf)
 ide_atapi_cmd_read(s, lba, nb_sectors, 2352);
   

[Qemu-devel] [PATCH 30/35] scsi-disk: small clean up to INQUIRY

2011-10-13 Thread Paolo Bonzini
Set s-removable, s-qdev.blocksize and s-qdev.type in the callers
of scsi_initfn.

With this in place, s-qdev.type is allowed, and we can just reuse it
as the first byte in VPD data (just like we do in standard INQUIRY data).
Also set s-removable is set consistently and we can use it.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 hw/scsi-disk.c |   46 +-
 1 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 7f2f67f..cc3998e 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -394,11 +394,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, 
uint8_t *outbuf)
 return -1;
 }
 
-if (s-qdev.type == TYPE_ROM) {
-outbuf[buflen++] = 5;
-} else {
-outbuf[buflen++] = 0;
-}
+outbuf[buflen++] = s-qdev.type  0x1f;
 outbuf[buflen++] = page_code ; // this page
 outbuf[buflen++] = 0x00;
 
@@ -538,11 +534,10 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, 
uint8_t *outbuf)
 memset(outbuf, 0, buflen);
 
 outbuf[0] = s-qdev.type  0x1f;
+outbuf[1] = s-removable ? 0x80 : 0;
 if (s-qdev.type == TYPE_ROM) {
-outbuf[1] = 0x80;
 memcpy(outbuf[16], QEMU CD-ROM , 16);
 } else {
-outbuf[1] = s-removable ? 0x80 : 0;
 memcpy(outbuf[16], QEMU HARDDISK   , 16);
 }
 memcpy(outbuf[8], QEMU, 8);
@@ -1511,7 +1506,7 @@ static void scsi_disk_unit_attention_reported(SCSIDevice 
*dev)
 }
 }
 
-static int scsi_initfn(SCSIDevice *dev, uint8_t scsi_type)
+static int scsi_initfn(SCSIDevice *dev)
 {
 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
 DriveInfo *dinfo;
@@ -1521,7 +1516,7 @@ static int scsi_initfn(SCSIDevice *dev, uint8_t scsi_type)
 return -1;
 }
 
-if (scsi_type == TYPE_DISK  !bdrv_is_inserted(s-qdev.conf.bs)) {
+if (!s-removable  !bdrv_is_inserted(s-qdev.conf.bs)) {
 error_report(Device needs media, but drive is empty);
 return -1;
 }
@@ -1543,18 +1538,11 @@ static int scsi_initfn(SCSIDevice *dev, uint8_t 
scsi_type)
 return -1;
 }
 
-if (scsi_type == TYPE_ROM) {
+if (s-removable) {
 bdrv_set_dev_ops(s-qdev.conf.bs, scsi_cd_block_ops, s);
-s-qdev.blocksize = 2048;
-} else if (scsi_type == TYPE_DISK) {
-s-qdev.blocksize = s-qdev.conf.logical_block_size;
-} else {
-error_report(scsi-disk: Unhandled SCSI type %02x, scsi_type);
-return -1;
 }
 bdrv_set_buffer_alignment(s-qdev.conf.bs, s-qdev.blocksize);
 
-s-qdev.type = scsi_type;
 qemu_add_vm_change_state_handler(scsi_dma_restart_cb, s);
 bdrv_iostatus_enable(s-qdev.conf.bs);
 add_boot_device_path(s-qdev.conf.bootindex, dev-qdev, ,0);
@@ -1563,27 +1551,35 @@ static int scsi_initfn(SCSIDevice *dev, uint8_t 
scsi_type)
 
 static int scsi_hd_initfn(SCSIDevice *dev)
 {
-return scsi_initfn(dev, TYPE_DISK);
+SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
+s-qdev.blocksize = s-qdev.conf.logical_block_size;
+s-qdev.type = TYPE_DISK;
+return scsi_initfn(s-qdev);
 }
 
 static int scsi_cd_initfn(SCSIDevice *dev)
 {
-return scsi_initfn(dev, TYPE_ROM);
+SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
+s-qdev.blocksize = 2048;
+s-qdev.type = TYPE_ROM;
+s-removable = true;
+return scsi_initfn(s-qdev);
 }
 
 static int scsi_disk_initfn(SCSIDevice *dev)
 {
 DriveInfo *dinfo;
-uint8_t scsi_type;
 
 if (!dev-conf.bs) {
-scsi_type = TYPE_DISK;  /* will die in scsi_initfn() */
-} else {
-dinfo = drive_get_by_blockdev(dev-conf.bs);
-scsi_type = dinfo-media_cd ? TYPE_ROM : TYPE_DISK;
+return scsi_initfn(dev);  /* ... and die there */
 }
 
-return scsi_initfn(dev, scsi_type);
+dinfo = drive_get_by_blockdev(dev-conf.bs);
+if (dinfo-media_cd) {
+return scsi_cd_initfn(dev);
+} else {
+return scsi_hd_initfn(dev);
+}
 }
 
 static SCSIReqOps scsi_disk_reqops = {
-- 
1.7.6





[Qemu-devel] [PATCH] linux-aio: Allow reads beyond the end of growable images

2011-10-13 Thread Kevin Wolf
This is the linux-aio version of commits 22afa7b5 (raw-posix, synchronous) and
ba1d1afd (posix-aio-compat). Reads now produce zeros after the end of file
instead of failing or resulting in short reads, making linux-aio compatible
with the behaviour of synchronous raw-posix requests and posix-aio-compat.

The problem can be reproduced like this:

dd if=/dev/zero of=/tmp/test.raw bs=1 count=1234
./qemu-io -k -n -g -c 'read -p 1024 512' /tmp/test.raw

Previously, the result of this was 'read failed: Invalid argument', now the
read completes successfully.

Signed-off-by: Kevin Wolf kw...@redhat.com
---
 linux-aio.c |   17 ++---
 1 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/linux-aio.c b/linux-aio.c
index 50da75d..1c635ef 100644
--- a/linux-aio.c
+++ b/linux-aio.c
@@ -31,6 +31,8 @@ struct qemu_laiocb {
 struct iocb iocb;
 ssize_t ret;
 size_t nbytes;
+QEMUIOVector *qiov;
+bool is_read;
 QLIST_ENTRY(qemu_laiocb) node;
 };
 
@@ -57,10 +59,17 @@ static void qemu_laio_process_completion(struct 
qemu_laio_state *s,
 
 ret = laiocb-ret;
 if (ret != -ECANCELED) {
-if (ret == laiocb-nbytes)
+if (ret == laiocb-nbytes) {
 ret = 0;
-else if (ret = 0)
-ret = -EINVAL;
+} else if (ret = 0) {
+/* Short reads mean EOF, pad with zeros. */
+if (laiocb-is_read) {
+qemu_iovec_memset_skip(laiocb-qiov, 0,
+laiocb-qiov-size - ret, ret);
+} else {
+ret = -EINVAL;
+}
+}
 
 laiocb-common.cb(laiocb-common.opaque, ret);
 }
@@ -162,6 +171,8 @@ BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void 
*aio_ctx, int fd,
 laiocb-nbytes = nb_sectors * 512;
 laiocb-ctx = s;
 laiocb-ret = -EINPROGRESS;
+laiocb-is_read = (type == QEMU_AIO_READ);
+laiocb-qiov = qiov;
 
 iocbs = laiocb-iocb;
 
-- 
1.7.6.4




Re: [Qemu-devel] [PATCH v2 0/5] block: do request processing in a coroutine

2011-10-13 Thread Kevin Wolf
Am 13.10.2011 14:08, schrieb Stefan Hajnoczi:
 Note: this version applies against Kevin's block tree
 
 Block layer features like dirty block tracing, I/O throttling, and live block
 copy are forced to duplicate code due to the three different interfaces:
 synchronous, asynchronous, and coroutines.
 
 Since there are bdrv_read(), bdrv_aio_readv(), and bdrv_co_readv() interfaces
 for read (and similar for write), per-request processing needs to be 
 duplicated
 for each of these execution contexts.  For example, dirty block tracking code
 is duplicated across these three interfaces.
 
 This patch series unifies request processing so that there is only one code
 path.  I see this as a prerequisite to the live block copy (image streaming)
 code I am working on, so I'm pushing it now.
 
 The short-term win from this series is that it becomes easy to add live block
 copy and other features.  We now have a single code path where the 
 perf-request
 processing is done.
 
 The longer-term win will be dropping the BlockDriver .bdrv_read(),
 .bdrv_write(), .bdrv_aio_readv(), and .bdrv_aio_writev() interfaces.  By doing
 that we can bring all BlockDrivers onto a common interface, namely
 .bdrv_co_readv() and .bdrv_co_writev().  It will also allow us to drop most of
 the sync and aio emulation code.
 
 A consequence of this patch series is that every I/O request goes through at
 least one coroutine.  There is no longer a direct .bdrv_read(), .bdrv_write(),
 .bdrv_aio_readv(), or .bdrv_aio_writev() call - we're trying to phase out 
 those
 interfaces.  I have not noticed performance degradation in correctness tests
 but we need to confirm that there has not been a performance regression.
 
 v2:
  * Fixed bdrv_read()/bdrv_write() infinite loop [Kevin]
 
 Stefan Hajnoczi (5):
   block: directly invoke .bdrv_* from emulation functions
   block: switch bdrv_read()/bdrv_write() to coroutines
   block: switch bdrv_aio_readv() to coroutines
   block: mark blocks dirty on coroutine write completion
   block: switch bdrv_aio_writev() to coroutines
 
  block.c |  245 --
  1 files changed, 111 insertions(+), 134 deletions(-)

Thanks, applied to the block branch.

I think there's some dead code now, but we can leave the clean-up for later.

Kevin



Re: [Qemu-devel] [PATCH] configure: Detect when glibc implements makecontext() to always fail

2011-10-13 Thread Andreas Färber

Am 12.10.2011 18:21, schrieb Peter Maydell:

Improve the configure test for presence of ucontext functions by
making linker warnings fatal; this allows us to detect when we are
linked with a glibc which implements makecontext() to always return
ENOSYS.

Signed-off-by: Peter Maydellpeter.mayd...@linaro.org


Tested-by: Andreas Färber afaer...@suse.de


---
Compiling on an Ubuntu Natty ARM host will hit this.


Works on Ubuntu Maverick ARM host as well.


(Anybody think we should clean up our configure tests so we can
enable -Werror and -Wl,--fatal-warnings on all of them?)


In theory that would be nice. I noticed for example that a missing 
glib2-devel package is not caught by configure, on openSUSE.


As a start for cleaning up...


  configure |7 +--
  1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index 9b4fe34..4d9d9e0 100755
--- a/configure
+++ b/configure
@@ -2549,9 +2549,12 @@ ucontext_coroutine=no
  if test $darwin != yes; then
cat  $TMPC  EOF
  #includeucontext.h
-int main(void) { makecontext(0, 0, 0); }
+int main(void) { makecontext(0, 0, 0); return 0; }


...we could give a good example by adopting regular multi-line Coding 
Style, like accept4() and others.


Andreas


  EOF
-  if compile_prog   ; then
+  # Note that we enable fatal linker warnings to catch the
+  # glibc makecontext is not implemented and will always fail
+  # linker warning.
+  if compile_prog -Wl,--fatal-warnings  ; then
ucontext_coroutine=yes
fi
  fi



--
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746, AG Nürnberg



Re: [Qemu-devel] [RFC PATCH v2] Specification for qcow2 version 3

2011-10-13 Thread Stefan Hajnoczi
On Wed, Oct 12, 2011 at 3:58 PM, Kevin Wolf kw...@redhat.com wrote:
 Am 12.10.2011 16:37, schrieb Stefan Hajnoczi:
 On Wed, Oct 12, 2011 at 2:31 PM, Kevin Wolf kw...@redhat.com wrote:
 Am 12.10.2011 14:51, schrieb Stefan Hajnoczi:
 Also a bit in l2 offset to say there is no l2 table cause all
 clusters in l2 are contiguous so we avoid entirely l2. Obviously this
 require an optimization step to detect or create such condition.

 There are several reserved L1 entry bits which could be used to mark
 this mode.  This mode severely restricts qcow2 features though: how
 would snapshots and COW work?  Perhaps by breaking the huge cluster
 back into an L2 table with individual clusters?  Backing files also
 cannot be used - unless we extend the sub-clusters approach and also
 keep a large bitmap with allocated/unallocated/zero information.

 A mode like this could be used for best performance on local storage,
 where efficiently image transport (e.g. scp or http) is not required.
 Actually I think this is reasonable, we could use qemu-img convert to
 produce a compact qcow2 for export and use the L2-less qcow2 for
 running the actual VM.

 Kevin: what do you think about fleshing out this mode instead of 
 sub-clusters?

 I'm hesitant to something like this as it adds quite some complexity and
 I'm not sure if there are practical use cases for it at all.

 If you take the current cluster sizes, an L2 table contains 512 MB of
 data, so you would lose any sparseness. You would probably already get
 full allocation just by creating a file system on the image.

 But even if you do have a use case where sparseness doesn't matter, the
 effect is very much the same as allowing a 512 MB cluster size and not
 changing any of the qcow2 internals.

 I guess I'm thinking of the 512 MB cluster size situation, because
 we'd definitely want a cow bitmap in order to keep backing files and
 sparseness.

 (What would the use case be? Backing files or snapshots with a COW
 granularity of 512 MB isn't going to fly. That leaves only something
 like encryption.)

 COW granularity needs to stay at 64-256 kb since those are reasonable
 request sizes for COW.

 But how do you do that without L2 tables? What you're describing
 (different sizes for allocation and COW) is exactly what subclusters are
 doing. I can't see how switching to 512 MB clusters and a single-level
 table can make that work.

Yes, very large sub-clusters are likely to provide the best performance:

1. The refcounts are incremented in a single operation when the large
cluster is allocated.
2. COW still works on smaller granularity so allocating a large
cluster does not require zeroing data.
3. Writes simply need to update the COW bitmap, no refcount updates
are required.

Stefan



Re: [Qemu-devel] [PATCH 1/2] hw/9pfs: Add new virtfs option cache=writethrough to skip host page cache

2011-10-13 Thread Stefan Hajnoczi
Reviewed-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com



Re: [Qemu-devel] balloon driver on winxp guest start failed

2011-10-13 Thread Stefan Hajnoczi
On Thu, Oct 13, 2011 at 5:00 AM, hkran hk...@vnet.linux.ibm.com wrote:
 On 10/12/2011 07:09 PM, hkran wrote:
 I used balloon driver for windows  virtio-win-0.1-15.iso (from
 http://alt.fedoraproject.org/pub/alt/virtio-win/latest/images/bin/)

 following the install guard , I installed the balloon driver like this:

 devcon.exe install d:\wxp\x86\balloon.inf
 PCI\VEN_1AF4DEV_1002SUBSYS_00051AF4REV_00
  then reboot guest Os, but the status of driver installed is always
 incorrect, that show me the driver start failed (code 10) in the device
 manager.

 I typed the following cmds in the monitor command line:

 (qemu) device_add virtio-balloon
 (qemu) info balloon
 balloon: actual=2048
 (qemu) balloon 1024
 (qemu) info balloon
 balloon: actual=2048
 (qemu) info balloon
 balloon: actual=2048

 And I also tried it by using qemu -balloon virtio param  when getting
 qemu up, the status is worse, the winxp guest froze at boot screen.

 Am I using balloon driver in a correct way?



 For the boot failure case, I take more looks into it.  I open the trace
 output and see the following when boot failed
 Balloon driver, built on Oct 13 2011 10:46:59
 ^M-- DriverEntry
 ^Mfile z:\source\kvm-guest-drivers-windows\balloon\sys\driver.c line 151
 ^M-- BalloonDeviceAdd
 ^M-- BalloonDeviceAdd
 ^M-- BalloonEvtDevicePrepareHardware
 ^M- Port   Resource [C0A0-C0C0]
 ^M-- BalloonEvtDevicePrepareHardware
 ^M-- BalloonEvtDeviceD0Entry
 ^M-- BalloonInit
 ^M-- VIRTIO_BALLOON_F_STATS_VQ
 ^M-- BalloonInit
 ^M-- BalloonInterruptEnable
 ^M-- BalloonInterruptEnable

 here, the system is blocked.

 I compare it with the logfile in the normal case that I hot-plugin the
 balloon device, and then find the system blocked before calling at
 BalloonInterruptDpc.

 Is it meaning that we open the interrupt of balloon device too soon when
 booting the system?

I suggest CCing Vadim on virtio Windows driver questions.  Not sure if
he sees every qemu-devel email.

Stefan



Re: [Qemu-devel] [PATCH] linux-aio: Allow reads beyond the end of growable images

2011-10-13 Thread Stefan Hajnoczi
On Thu, Oct 13, 2011 at 2:49 PM, Kevin Wolf kw...@redhat.com wrote:
 This is the linux-aio version of commits 22afa7b5 (raw-posix, synchronous) and
 ba1d1afd (posix-aio-compat). Reads now produce zeros after the end of file
 instead of failing or resulting in short reads, making linux-aio compatible
 with the behaviour of synchronous raw-posix requests and posix-aio-compat.

 The problem can be reproduced like this:

 dd if=/dev/zero of=/tmp/test.raw bs=1 count=1234
 ./qemu-io -k -n -g -c 'read -p 1024 512' /tmp/test.raw

 Previously, the result of this was 'read failed: Invalid argument', now the
 read completes successfully.

 Signed-off-by: Kevin Wolf kw...@redhat.com
 ---
  linux-aio.c |   17 ++---
  1 files changed, 14 insertions(+), 3 deletions(-)

Reviewed-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com



Re: [Qemu-devel] [PATCH v3 00/15] NBD improvements

2011-10-13 Thread Paolo Bonzini

On 10/05/2011 09:17 AM, Paolo Bonzini wrote:

v2-v3:
 fix comments from sheepdog maintainer

v1-v2:
 moved coroutine send/recv functions to osdep.c, added support
 for multiple in-flight requests, added support for co_discard
 and aio_discard.


FWIW, I placed a rebased version at git://github.com/bonzini/qemu.gdb 
branch nbd-trim.  It has the problem that Stefan's coroutine treatment 
is not given to co_flush and co_discard.  Can this be left for later?  I 
didn't really understand how that series worked...


Paolo



[Qemu-devel] [PATCH] KVM: Use -cpu host as default on x86

2011-10-13 Thread Alexander Graf
When running QEMU without -cpu parameter, the user usually wants a sane
default. So far, we're using the qemu64/qemu32 CPU type, which basically
means the maximum TCG can emulate.

That's a really good default when using TCG, but when running with KVM
we much rather want a default saying the maximum KVM can support.

Fortunately we already have such a CPU type. It's called host. All we
need to do is to select it by default when not getting a -cpu passed in.

This fixes a lot of subtile breakage in the GNU toolchain (libgmp) which
hicks up on QEMU's non-existent CPU models.

Signed-off-by: Alexander Graf ag...@suse.de
---
 hw/pc.c  |   10 +++---
 hw/pc.h  |2 +-
 hw/pc_piix.c |2 +-
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index 203627d..e0c48f2 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -941,17 +941,21 @@ static CPUState *pc_new_cpu(const char *cpu_model)
 return env;
 }
 
-void pc_cpus_init(const char *cpu_model)
+void pc_cpus_init(const char *cpu_model, int kvm_enabled)
 {
 int i;
 
 /* init CPUs */
 if (cpu_model == NULL) {
+if (kvm_enabled) {
+cpu_model = host;
+} else {
 #ifdef TARGET_X86_64
-cpu_model = qemu64;
+cpu_model = qemu64;
 #else
-cpu_model = qemu32;
+cpu_model = qemu32;
 #endif
+}
 }
 
 for(i = 0; i  smp_cpus; i++) {
diff --git a/hw/pc.h b/hw/pc.h
index f3e21b6..b5519ff 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -130,7 +130,7 @@ void pc_register_ferr_irq(qemu_irq irq);
 void pc_cmos_set_s3_resume(void *opaque, int irq, int level);
 void pc_acpi_smi_interrupt(void *opaque, int irq, int level);
 
-void pc_cpus_init(const char *cpu_model);
+void pc_cpus_init(const char *cpu_model, int kvm_enabled);
 void pc_memory_init(MemoryRegion *system_memory,
 const char *kernel_filename,
 const char *kernel_cmdline,
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index ce1c87f..a080191 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -99,7 +99,7 @@ static void pc_init1(MemoryRegion *system_memory,
 MemoryRegion *pci_memory;
 MemoryRegion *rom_memory;
 
-pc_cpus_init(cpu_model);
+pc_cpus_init(cpu_model, kvm_enabled());
 
 if (kvmclock_enabled) {
 kvmclock_create();
-- 
1.7.3.4




[Qemu-devel] [Bug 873460] [NEW] Likewise no sound

2011-10-13 Thread Marcus Paiva
Public bug reported:

Hi,
using fresh Ubuntu 11.10 with Likewise 6 in a MS Domain.
Domain users log with no sound.
Local users are OK.

Thx

** Affects: qemu
 Importance: Undecided
 Status: New


** Tags: 11.10 likewise ubuntu

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/873460

Title:
  Likewise no sound

Status in QEMU:
  New

Bug description:
  Hi,
  using fresh Ubuntu 11.10 with Likewise 6 in a MS Domain.
  Domain users log with no sound.
  Local users are OK.

  Thx

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/873460/+subscriptions



[Qemu-devel] [Bug 873460] Re: Likewise no sound

2011-10-13 Thread Marcus Paiva
Sry, posted in the wrong chanel.

Can I move it to https://bugs.launchpad.net/ubuntu/+source/likewise-open
?

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/873460

Title:
  Likewise no sound

Status in QEMU:
  New

Bug description:
  Hi,
  using fresh Ubuntu 11.10 with Likewise 6 in a MS Domain.
  Domain users log with no sound.
  Local users are OK.

  Thx

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/873460/+subscriptions



  1   2   >