Re: [Qemu-devel] Question about posixaio thread number.

2011-08-03 Thread Stefan Hajnoczi
On Wed, Aug 3, 2011 at 6:19 AM, Gui Jianfeng  wrote:
> When i did some io tests in Guest say dd like
> dd if=/dev/zero oflag=direct of=/mnt/sdb1/date.img bs=4k count=262114
>
> qemu will start one or several threads to perform IO requests.
>
> It seems qemu makes use of its own posixaio. I'm wondering how qemu
> decides how many threads should be created to perform io operation?

Look at posix-aio-compat.c.

If a new request comes in and there is no idle thread around, a new
thread will be spawned up to a maximum limit.

When you run a synchronous I/O workload like dd(1), expect to see only
1 or 2 aio worker threads.  If the workload is multithreaded, expect
to see many (depending on the guest's queue depth).

Stefan



Re: [Qemu-devel] [PATCH] do not call monitor_resume() from migrate_fd_put_buffer() error path

2011-08-03 Thread Michael Tokarev
So, can we decide on this somehow?  I don't see a code
path where we don't call monitor_resume at the end,
so the "intermediate" monitor_resume can be dropped.
This way we fix real bug.  If there will be other
problem from that, it can be fixed later - this will
mean that code path is found...

Should I resend the initial patch again?

Thanks,

/mjt

21.07.2011 02:06, Jan Kiszka wriote:
> On 2011-07-20 18:34, Marcelo Tosatti wrote:
>> On Tue, Jul 19, 2011 at 11:48:22PM +0200, Jan Kiszka wrote:
>>> On 2011-07-19 13:46, Michael Tokarev wrote:
 If we do, it results in double monitor_resume() (second being called
 from migrate_fd_cleanup() anyway) and monitor suspend count becoming
 negative.

 Cc'ing people from `git blame' list for the lines in question: the
 change fixes the problem but I'm not sure what the original intention
 of this code was in this place.  Unfortunately noone replied to two
 my attempts to raise this issue.

 Signed-Off-By: Michael Tokarev 
 ---
  migration.c |3 ---
  1 files changed, 0 insertions(+), 3 deletions(-)

 diff --git a/migration.c b/migration.c
 index af3a1f2..115588c 100644
 --- a/migration.c
 +++ b/migration.c
 @@ -330,9 +330,6 @@ ssize_t migrate_fd_put_buffer(void *opaque, const void 
 *data, size_t size)
  if (ret == -EAGAIN) {
  qemu_set_fd_handler2(s->fd, NULL, NULL, migrate_fd_put_notify, s);
  } else if (ret < 0) {
 -if (s->mon) {
 -monitor_resume(s->mon);
 -}
  s->state = MIG_STATE_ERROR;
  notifier_list_notify(&migration_state_notifiers);
  }
>>>
>>> Looks reasonable to me, but Marcelo should comment on this, specifically
>>> which scenario once required the resume.
>>>
>>> Jan
>>
>> If the monitor was suspended (migrate without -d), then this path must
>> resume. Should record that somewhere and check here.
> 
> It's clear that we need to resume. The question is in which case
> migrate_fd_cleanup may not be called after an error in
> migrate_fd_put_buffer.
> 
> Jan
> 




[Qemu-devel] [Patch] virtio: security patch

2011-08-03 Thread Supriya Kannery
For security purpose, convert  'int i' to 'unsigned int i' in
virtio functions, so that range of index is restricted
to positive value.

Signed-off-by: Supriya Kannery (supri...@linux.vnet.ibm.com)

---
 hw/virtio.c |   27 +--
 hw/virtio.h |3 ++-
 2 files changed, 19 insertions(+), 11 deletions(-)

Index: qemu/hw/virtio.c
===
--- qemu.orig/hw/virtio.c
+++ qemu/hw/virtio.c
@@ -101,28 +101,32 @@ static void virtqueue_init(VirtQueue *vq
  VIRTIO_PCI_VRING_ALIGN);
 }
 
-static inline uint64_t vring_desc_addr(target_phys_addr_t desc_pa, int i)
+static inline uint64_t vring_desc_addr(target_phys_addr_t desc_pa,
+   unsigned int i)
 {
 target_phys_addr_t pa;
 pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, addr);
 return ldq_phys(pa);
 }
 
-static inline uint32_t vring_desc_len(target_phys_addr_t desc_pa, int i)
+static inline uint32_t vring_desc_len(target_phys_addr_t desc_pa,
+  unsigned int i)
 {
 target_phys_addr_t pa;
 pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, len);
 return ldl_phys(pa);
 }
 
-static inline uint16_t vring_desc_flags(target_phys_addr_t desc_pa, int i)
+static inline uint16_t vring_desc_flags(target_phys_addr_t desc_pa,
+unsigned int i)
 {
 target_phys_addr_t pa;
 pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, flags);
 return lduw_phys(pa);
 }
 
-static inline uint16_t vring_desc_next(target_phys_addr_t desc_pa, int i)
+static inline uint16_t vring_desc_next(target_phys_addr_t desc_pa,
+   unsigned int i)
 {
 target_phys_addr_t pa;
 pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, next);
@@ -143,7 +147,7 @@ static inline uint16_t vring_avail_idx(V
 return lduw_phys(pa);
 }
 
-static inline uint16_t vring_avail_ring(VirtQueue *vq, int i)
+static inline uint16_t vring_avail_ring(VirtQueue *vq, unsigned int i)
 {
 target_phys_addr_t pa;
 pa = vq->vring.avail + offsetof(VRingAvail, ring[i]);
@@ -155,14 +159,16 @@ static inline uint16_t vring_used_event(
 return vring_avail_ring(vq, vq->vring.num);
 }
 
-static inline void vring_used_ring_id(VirtQueue *vq, int i, uint32_t val)
+static inline void vring_used_ring_id(VirtQueue *vq, unsigned int i,
+  uint32_t val)
 {
 target_phys_addr_t pa;
 pa = vq->vring.used + offsetof(VRingUsed, ring[i].id);
 stl_phys(pa, val);
 }
 
-static inline void vring_used_ring_len(VirtQueue *vq, int i, uint32_t val)
+static inline void vring_used_ring_len(VirtQueue *vq, unsigned int i,
+   uint32_t val)
 {
 target_phys_addr_t pa;
 pa = vq->vring.used + offsetof(VRingUsed, ring[i].len);
@@ -334,10 +340,11 @@ static unsigned virtqueue_next_desc(targ
 return next;
 }
 
-int virtqueue_avail_bytes(VirtQueue *vq, int in_bytes, int out_bytes)
+int virtqueue_avail_bytes(VirtQueue *vq, unsigned int in_bytes,
+  unsigned int out_bytes)
 {
 unsigned int idx;
-int total_bufs, in_total, out_total;
+unsigned int total_bufs, in_total, out_total;
 
 idx = vq->last_avail_idx;
 
@@ -345,7 +352,7 @@ int virtqueue_avail_bytes(VirtQueue *vq,
 while (virtqueue_num_heads(vq, idx)) {
 unsigned int max, num_bufs, indirect = 0;
 target_phys_addr_t desc_pa;
-int i;
+unsigned int i;
 
 max = vq->vring.num;
 num_bufs = total_bufs;
Index: qemu/hw/virtio.h
===
--- qemu.orig/hw/virtio.h
+++ qemu/hw/virtio.h
@@ -156,7 +156,8 @@ void virtqueue_fill(VirtQueue *vq, const
 void virtqueue_map_sg(struct iovec *sg, target_phys_addr_t *addr,
 size_t num_sg, int is_write);
 int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem);
-int virtqueue_avail_bytes(VirtQueue *vq, int in_bytes, int out_bytes);
+int virtqueue_avail_bytes(VirtQueue *vq, unsigned int in_bytes,
+  unsigned int out_bytes);
 
 void virtio_notify(VirtIODevice *vdev, VirtQueue *vq);
 



Re: [Qemu-devel] QEMU 0.15.0-rc2 delayed to 08/03/11

2011-08-03 Thread Michael Walle
> I want -rc2 to be the final build so I'm delaying -rc3 until tomorrow so
> we can sort out how to handle this migration issue.

Ok, one more try :)

Anthony, could you please commit the following small patch to the 0.15
branch:
http://lists.nongnu.org/archive/html/qemu-devel/2011-07/msg02183.html

Without this patch, the whole milkymist emulation is broken. And without
this machine model, the whole lm32 target is almost useless.

-- 
Michael




Re: [Qemu-devel] [PATCH 44/55] spitz tosa: Simplify "drive is suitable for microdrive" test

2011-08-03 Thread Markus Armbruster
Peter Maydell  writes:

> On 1 August 2011 13:33, Markus Armbruster  wrote:
>> andrzej zaborowski  writes:
>>> On 20 July 2011 18:24, Markus Armbruster  wrote:
 We try the drive defined with -drive if=ide,index=0 (or equivalent
 sugar).  We use it only if (dinfo && bdrv_is_inserted(dinfo->bdrv) &&
 !bdrv_is_removable(dinfo->bdrv)).  This is a convoluted way to test
 for "drive media can't be removed".

 The only way to create such a drive with -drive if=ide is media=cdrom.
 And that sets dinfo->media_cd, so just test that.
>>>
>>> This is a less generic test and more prone to be broken inadvertently,
>>> so it seems like a step back.  What's the argument against the
>>> convoluted and explicit test?
>>
>> My motivation for changing it was to reduce the uses of BlockDriverState
>> member removable prior to nuking it from orbit [PATCH 45/55].
>>
>> I consider my change an improvement, because I find "dinfo->media_cd"
>> clearer than
>> "bdrv_is_inserted(dinfo->bdrv) && !bdrv_is_removable(dinfo->bdrv)".
>
> This seems like an argument for providing a bdrv_supports_eject()
> or whatever we're actually trying to test for here. I kind of felt
> the same way as Andrzej when I saw this patch going past but it
> got lost in my mail folder...

Well, what are you trying to test for here?

Let's start with figuring out what we actually test for right now (may
not be what you *want* to test for, but it's a start).  The test code is
"bdrv_is_inserted(bs) && !bdrv_is_removable(bs)".

bdrv_is_removable() is a confused mess.  It is true when an ide-cd,
scsi-cd or floppy qdev is attached, or when the BlockDriverState was
created with -drive if={floppy,sd} or -drive
if={ide,scsi,xen,none},media=cdrom, except when an ide-hd, scsi-hd,
scsi-generic or virtio-blk qdev is attached.

Since we're about to attach a device here, no other device can be
attached, and the mess simplifies into "when the BlockDriverState was
created with -drive if={floppy,sd} or -drive
if={ide,scsi,xen,none},media=cdrom".

Since we're getting IF_IDE, it further simplifies into "when the
BlockDriverState was created with -drive if=ide,media=cdrom".  Which is
what my patch tests.

The bdrv_is_inserted() part is actually redundant, because it can only
be false if bdrv_is_removable() is true: the only way to create an IDE
drive empty is with media=cdrom (makes bdrv_is_removable() true), and
media is ejectable only when bdrv_is_removable() is true.

Therefore, my patch preserves behavior.


Testing for "block driver supports eject" is something else entirely.
Block drivers "host_cdrom" and "host_floppy" implement method
bdrv_eject()[*].  Is that what you want?

Note that "block driver supports eject" is completely independent of
"monitor command eject works".  You can back a removable device such as
a CD-ROM with a block driver that doesn't support eject, say "file".
Monitor command eject works fine then.  Conversely, you can back a
non-removable device such as a disk with a block driver that does
support eject, such as "host_cdrom".  It may not be the wisest thing to
do, but it works.  Ejecting the physical media while the device model is
using it will result in I/O errors, to nobody's surprise.


Anyway.  bdrv_is_removable() must die.  You're using it.  Please tell me
what exactly you're trying to accomplish, so I can get it done without
bdrv_is_removable().  Best way to tell me is with a patch.


[*] "raw" implements bdrv_eject() as well, but it merely forwards, which
doesn't count.



[Qemu-devel] ethlite mac on virtex board

2011-08-03 Thread Lê Đức Tài
Hi Edgar,
I have a problem with Ethernet Lite on Virtex board as following.
Could you help me?
Thank you!

[Modify device tree - linux-2.6.37]

diff --git a/arch/powerpc/boot/dts/virtex440-ml507.dts 
b/arch/powerpc/boot/dts/virtex440-ml507.dts
index 9cf6081..acc8406 100644
--- a/arch/powerpc/boot/dts/virtex440-ml507.dts
+++ b/arch/powerpc/boot/dts/virtex440-ml507.dts
@@ -155,6 +155,18 @@
#size-cells = <1>;
compatible = "xlnx,plb-v46-1.03.a", "simple-bus";
ranges ;
+   ethernet@8100 {
+   compatible = "xlnx,xps-ethernetlite-1.00.a";
+   device_type = "network";
+   interrupt-parent = <&xps_intc_0>;
+   interrupts = < 5 2 >;
+   local-mac-address = [02 00 00 00 00 00];
+   reg = <0x8100 0x1>;
+   xlnx,duplex = <0x1>;
+   xlnx,family = "spartan3adsp";
+   xlnx,rx-ping-pong = <0x0>;
+   xlnx,tx-ping-pong = <0x0>;
+   };
DIP_Switches_8Bit: gpio@8146 {
compatible = "xlnx,xps-gpio-1.00.a";
interrupt-parent = <&xps_intc_0>;


[Modify qemu - v0.15.0rc1]

diff --git a/hw/virtex_ml507.c b/hw/virtex_ml507.c
index 7bde8c7..4dea56a 100644
--- a/hw/virtex_ml507.c
+++ b/hw/virtex_ml507.c
@@ -232,6 +232,7 @@ static void virtex_init(ram_addr_t ram_size,
 
 /* 2 timers at irq 2 @ 62 Mhz.  */
 xilinx_timer_create(0x83c0, irq[3], 2, 62 * 100);
+xilinx_ethlite_create(&nd_table[0], 0x8100, irq[5], 0, 0);
 
 if (kernel_filename) {
 uint64_t entry, low, high;


[Error when running guest machine]

zImage starting: loaded at 0x0120 (sp: 0x0153cfb0)
Allocating 0x4bbe68 bytes for kernel ...
gunzipping (0x <- 0x0120e000:0x013cb92a)...done 0x39b4f0 bytes
Attached initrd image at 0x013cc000-0x0153bf20
initrd head: 0x1f8b0808

Linux/PowerPC load: console=ttyS0
Finalizing device tree... flat tree at 0x1549300
[0.00] Using Xilinx Virtex440 machine description
[0.00] Linux version 2.6.37+ (taild@debian-ttec) (gcc version 4.3.5 
(Debian 4.3.5-4) ) #35 PREEMPT Wed Aug 3 11:30:45 ICT 2011
[0.00] Found initrd at 0xc13cc000:0xc153bf20
[0.00] Zone PFN ranges:
[0.00]   DMA  0x -> 0x0001
[0.00]   Normal   empty
[0.00] Movable zone start PFN for each node
[0.00] early_node_map[1] active PFN ranges
[0.00] 0: 0x -> 0x0001
[0.00] MMU: Allocated 1088 bytes of context maps for 255 contexts
[0.00] Built 1 zonelists in Zone order, mobility grouping on.  Total 
pages: 65024
[0.00] Kernel command line: console=ttyS0
[0.00] PID hash table entries: 1024 (order: 0, 4096 bytes)
[0.00] Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
[0.00] Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
[0.00] Memory: 253468k/262144k available (3520k kernel code, 8676k 
reserved, 176k data, 1151k bss, 160k init)
[0.00] Kernel virtual memory layout:
[0.00]   * 0xfffdf000..0xf000  : fixmap
[0.00]   * 0xfde0..0xfe00  : consistent mem
[0.00]   * 0xfde0..0xfde0  : early ioremap
[0.00]   * 0xd100..0xfde0  : vmalloc & ioremap
[0.00] Preemptable hierarchical RCU implementation.
[0.00] RCU-based detection of stalled CPUs is disabled.
[0.00] Verbose stalled-CPUs detection is disabled.
[0.00] NR_IRQS:512
[0.00] clocksource: timebase mult[a0] shift[22] registered
[0.00] Console: colour dummy device 80x25
[0.016523] pid_max: default: 32768 minimum: 301
[0.017972] Mount-cache hash table entries: 512
[0.086498] NET: Registered protocol family 16
[0.104131] PCI: Probing PCI hardware
[0.131515] bio: create slab  at 0
[0.136472] XGpio: /plb@0/gpio@8146: registered
[0.137461] XGpio: /plb@0/gpio@8140: registered
[0.138130] XGpio: /plb@0/gpio@8142: registered
[0.138710] XGpio: /plb@0/gpio@8144: registered
[0.141923] vgaarb: loaded
[0.155370] Switching to clocksource timebase
[0.203063] NET: Registered protocol family 2
[0.207284] IP route cache hash table entries: 2048 (order: 1, 8192 bytes)
[0.214170] TCP established hash table entries: 8192 (order: 4, 65536 bytes)
[0.214492] TCP bind hash table entries: 8192 (order: 3, 32768 bytes)
[0.215635] TCP: Hash tables configured (established 8192 bind 8192)
[0.215961] TCP reno registered
[0.216157] UDP hash table entries: 256 (order: 0, 4096 bytes)
[0.216482] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[0.218590] NET: Registered protocol family 1
[0.222081] RPC: Registered udp transport module.
[0.05] RPC: Registered

Re: [Qemu-devel] [PULL] pci, virtio, net

2011-08-03 Thread Markus Armbruster
"Michael S. Tsirkin"  writes:

> The following changes since commit d1afc48b7cfdb4490f322d5d82a2aae6d545ec06:
>
>   SPARC64: implement addtional MMU faults related to nonfaulting load 
> (2011-07-21 20:02:22 +)
>
> are available in the git repository at:
>   git://git.kernel.org/pub/scm/linux/kernel/git/mst/qemu.git for_anthony
>
> Amit Shah (3):
>   virtio-blk: Fix memleak on exit
>   virtio-net: don't use vdev after virtio_cleanup
>   virtio: Plug memleak by freeing vdev
>
> Isaku Yamahata (1):
>   pcie_host: verify mmcfg address range
>
> Jan Kiszka (1):
>   pci: Common overflow prevention
>
> Markus Armbruster (2):
>   Fix automatically assigned network names for netdev
>   Fix netdev name lookup in -device, device_add, netdev_del
>
> Michael S. Tsirkin (1):
>   virtio-pci: use generic logic for command access

Some of these (including mine) are obvious candidates for STABLE.
Perhaps even all of them.  Michael?



Re: [Qemu-devel] [PULL] pci, virtio, net

2011-08-03 Thread Michael S. Tsirkin
On Wed, Aug 03, 2011 at 10:15:03AM +0200, Markus Armbruster wrote:
> "Michael S. Tsirkin"  writes:
> 
> > The following changes since commit d1afc48b7cfdb4490f322d5d82a2aae6d545ec06:
> >
> >   SPARC64: implement addtional MMU faults related to nonfaulting load 
> > (2011-07-21 20:02:22 +)
> >
> > are available in the git repository at:
> >   git://git.kernel.org/pub/scm/linux/kernel/git/mst/qemu.git for_anthony
> >
> > Amit Shah (3):
> >   virtio-blk: Fix memleak on exit
> >   virtio-net: don't use vdev after virtio_cleanup
> >   virtio: Plug memleak by freeing vdev
> >
> > Isaku Yamahata (1):
> >   pcie_host: verify mmcfg address range
> >
> > Jan Kiszka (1):
> >   pci: Common overflow prevention
> >
> > Markus Armbruster (2):
> >   Fix automatically assigned network names for netdev
> >   Fix netdev name lookup in -device, device_add, netdev_del
> >
> > Michael S. Tsirkin (1):
> >   virtio-pci: use generic logic for command access
> 
> Some of these (including mine) are obvious candidates for STABLE.
> Perhaps even all of them.  Michael?

Amit's and your patches probably are. The pci changes probably aren't.

-- 
MST



Re: [Qemu-devel] [PATCH] memory: use signed arithmetic

2011-08-03 Thread Avi Kivity

On 08/03/2011 01:15 AM, Richard Henderson wrote:

On 08/02/2011 03:06 PM, Avi Kivity wrote:
>  I don't think there's any cpu which has a real 64-bit physical
>  address space? Don't they all truncate it?

I don't know.  You're right that x86_64 does, at 48 bits.
The alpha system I'm trying to emulate does, at 50 bits.

I guess if IBM agrees wrt p-series and z-series emulation, then
I'd be ok, so long as you add a comment above that structure that
says no existing hw implementation actually uses 63 address bits.


Ben, can you confirm that pseries physical addresses are 63 bits wide or 
smaller?


IIRC zseries has no mmio, and Zettabyte machines are still rare.

--
error compiling committee.c: too many arguments to function




Re: [Qemu-devel] [PATCH] migration: remove subsections in fdc and rtl8139 and bump versions (v2)

2011-08-03 Thread Kevin Wolf
Am 03.08.2011 02:18, schrieb Anthony Liguori:
> As Paolo points out, the migration protocol is ambiguous when using 
> subsections
> today.  That means that even if we preserve subsections and change the 
> protocol
> accordingly, the old protocol w/subsections is still ambiguous.
> 
> Remove subsection usage and bump any device using subsections.  This 
> effectively
> eliminates the amiguouity and allows for a clean transition to a new protocol
> with unambiguous subsections.
> 
> Signed-off-by: Anthony Liguori 
> --
> v1 -> v2
>  - Also remove IDE subsections (spotted by Juan Quintela)

Please remove migration_compat_status from BMDMAState and the respective
VMState, there's no reason for it any more when you increase the version
number.

Kevin



[Qemu-devel] [PATCH 00/16] SCSI sense and target request overhaul

2011-08-03 Thread Paolo Bonzini
This is a pretty important step in the modernization and improvement
of the SCSI backends, and a prerequisite for pretty much everything
that is on the table: migration, addressing, improved CD-ROM support,
hotplug.

The series touches two main parts:

1) sense data.  Autosense is made a first-class citizen of the
subsystem.  Sense data is communicated to the target primarily
via autosense, and it is then the target that uses this information
to reply to REQUEST SENSE commands.  In addition, each LUN or
target can be in a unit attention condition, which will be
communicated via either autosense or REQUEST SENSE, or cleared
automatically.

2) target requests.  The common example of this is REPORT LUNS
and commands sent to invalid LUNs.  Handling of these commands
previously had to be done for every SCSIDevice.  This series splits
request-related SCSIDevice callbacks out into a new SCSIReqOps
structure, thus allowing the target (SCSIBus) to hijack those requests
and reply to them without involving the SCSIDevice at all.  The
system is quite flexible, and is also used for invalid commands,
REQUEST SENSE and commands sent while a unit attention
condition is pending.

Finally, other parts of the SCSIDevice code are moved to common
code including general parsing of requests.

The two parts are slightly intertwined.  Sense data is handled by patches
2/3/4/12/13/14/15, and target requests are handled by patches 5 to 11.
(patches 1 and 16 are somewhat unrelated).  The reason for this is that
the current device-specific handling of sense data conflicts heavily
with the goal of handling some commands in a device-independent way.
So, the series starts by moving sense handling to generic code, and
comes back to generic handling of REQUEST SENSE and unit attention after
implementing a few others device-independent requests.

It conflicts somewhat with Markus's tray series, but not in a
fatal way; the conflicts are trivial.

Paolo Bonzini (16):
  scsi-disk: no need to call scsi_req_data on a short read
  vscsi: always use get_sense
  scsi: pass status when completing
  scsi: move sense handling to generic code
  scsi: introduce SCSIReqOps
  scsi: move request-related callbacks from SCSIDeviceInfo to SCSIReqOps
  scsi: pass cdb already to scsi_req_new
  scsi: introduce SCSICommand
  scsi: push lun field to SCSIDevice
  scsi: move request parsing to common code
  scsi: move handling of REPORT LUNS and invalid LUNs to common code
  scsi: move handling of REQUEST SENSE to common code
  scsi: add a bunch more common sense codes
  scsi: add support for unit attention conditions
  scsi: report unit attention on reset
  scsi: add special traces for common commands

 hw/esp.c  |4 +-
 hw/lsi53c895a.c   |4 +-
 hw/scsi-bus.c |  578 +
 hw/scsi-defs.h|4 +
 hw/scsi-disk.c|  164 +---
 hw/scsi-generic.c |  156 ---
 hw/scsi.h |   72 +--
 hw/spapr_vscsi.c  |   95 ++---
 hw/usb-msd.c  |4 +-
 trace-events  |5 +
 10 files changed, 668 insertions(+), 418 deletions(-)

-- 
1.7.6




[Qemu-devel] [PATCH 02/16] vscsi: always use get_sense

2011-08-03 Thread Paolo Bonzini
vscsi supports autosensing by providing sense data directly in the
response.  When get_sense was added, the older state machine approach
that sent REQUEST SENSE commands separately was left in place.  Remove
it, all existing SCSIDevices do support autosensing and the next patches
will make the support come for free from the SCSIBus.

Signed-off-by: Paolo Bonzini 
---
 hw/spapr_vscsi.c |   91 -
 1 files changed, 21 insertions(+), 70 deletions(-)

diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
index 646b1e3..c65308c 100644
--- a/hw/spapr_vscsi.c
+++ b/hw/spapr_vscsi.c
@@ -80,7 +80,6 @@ typedef struct vscsi_req {
 int active;
 longdata_len;
 int writing;
-int sensing;
 int senselen;
 uint8_t sense[SCSI_SENSE_BUF_SIZE];
 
@@ -436,40 +435,6 @@ static int vscsi_preprocess_desc(vscsi_req *req)
 return 0;
 }
 
-static void vscsi_send_request_sense(VSCSIState *s, vscsi_req *req)
-{
-uint8_t *cdb = req->iu.srp.cmd.cdb;
-int n;
-
-n = scsi_req_get_sense(req->sreq, req->sense, sizeof(req->sense));
-if (n) {
-req->senselen = n;
-vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0);
-vscsi_put_req(req);
-return;
-}
-
-dprintf("VSCSI: Got CHECK_CONDITION, requesting sense...\n");
-cdb[0] = 3;
-cdb[1] = 0;
-cdb[2] = 0;
-cdb[3] = 0;
-cdb[4] = 96;
-cdb[5] = 0;
-req->sensing = 1;
-n = scsi_req_enqueue(req->sreq, cdb);
-dprintf("VSCSI: Queued request sense tag 0x%x\n", req->qtag);
-if (n < 0) {
-fprintf(stderr, "VSCSI: REQUEST_SENSE wants write data !?!?!?\n");
-vscsi_makeup_sense(s, req, HARDWARE_ERROR, 0, 0);
-scsi_req_abort(req->sreq, CHECK_CONDITION);
-return;
-} else if (n == 0) {
-return;
-}
-scsi_req_continue(req->sreq);
-}
-
 /* Callback to indicate that the SCSI layer has completed a transfer.  */
 static void vscsi_transfer_data(SCSIRequest *sreq, uint32_t len)
 {
@@ -485,23 +450,6 @@ static void vscsi_transfer_data(SCSIRequest *sreq, 
uint32_t len)
 return;
 }
 
-if (req->sensing) {
-uint8_t *buf = scsi_req_get_buf(sreq);
-
-len = MIN(len, SCSI_SENSE_BUF_SIZE);
-dprintf("VSCSI: Sense data, %d bytes:\n", len);
-dprintf("   %02x  %02x  %02x  %02x  %02x  %02x  %02x  %02x\n",
-buf[0], buf[1], buf[2], buf[3],
-buf[4], buf[5], buf[6], buf[7]);
-dprintf("   %02x  %02x  %02x  %02x  %02x  %02x  %02x  %02x\n",
-buf[8], buf[9], buf[10], buf[11],
-buf[12], buf[13], buf[14], buf[15]);
-memcpy(req->sense, buf, len);
-req->senselen = len;
-scsi_req_continue(req->sreq);
-return;
-}
-
 if (len) {
 buf = scsi_req_get_buf(sreq);
 rc = vscsi_srp_transfer_data(s, req, req->writing, buf, len);
@@ -532,28 +480,31 @@ static void vscsi_command_complete(SCSIRequest *sreq, 
uint32_t status)
 return;
 }
 
-if (!req->sensing && status == CHECK_CONDITION) {
-vscsi_send_request_sense(s, req);
-return;
+if (status == CHECK_CONDITION) {
+req->senselen = scsi_req_get_sense(req->sreq, req->sense,
+   sizeof(req->sense));
+status = 0;
+dprintf("VSCSI: Sense data, %d bytes:\n", len);
+dprintf("   %02x  %02x  %02x  %02x  %02x  %02x  %02x  %02x\n",
+req->sense[0], req->sense[1], req->sense[2], req->sense[3],
+req->sense[4], req->sense[5], req->sense[6], req->sense[7]);
+dprintf("   %02x  %02x  %02x  %02x  %02x  %02x  %02x  %02x\n",
+req->sense[8], req->sense[9], req->sense[10], req->sense[11],
+req->sense[12], req->sense[13], req->sense[14], 
req->sense[15]);
 }
 
-if (req->sensing) {
-dprintf("VSCSI: Sense done !\n");
-status = CHECK_CONDITION;
-} else {
-dprintf("VSCSI: Command complete err=%d\n", status);
-if (status == 0) {
-/* We handle overflows, not underflows for normal commands,
- * but hopefully nobody cares
- */
-if (req->writing) {
-res_out = req->data_len;
-} else {
-res_in = req->data_len;
-}
+dprintf("VSCSI: Command complete err=%d\n", status);
+if (status == 0) {
+/* We handle overflows, not underflows for normal commands,
+ * but hopefully nobody cares
+ */
+if (req->writing) {
+res_out = req->data_len;
+} else {
+res_in = req->data_len;
 }
 }
-vscsi_send_rsp(s, req, 0, res_in, res_out);
+vscsi_send_rsp(s, req, status, res_in, res_out);
 vscsi_put_req(req);
 }
 
-- 
1.7.6





[Qemu-devel] [PATCH 12/16] scsi: move handling of REQUEST SENSE to common code

2011-08-03 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini 
---
 hw/scsi-bus.c |   12 ++--
 hw/scsi-disk.c|9 ++---
 hw/scsi-generic.c |   16 
 3 files changed, 12 insertions(+), 25 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 139f6a6..fbb9801 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -270,6 +270,13 @@ static int32_t scsi_target_send_command(SCSIRequest *req, 
uint8_t *buf)
 goto illegal_request;
 }
 break;
+case REQUEST_SENSE:
+if (req->cmd.xfer < 4) {
+goto illegal_request;
+}
+r->len = scsi_device_get_sense(r->req.dev, r->buf, req->cmd.xfer,
+   (req->cmd.buf[1] & 1) == 0);
+break;
 default:
 scsi_req_build_sense(req, SENSE_CODE(LUN_NOT_SUPPORTED));
 scsi_req_complete(req, CHECK_CONDITION);
@@ -351,8 +358,9 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, 
uint32_t lun,
   cmd.lba);
 }
 
-if ((lun != d->lun && buf[0] != REQUEST_SENSE) ||
-buf[0] == REPORT_LUNS) {
+if (lun != d->lun ||
+buf[0] == REPORT_LUNS ||
+buf[0] == REQUEST_SENSE) {
 req = scsi_req_alloc(&reqops_target_command, d, tag, lun,
  hba_private);
 } else {
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index a5fdb05..5f21d68 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -792,12 +792,6 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r, 
uint8_t *outbuf)
 if (!bdrv_is_inserted(s->bs))
 goto not_ready;
break;
-case REQUEST_SENSE:
-if (req->cmd.xfer < 4)
-goto illegal_request;
-buflen = scsi_device_get_sense(&s->qdev, outbuf, req->cmd.xfer,
-   (req->cmd.buf[1] & 1) == 0);
-break;
 case INQUIRY:
 buflen = scsi_disk_emulate_inquiry(req, outbuf);
 if (buflen < 0)
@@ -974,7 +968,6 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t 
*buf)
 
 switch (command) {
 case TEST_UNIT_READY:
-case REQUEST_SENSE:
 case INQUIRY:
 case MODE_SENSE:
 case MODE_SENSE_10:
@@ -1074,6 +1067,8 @@ static int32_t scsi_send_command(SCSIRequest *req, 
uint8_t *buf)
 }
 
 break;
+case REQUEST_SENSE:
+abort();
 default:
 DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
 scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 5217aaf..c122ad3 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -183,22 +183,6 @@ static void scsi_read_data(SCSIRequest *req)
 return;
 }
 
-if (r->req.cmd.buf[0] == REQUEST_SENSE) {
-r->io_header.driver_status = 0;
-r->io_header.status = 0;
-r->io_header.dxfer_len =
-scsi_device_get_sense(&s->qdev, r->buf, r->req.cmd.xfer,
-  (r->req.cmd.buf[1] & 1) == 0);
-r->len = -1;
-DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, 
r->io_header.dxfer_len);
-DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
-r->buf[0], r->buf[1], r->buf[2], r->buf[3],
-r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
-scsi_req_data(&r->req, r->io_header.dxfer_len);
-/* The sense buffer is cleared when we return GOOD */
-return;
-}
-
 ret = execute_command(s->bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
 if (ret < 0) {
 scsi_command_complete(r, ret);
-- 
1.7.6





[Qemu-devel] [PATCH v2] memory: use signed arithmetic

2011-08-03 Thread Avi Kivity
When trying to map an alias of a ram region, where the alias starts at
address A and we map it into address B, and A > B, we had an arithmetic
underflow.  Because we use unsigned arithmetic, the underflow converted
into a large number which failed addrrange_intersects() tests.

The concrete example which triggered this was cirrus vga mapping
the framebuffer at offsets 0xc-0xc7fff (relative to the start of
the framebuffer) into offsets 0xa (relative to system addres space
start).

With our favorite analogy of a windowing system, this is equivalent to
dragging a subwindow off the left edge of the screen, and failing to clip
it into its parent window which is on screen.

Fix by switching to signed arithmetic.

Signed-off-by: Avi Kivity 
---

v2: add comment about physical address width limitation to 63 bits

 exec.c   |2 +-
 memory.c |   23 ++-
 2 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/exec.c b/exec.c
index 476b507..751fd89 100644
--- a/exec.c
+++ b/exec.c
@@ -3818,7 +3818,7 @@ static void io_mem_init(void)
 static void memory_map_init(void)
 {
 system_memory = qemu_malloc(sizeof(*system_memory));
-memory_region_init(system_memory, "system", UINT64_MAX);
+memory_region_init(system_memory, "system", INT64_MAX);
 set_system_memory_map(system_memory);
 }
 
diff --git a/memory.c b/memory.c
index 5f20320..be891c6 100644
--- a/memory.c
+++ b/memory.c
@@ -22,12 +22,17 @@ unsigned memory_region_transaction_depth = 0;
 
 typedef struct AddrRange AddrRange;
 
+/*
+ * Note using signed integers limits us to physical addresses at most
+ * 63 bits wide.  They are needed for negative offsetting in aliases
+ * (large MemoryRegion::alias_offset).
+ */
 struct AddrRange {
-uint64_t start;
-uint64_t size;
+int64_t start;
+int64_t size;
 };
 
-static AddrRange addrrange_make(uint64_t start, uint64_t size)
+static AddrRange addrrange_make(int64_t start, int64_t size)
 {
 return (AddrRange) { start, size };
 }
@@ -37,7 +42,7 @@ static bool addrrange_equal(AddrRange r1, AddrRange r2)
 return r1.start == r2.start && r1.size == r2.size;
 }
 
-static uint64_t addrrange_end(AddrRange r)
+static int64_t addrrange_end(AddrRange r)
 {
 return r.start + r.size;
 }
@@ -56,9 +61,9 @@ static bool addrrange_intersects(AddrRange r1, AddrRange r2)
 
 static AddrRange addrrange_intersection(AddrRange r1, AddrRange r2)
 {
-uint64_t start = MAX(r1.start, r2.start);
+int64_t start = MAX(r1.start, r2.start);
 /* off-by-one arithmetic to prevent overflow */
-uint64_t end = MIN(addrrange_end(r1) - 1, addrrange_end(r2) - 1);
+int64_t end = MIN(addrrange_end(r1) - 1, addrrange_end(r2) - 1);
 return addrrange_make(start, end - start + 1);
 }
 
@@ -411,8 +416,8 @@ static void render_memory_region(FlatView *view,
 MemoryRegion *subregion;
 unsigned i;
 target_phys_addr_t offset_in_region;
-uint64_t remain;
-uint64_t now;
+int64_t remain;
+int64_t now;
 FlatRange fr;
 AddrRange tmp;
 
@@ -486,7 +491,7 @@ static FlatView generate_memory_topology(MemoryRegion *mr)
 
 flatview_init(&view);
 
-render_memory_region(&view, mr, 0, addrrange_make(0, UINT64_MAX));
+render_memory_region(&view, mr, 0, addrrange_make(0, INT64_MAX));
 flatview_simplify(&view);
 
 return view;
-- 
1.7.5.3




Re: [Qemu-devel] [Patch] virtio: security patch

2011-08-03 Thread Stefan Hajnoczi
On Wed, Aug 3, 2011 at 8:56 AM, Supriya Kannery
 wrote:
> For security purpose, convert  'int i' to 'unsigned int i' in
> virtio functions, so that range of index is restricted
> to positive value.
>
> Signed-off-by: Supriya Kannery (supri...@linux.vnet.ibm.com)
>
> ---
>  hw/virtio.c |   27 +--
>  hw/virtio.h |    3 ++-
>  2 files changed, 19 insertions(+), 11 deletions(-)

I think this change is good because the ints are accidents waiting to happen.

The commit message should be descriptive though: "virtio: make indices
unsigned".  There is currently no bug in the code AFAICT.  This is not
a security fix, just a cleanup to make the code safer.

Stefan



Re: [Qemu-devel] [PATCH] migration: remove subsections in fdc and rtl8139 and bump versions

2011-08-03 Thread Juan Quintela
Anthony Liguori  wrote:
> On 08/02/2011 06:25 PM, Juan Quintela wrote:
>> Anthony Liguori  wrote:
>>> As Paolo points out, the migration protocol is ambiguous when using 
>>> subsections
>>> today.  That means that even if we preserve subsections and change the 
>>> protocol
>>> accordingly, the old protocol w/subsections is still ambiguous.
>>>
>>> Remove subsection usage and bump any device using subsections.  This 
>>> effectively
>>> eliminates the amiguouity and allows for a clean transition to a new 
>>> protocol
>>> with unambiguous subsections.
>>
>> If you are doing that, you can just remove the old protocol altogether.
>
> The fundamental problem is that newer QEMUs generate migration state
> that is ambiguous to older QEMUs.
>
> No matter what, we have to change the migration protocol in some way
> as to make it impossible to migrate from newer QEMUs to older QEMUs.
>
> Even with subsections in the older protocol, newer QEMUs (provided we
> don't add more subsections), can still read the old protocol.
>
> Paolo's proposed changes make newer QEMUs use a new protocol.  It's
> still possible to read the older protocol.  This means that you can't
> migrate new to old, but can migrate old to new.
>
> I've poured over these patches in great detail and the changes are
> just too much right now.  Just the ram_addr_t change which now
> conflicts has a non-trivial resolution due to a related Xen change.
>
> So my thinking is to be a bit more conservative.  If we bump the
> version number for 0.15.0, we make sure that we don't allow new -> old
> migration.  We will break old -> new migration, but we can fix that
> (including in the stable series) by adding special handling of the
> previous version.
>
> Fixing new->old is the critical bit here.  We can resolve old->new as
> a stable update.

We are making something that is incompatible.  If we don't care about
breaking 0.14 -> 0.15 migration.  Just add Paolo version, and drop
altogether the old protocol.  It will give us exactly the same result,
new versions work, old versions fail.

>> You are missing also ide on your patch.
>
> Thanks for catching that.
>
>>  Only platform that
>> ever cares about forward compatiblity is pc's.  And pc's always use
>> floppies on qemu.
>>
>> I still think that improving the "subsection" match is the way to go for 
>> 0.15.
>
> This series was just too late for 0.15.  I can close to suggesting
> that we delay 0.15 in order to give this time to be tested thoroughly
> but I think my proposal is a reasonable compromise.

I think it is anything except reasonable.  From my point on view (and I
am biased), it is the equivalent of finding a corner case broken on
qcow2 and make all _OLD_ qcow2 images unreadable.  It will work, but it
is anything except reasonable.  As said, everything uses an fdc.
Furthermore, the _two_ things that you change don't matter in the big
scheme of things.  The subsections that fail are the ones that can
appear in the middle of another section.  The ones that appear at the
end of a real section work perfectly well with this protocol (a.k.a. the
ones that are broken are IDE), floppy and rtl8139 are ok with current
protocol.

Later, Juan.



Re: [Qemu-devel] qemu-kvm aborts - vhost_dev_unassign_memory: Assertion `to >= 0' failed.

2011-08-03 Thread Avi Kivity

On 08/01/2011 08:44 PM, David Ahern wrote:

qemu-kvm.git as of:

commit dacdc4b10bafbb21120e1c24a9665444768ef999
Merge: 7b69d4f 0af4922
Author: Avi Kivity
Date:   Sun Jul 31 11:42:26 2011 +0300

 Merge branch 'upstream-merge' into next

is aborting with the error:

qemu-kvm: qemu-kvm.git/hw/vhost.c:123: vhost_dev_unassign_memory:
Assertion `to>= 0' failed.
Aborted


Full command line please?

--
error compiling committee.c: too many arguments to function




Re: [Qemu-devel] [Request for Help] QEMU 0.15.0 change log

2011-08-03 Thread Philipp Hahn
Hello,

On Monday 25 July 2011 16:18:07 Anthony Liguori wrote:
> Hands down, 0.14.0 had the best change log of any QEMU release.  A large
> part of the success of the change log was how many people participated
> in creating it.  I'd love for us to go even further with 0.15.0.
>
> I've created a template to start with:
>
> http://wiki.qemu.org/ChangeLog/0.15

I just had to look at the 0.14 (.1) changelog and noticed that most links to 
the git-commits were currently not working, because git.qemu.org is 
(currently?) unreachable.

I took the oportunity to create the Wiki-Template 
 which can be used to create links to git 
commits by just writing
{{git|56a60dd6d619877e9957ba06b92d2f276e3c229d}}
instead of hard-coding the host-name and path to gitweb in each link, so 
update the host and path now can be done easily in one place instead of 
multiple places. It's currently pointing to repo.or.cz.

I already converted the 0.14 and 0.15 ChangeLogs to use that template:
 s!\[http://git\.qemu\.org/qemu\.git/commit/?id=\(\x\+\) (commit)\]!{{git|
\1}}!g  
 
 s!\[http://repo\.or\.cz/w/qemu\.git/commitdiff/\(\x\+\) (commit)\]!{{git|
\1}}!g  
 
 s!\[http://repo\.or\.cz/w/qemu\.git/commit/\(\x\+\) (commit)\]!{{git|
\1}}!g  
 

Sincerely
Philipp
-- 
Philipp Hahn   Open Source Software Engineer  h...@univention.de
Univention GmbHLinux for Your Businessfon: +49 421 22 232- 0
Mary-Somerville-Str.1  D-28359 Bremen fax: +49 421 22 232-99
   http://www.univention.de/


signature.asc
Description: This is a digitally signed message part.


Re: [Qemu-devel] modelling omap_gpmc with the hierarchical memory API

2011-08-03 Thread Peter Maydell
On 3 August 2011 03:25, Anthony Liguori  wrote:
> On 08/02/2011 04:28 PM, Peter Maydell wrote:
>> Typically in the latter case the device we're talking to will
>> also provide some gpio or irq signals, which will be routed in
>> a totally different direction having nothing to do with the GPMC.
>> So it's important that we should be able to take an existing
>> device model and route its registers through the GPMC and its
>> GPIO elsewhere.
>
> So I think the modelling disconnect here is that you're trying to model the
> wire connections to hook up arbitrary devices to a OMAP SOC.

Yes. This is how hardware works... If our device model lets
us wire up connections at a fairly low level, then we can always
implement more strongly typed and more bus like connections in
terms of that. If we only provide strongly typed connections then
it's not possible to model lower level wiring in terms of those.

This is IMHO exactly why so many things end up as sysbus devices --
they're the closest thing we have to "just get out of my way and
let me connect this device model up the way it needs to be connected".

> Unless you're modelling each pin (which I don't think you're doing), I think
> it makes more sense to treat this as a bus and model accordingly.

I think the "bus" like thing is the "I am providing an addressible
section of memory" part. I think we need that as a low level
fundamental kind of connection in the same way as a single GPIO
signal is a low level fundamental connection. At the moment the
closest thing we have to that is to model it as a complete sysbus,
which seems like overkill (we don't want the GPIO bits of sysbus
for just the memory connection) but will work.

[*] I did convince myself that you do want a sysbus bus on each
chip select, because in theory in the hardware you could put an
external address decoder on the gpmc_a[] bus and hang multiple
devices off one chipselect. So that's a sysbus, really.

-- PMM



[Qemu-devel] [PATCH 11/16] scsi: move handling of REPORT LUNS and invalid LUNs to common code

2011-08-03 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini 
---
 hw/scsi-bus.c |  175 -
 hw/scsi-defs.h|3 +
 hw/scsi-disk.c|   21 --
 hw/scsi-generic.c |7 --
 4 files changed, 177 insertions(+), 29 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 01dbe02..139f6a6 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -149,6 +149,172 @@ struct SCSIReqOps reqops_invalid_opcode = {
 .send_command = scsi_invalid_command
 };
 
+/* SCSIReqOps implementation for REPORT LUNS and for commands sent to
+   an invalid LUN.  */
+
+typedef struct SCSITargetReq SCSITargetReq;
+
+struct SCSITargetReq {
+SCSIRequest req;
+int len;
+uint8_t buf[64];
+};
+
+static void store_lun(uint8_t *outbuf, int lun)
+{
+if (lun < 256) {
+outbuf[1] = lun;
+return;
+}
+outbuf[1] = (lun & 255);
+outbuf[0] = (lun >> 8) | 0x40;
+}
+
+static bool scsi_target_emulate_report_luns(SCSITargetReq *r)
+{
+int len;
+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);
+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;
+}
+return true;
+}
+
+static bool scsi_target_emulate_inquiry(SCSITargetReq *r)
+{
+assert(r->req.dev->lun != r->req.lun);
+if (r->req.cmd.buf[1] & 0x2) {
+/* Command support data - optional, not implemented */
+return false;
+}
+
+if (r->req.cmd.buf[1] & 0x1) {
+/* Vital product data */
+uint8_t page_code = r->req.cmd.buf[2];
+if (r->req.cmd.xfer < 4) {
+return false;
+}
+
+r->buf[r->len++] = page_code ; /* this page */
+r->buf[r->len++] = 0x00;
+
+switch (page_code) {
+case 0x00: /* Supported page codes, mandatory */
+{
+int pages;
+pages = r->len++;
+r->buf[r->len++] = 0x00; /* list of supported pages (this page) */
+r->buf[pages] = r->len - pages - 1; /* number of pages */
+break;
+}
+default:
+return false;
+}
+/* done with EVPD */
+assert(r->len < sizeof(r->buf));
+r->len = MIN(r->req.cmd.xfer, r->len);
+return true;
+}
+
+/* Standard INQUIRY data */
+if (r->req.cmd.buf[2] != 0) {
+return false;
+}
+
+/* PAGE CODE == 0 */
+if (r->req.cmd.xfer < 5) {
+return -1;
+}
+
+r->len = MIN(r->req.cmd.xfer, 36);
+memset(r->buf, 0, r->len);
+if (r->req.lun != 0) {
+r->buf[0] = TYPE_NO_LUN;
+} else {
+r->buf[0] = TYPE_NOT_PRESENT | TYPE_INACTIVE;
+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.  */
+memcpy(&r->buf[8], "QEMU", 8);
+memcpy(&r->buf[16], "QEMU TARGET ", 16);
+strncpy((char *) &r->buf[32], QEMU_VERSION, 4);
+}
+return true;
+}
+
+static int32_t scsi_target_send_command(SCSIRequest *req, uint8_t *buf)
+{
+SCSITargetReq *r = DO_UPCAST(SCSITargetReq, req, req);
+
+switch (buf[0]) {
+case REPORT_LUNS:
+if (!scsi_target_emulate_report_luns(r)) {
+goto illegal_request;
+}
+break;
+case INQUIRY:
+if (!scsi_target_emulate_inquiry(r)) {
+goto illegal_request;
+}
+break;
+default:
+scsi_req_build_sense(req, SENSE_CODE(LUN_NOT_SUPPORTED));
+scsi_req_complete(req, CHECK_CONDITION);
+return 0;
+illegal_request:
+scsi_req_build_sense(req, SENSE_CODE(INVALID_FIELD));
+scsi_req_complete(req, CHECK_CONDITION);
+return 0;
+}
+
+if (!r->len) {
+scsi_req_complete(req, GOOD);
+}
+return r->len;
+}
+
+static void scsi_target_read_data(SCSIRequest *req)
+{
+SCSITargetReq *r = DO_UPCAST(SCSITargetReq, req, req);
+uint32_t n;
+
+n = r->len;
+if (n > 0) {
+r->len = 0;
+scsi_req_data(&r->req, n);
+} else {
+scsi_req_complete(&r->req, GOOD);
+}
+}
+
+static uint8_t *scsi_target_get_buf(SCSIRequest *req)
+{
+SCSITargetReq *r = DO_UPCAST(SCSITargetReq, req, req);
+
+return r->buf;
+}
+
+struct SCSIReqOps reqops_target_command = {
+.size = sizeof(SCSITargetReq),
+.send_command = scsi_target_send_command,
+.read_data= scsi_target_read_data,
+.get_buf  = scsi_target_get_buf,
+};
+
+
 SCSIRequest *scsi_req_alloc(SCSIReqOps *reqops, SCSIDevice *d, uint32_t tag,
 uint32_t lun, void *hba_private)
 {
@@ -184,7 +350,14 @@ SCSIRequest *scsi_req_n

Re: [Qemu-devel] [PATCH V4 1/2] [SLIRP] Simple ARP table

2011-08-03 Thread Jan Kiszka
On 2011-08-02 15:19, Fabien Chouteau wrote:
> This patch adds a simple ARP table in Slirp and also adds handling of
> gratuitous ARP requests.
> 
> Signed-off-by: Fabien Chouteau 
> ---
>  Makefile.objs |2 +-
>  slirp/arp_table.c |   71 
> +
>  slirp/bootp.c |   21 +--
>  slirp/slirp.c |   63 ---
>  slirp/slirp.h |   47 --
>  5 files changed, 145 insertions(+), 59 deletions(-)
>  create mode 100644 slirp/arp_table.c
> 
> diff --git a/Makefile.objs b/Makefile.objs
> index 6991a9f..0c10557 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -151,7 +151,7 @@ common-obj-y += qemu-timer.o qemu-timer-common.o
> 
>  slirp-obj-y = cksum.o if.o ip_icmp.o ip_input.o ip_output.o
>  slirp-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o
> -slirp-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o
> +slirp-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o arp_table.o
>  common-obj-$(CONFIG_SLIRP) += $(addprefix slirp/, $(slirp-obj-y))
> 
>  # xen backend driver support
> diff --git a/slirp/arp_table.c b/slirp/arp_table.c
> new file mode 100644
> index 000..c259b42
> --- /dev/null
> +++ b/slirp/arp_table.c
> @@ -0,0 +1,71 @@
> +#include "slirp.h"
> +
> +void arp_table_add(Slirp *slirp, int ip_addr, uint8_t ethaddr[ETH_ALEN])
> +{
> +const in_addr_t broadcast_addr =
> +~slirp->vnetwork_mask.s_addr | slirp->vnetwork_addr.s_addr;
> +ArpTable *arptbl = &slirp->arp_table;
> +int i;
> +
> +DEBUG_CALL("arp_table_add");
> +DEBUG_ARG("ip = 0x%x", ip_addr);
> +DEBUG_ARGS((dfd, " hw addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
> +ethaddr[0], ethaddr[1], ethaddr[2],
> +ethaddr[3], ethaddr[4], ethaddr[5]));
> +
> +/* Check 0.0.0.0/8 invalid source-only addresses */
> +assert((ip_addr & htonl(~(0xf << 28))) != 0);
> +
> +if (ip_addr == 0x || ip_addr == broadcast_addr) {
> +/* Do not register broadcast addresses */
> +return;
> +}
> +
> +/* Search for an entry */
> +for (i = 0; i < ARP_TABLE_SIZE; i++) {
> +if (arptbl->table[i].ar_sip == ip_addr) {
> +/* Update the entry */
> +memcpy(arptbl->table[i].ar_sha, ethaddr, ETH_ALEN);
> +return;
> +}
> +}
> +
> +/* No entry found, create a new one */
> +arptbl->table[arptbl->next_victim].ar_sip = ip_addr;
> +memcpy(arptbl->table[arptbl->next_victim].ar_sha,  ethaddr, ETH_ALEN);
> +arptbl->next_victim = (arptbl->next_victim + 1) % ARP_TABLE_SIZE;
> +}
> +
> +bool arp_table_search(Slirp *slirp, int in_ip_addr,
> +  uint8_t out_ethaddr[ETH_ALEN])
> +{
> +const in_addr_t broadcast_addr =
> +~slirp->vnetwork_mask.s_addr | slirp->vnetwork_addr.s_addr;
> +ArpTable *arptbl = &slirp->arp_table;
> +int i;
> +
> +DEBUG_CALL("arp_table_search");
> +DEBUG_ARG("ip = 0x%x", in_ip_addr);
> +
> +/* Check 0.0.0.0/8 invalid source-only addresses */
> +assert((in_ip_addr & htonl(~(0xf << 28))) != 0);
> +
> +/* If broadcast address */
> +if (in_ip_addr == 0x || in_ip_addr == broadcast_addr) {
> +/* return Ethernet broadcast address */
> +memset(out_ethaddr, 0xff, ETH_ALEN);
> +return 1;
> +}
> +
> +for (i = 0; i < ARP_TABLE_SIZE; i++) {
> +if (arptbl->table[i].ar_sip == in_ip_addr) {
> +memcpy(out_ethaddr, arptbl->table[i].ar_sha,  ETH_ALEN);
> +DEBUG_ARGS((dfd, " found hw addr = 
> %02x:%02x:%02x:%02x:%02x:%02x\n",
> +out_ethaddr[0], out_ethaddr[1], out_ethaddr[2],
> +out_ethaddr[3], out_ethaddr[4], out_ethaddr[5]));
> +return 1;
> +}
> +}
> +
> +return 0;
> +}
> diff --git a/slirp/bootp.c b/slirp/bootp.c
> index 1eb2ed1..efd1fe7 100644
> --- a/slirp/bootp.c
> +++ b/slirp/bootp.c
> @@ -149,6 +149,7 @@ static void bootp_reply(Slirp *slirp, const struct 
> bootp_t *bp)
>  struct in_addr preq_addr;
>  int dhcp_msg_type, val;
>  uint8_t *q;
> +uint8_t client_ethaddr[ETH_ALEN];
> 
>  /* extract exact DHCP msg type */
>  dhcp_decode(bp, &dhcp_msg_type, &preq_addr);
> @@ -164,8 +165,9 @@ static void bootp_reply(Slirp *slirp, const struct 
> bootp_t *bp)
>  if (dhcp_msg_type != DHCPDISCOVER &&
>  dhcp_msg_type != DHCPREQUEST)
>  return;
> -/* XXX: this is a hack to get the client mac address */
> -memcpy(slirp->client_ethaddr, bp->bp_hwaddr, 6);
> +
> +/* Get client's hardware address from bootp request */
> +memcpy(client_ethaddr, bp->bp_hwaddr, ETH_ALEN);
> 
>  m = m_get(slirp);
>  if (!m) {
> @@ -178,25 +180,25 @@ static void bootp_reply(Slirp *slirp, const struct 
> bootp_t *bp)
> 
>  if (dhcp_msg_type == DHCPDISCOVER) {
>  if (preq_addr.s_addr != htonl(0L)) {

[Qemu-devel] [PATCH 04/16] scsi: move sense handling to generic code

2011-08-03 Thread Paolo Bonzini
With this patch, sense data is stored in the generic data structures
for SCSI devices and requests.  The SCSI layer takes care of storing
sense data in the SCSIDevice for the subsequent REQUEST SENSE command.

At the same time, get_sense is removed and scsi_req_get_sense can use
an entirely generic implementation.

Signed-off-by: Paolo Bonzini 
---
 hw/scsi-bus.c |   79 +---
 hw/scsi-disk.c|   69 +++---
 hw/scsi-generic.c |   76 +++---
 hw/scsi.h |   10 +-
 trace-events  |1 +
 5 files changed, 117 insertions(+), 118 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index bff2f5b..067a615 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -7,6 +7,8 @@
 #include "trace.h"
 
 static char *scsibus_get_fw_dev_path(DeviceState *dev);
+static int scsi_build_sense(uint8_t *in_buf, int in_len,
+uint8_t *buf, int len, bool fixed);
 
 static struct BusInfo scsi_bus_info = {
 .name  = "SCSI",
@@ -144,6 +146,7 @@ SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, 
uint32_t tag,
 req->lun = lun;
 req->hba_private = hba_private;
 req->status = -1;
+req->sense_len = 0;
 trace_scsi_req_alloc(req->dev->id, req->lun, req->tag);
 return req;
 }
@@ -161,11 +164,28 @@ uint8_t *scsi_req_get_buf(SCSIRequest *req)
 
 int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len)
 {
-if (req->dev->info->get_sense) {
-return req->dev->info->get_sense(req, buf, len);
-} else {
+assert(len >= 14);
+if (!req->sense_len) {
 return 0;
 }
+return scsi_build_sense(req->sense, req->sense_len, buf, len, true);
+}
+
+int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed)
+{
+return scsi_build_sense(dev->sense, dev->sense_len, buf, len, fixed);
+}
+
+void scsi_req_build_sense(SCSIRequest *req, SCSISense sense)
+{
+trace_scsi_req_build_sense(req->dev->id, req->lun, req->tag,
+   sense.key, sense.asc, sense.ascq);
+memset(req->sense, 0, 18);
+req->sense[0] = 0xf0;
+req->sense[2] = sense.key;
+req->sense[12] = sense.asc;
+req->sense[13] = sense.ascq;
+req->sense_len = 18;
 }
 
 int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf)
@@ -486,14 +506,40 @@ const struct SCSISense sense_code_LUN_FAILURE = {
 /*
  * scsi_build_sense
  *
- * Build a sense buffer
+ * Convert between fixed and descriptor sense buffers
  */
-int scsi_build_sense(SCSISense sense, uint8_t *buf, int len, int fixed)
+int scsi_build_sense(uint8_t *in_buf, int in_len,
+ uint8_t *buf, int len, bool fixed)
 {
+bool fixed_in;
+SCSISense sense;
 if (!fixed && len < 8) {
 return 0;
 }
 
+if (in_len == 0) {
+sense.key = NO_SENSE;
+sense.asc = 0;
+sense.ascq = 0;
+} else {
+fixed_in = (in_buf[0] & 2) == 0;
+
+if (fixed == fixed_in) {
+memcpy(buf, in_buf, MIN(len, in_len));
+return MIN(len, in_len);
+}
+
+if (fixed_in) {
+sense.key = in_buf[2];
+sense.asc = in_buf[12];
+sense.ascq = in_buf[13];
+} else {
+sense.key = in_buf[1];
+sense.asc = in_buf[2];
+sense.ascq = in_buf[3];
+}
+}
+
 memset(buf, 0, len);
 if (fixed) {
 /* Return fixed format sense buffer */
@@ -676,6 +722,17 @@ void scsi_req_complete(SCSIRequest *req, int status)
 {
 assert(req->status == -1);
 req->status = status;
+
+assert(req->sense_len < sizeof(req->sense));
+if (status == GOOD) {
+req->sense_len = 0;
+}
+
+if (req->sense_len) {
+memcpy(req->dev->sense, req->sense, req->sense_len);
+}
+req->dev->sense_len = req->sense_len;
+
 scsi_req_ref(req);
 scsi_req_dequeue(req);
 req->bus->ops->complete(req, req->status);
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 8beaebf..4c1e58f 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -73,7 +73,6 @@ struct SCSIDiskState
 QEMUBH *bh;
 char *version;
 char *serial;
-SCSISense sense;
 SCSIDriveKind drive_kind;
 };
 
@@ -100,20 +99,13 @@ static void scsi_free_request(SCSIRequest *req)
 qemu_vfree(r->iov.iov_base);
 }
 
-static void scsi_disk_clear_sense(SCSIDiskState *s)
+/* Helper function for command completion with sense.  */
+static void scsi_check_condition(SCSIDiskReq *r, SCSISense sense)
 {
-memset(&s->sense, 0, sizeof(s->sense));
-}
-
-/* Helper function for command completion.  */
-static void scsi_command_complete(SCSIDiskReq *r, int status, SCSISense sense)
-{
-SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
-
 DPRINTF("Command complete tag=0x%x status=%d sense=%d/%d/%d\n",
 r->req.tag, status, sense.key, sense.asc, sense.ascq);
-s->sense = sense;
-scsi

[Qemu-devel] [PATCH 10/16] scsi: move request parsing to common code

2011-08-03 Thread Paolo Bonzini
Also introduce the first occurrence of "independent" SCSIReqOps,
to handle invalid commands in common code.

Signed-off-by: Paolo Bonzini 
---
 hw/scsi-bus.c |   53 ++---
 hw/scsi-disk.c|5 -
 hw/scsi-generic.c |9 -
 hw/scsi.h |1 -
 4 files changed, 38 insertions(+), 30 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 07d8704..01dbe02 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -7,6 +7,7 @@
 #include "trace.h"
 
 static char *scsibus_get_fw_dev_path(DeviceState *dev);
+static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf);
 static int scsi_build_sense(uint8_t *in_buf, int in_len,
 uint8_t *buf, int len, bool fixed);
 
@@ -134,6 +135,20 @@ int scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
 return res;
 }
 
+/* SCSIReqOps implementation for invalid commands.  */
+
+static int32_t scsi_invalid_command(SCSIRequest *req, uint8_t *buf)
+{
+scsi_req_build_sense(req, SENSE_CODE(INVALID_OPCODE));
+scsi_req_complete(req, CHECK_CONDITION);
+return 0;
+}
+
+struct SCSIReqOps reqops_invalid_opcode = {
+.size = sizeof(SCSIRequest),
+.send_command = scsi_invalid_command
+};
+
 SCSIRequest *scsi_req_alloc(SCSIReqOps *reqops, SCSIDevice *d, uint32_t tag,
 uint32_t lun, void *hba_private)
 {
@@ -157,8 +172,22 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, 
uint32_t lun,
   uint8_t *buf, void *hba_private)
 {
 SCSIRequest *req;
-req = d->info->alloc_req(d, tag, lun, hba_private);
-memcpy(req->cmd.buf, buf, 16);
+SCSICommand cmd;
+
+if (scsi_req_parse(&cmd, d, buf) != 0) {
+trace_scsi_req_parse_bad(d->id, lun, tag, buf[0]);
+req = scsi_req_alloc(&reqops_invalid_opcode, d, tag, lun, hba_private);
+} else {
+trace_scsi_req_parsed(d->id, lun, tag, buf[0],
+  cmd.mode, cmd.xfer);
+if (req->cmd.lba != -1) {
+trace_scsi_req_parsed_lba(d->id, lun, tag, buf[0],
+  cmd.lba);
+}
+req = d->info->alloc_req(d, tag, lun, hba_private);
+}
+
+req->cmd = cmd;
 return req;
 }
 
@@ -426,27 +455,21 @@ static uint64_t scsi_cmd_lba(SCSICommand *cmd)
 return lba;
 }
 
-int scsi_req_parse(SCSIRequest *req, uint8_t *buf)
+int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
 {
 int rc;
 
-if (req->dev->type == TYPE_TAPE) {
-rc = scsi_req_stream_length(&req->cmd, req->dev, buf);
+if (dev->type == TYPE_TAPE) {
+rc = scsi_req_stream_length(cmd, dev, buf);
 } else {
-rc = scsi_req_length(&req->cmd, req->dev, buf);
+rc = scsi_req_length(cmd, dev, buf);
 }
 if (rc != 0)
 return rc;
 
-assert(buf == req->cmd.buf);
-scsi_cmd_xfer_mode(&req->cmd);
-req->cmd.lba = scsi_cmd_lba(&req->cmd);
-trace_scsi_req_parsed(req->dev->id, req->lun, req->tag, buf[0],
-  req->cmd.mode, req->cmd.xfer);
-if (req->cmd.lba != -1) {
-trace_scsi_req_parsed_lba(req->dev->id, req->lun, req->tag, buf[0],
-  req->cmd.lba);
-}
+memcpy(cmd->buf, buf, cmd->len);
+scsi_cmd_xfer_mode(cmd);
+cmd->lba = scsi_cmd_lba(cmd);
 return 0;
 }
 
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index ceb0e0a..64aa141 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -974,11 +974,6 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t 
*buf)
 outbuf = (uint8_t *)r->iov.iov_base;
 DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", req->lun, req->tag, 
buf[0]);
 
-if (scsi_req_parse(&r->req, buf) != 0) {
-BADF("Unsupported command length, command %x\n", command);
-scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
-return 0;
-}
 #ifdef DEBUG_SCSI
 {
 int i;
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 699831a..e91c32e 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -84,10 +84,6 @@ static void scsi_command_complete(void *opaque, int ret)
 case -EDOM:
 status = TASK_SET_FULL;
 break;
-case -EINVAL:
-status = CHECK_CONDITION;
-scsi_req_build_sense(&r->req, SENSE_CODE(INVALID_FIELD));
-break;
 case -ENOMEM:
 status = CHECK_CONDITION;
 scsi_req_build_sense(&r->req, SENSE_CODE(TARGET_FAILURE));
@@ -298,11 +294,6 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t 
*cmd)
 return 0;
 }
 
-if (-1 == scsi_req_parse(&r->req, cmd)) {
-BADF("Unsupported command length, command %x\n", cmd[0]);
-scsi_command_complete(r, -EINVAL);
-return 0;
-}
 scsi_req_fixup(&r->req);
 
 DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun, tag,
diff --git a/hw/scsi.h b/hw/scsi.h
index 5a1bbe2..dec814a

Re: [Qemu-devel] modelling omap_gpmc with the hierarchical memory API

2011-08-03 Thread Avi Kivity

On 08/03/2011 12:10 PM, Peter Maydell wrote:

[*] I did convince myself that you do want a sysbus bus on each
chip select, because in theory in the hardware you could put an
external address decoder on the gpmc_a[] bus and hang multiple
devices off one chipselect. So that's a sysbus, really.


No, you've added a device which is yet another bus.

--
error compiling committee.c: too many arguments to function




[Qemu-devel] [PATCH 08/16] scsi: introduce SCSICommand

2011-08-03 Thread Paolo Bonzini
This struct is currently unnamed.  Give it a name and use it
explicitly to decouple (some parts of) CDB parsing from
SCSIRequest.

Signed-off-by: Paolo Bonzini 
---
 hw/scsi-bus.c |   95 +
 hw/scsi.h |   17 ++
 2 files changed, 58 insertions(+), 54 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 9b81b9c..579f6b4 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -217,35 +217,35 @@ static void scsi_req_dequeue(SCSIRequest *req)
 }
 }
 
-static int scsi_req_length(SCSIRequest *req, uint8_t *cmd)
+static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
 {
-switch (cmd[0] >> 5) {
+switch (buf[0] >> 5) {
 case 0:
-req->cmd.xfer = cmd[4];
-req->cmd.len = 6;
+cmd->xfer = buf[4];
+cmd->len = 6;
 /* length 0 means 256 blocks */
-if (req->cmd.xfer == 0)
-req->cmd.xfer = 256;
+if (cmd->xfer == 0) {
+cmd->xfer = 256;
+}
 break;
 case 1:
 case 2:
-req->cmd.xfer = cmd[8] | (cmd[7] << 8);
-req->cmd.len = 10;
+cmd->xfer = buf[8] | (buf[7] << 8);
+cmd->len = 10;
 break;
 case 4:
-req->cmd.xfer = cmd[13] | (cmd[12] << 8) | (cmd[11] << 16) | (cmd[10] 
<< 24);
-req->cmd.len = 16;
+cmd->xfer = buf[13] | (buf[12] << 8) | (buf[11] << 16) | (buf[10] << 
24);
+cmd->len = 16;
 break;
 case 5:
-req->cmd.xfer = cmd[9] | (cmd[8] << 8) | (cmd[7] << 16) | (cmd[6] << 
24);
-req->cmd.len = 12;
+cmd->xfer = buf[9] | (buf[8] << 8) | (buf[7] << 16) | (buf[6] << 24);
+cmd->len = 12;
 break;
 default:
-trace_scsi_req_parse_bad(req->dev->id, req->lun, req->tag, cmd[0]);
 return -1;
 }
 
-switch(cmd[0]) {
+switch (buf[0]) {
 case TEST_UNIT_READY:
 case REZERO_UNIT:
 case START_STOP:
@@ -266,27 +266,27 @@ static int scsi_req_length(SCSIRequest *req, uint8_t *cmd)
 case WRITE_LONG:
 case MOVE_MEDIUM:
 case UPDATE_BLOCK:
-req->cmd.xfer = 0;
+cmd->xfer = 0;
 break;
 case MODE_SENSE:
 break;
 case WRITE_SAME:
-req->cmd.xfer = 1;
+cmd->xfer = 1;
 break;
 case READ_CAPACITY:
-req->cmd.xfer = 8;
+cmd->xfer = 8;
 break;
 case READ_BLOCK_LIMITS:
-req->cmd.xfer = 6;
+cmd->xfer = 6;
 break;
 case READ_POSITION:
-req->cmd.xfer = 20;
+cmd->xfer = 20;
 break;
 case SEND_VOLUME_TAG:
-req->cmd.xfer *= 40;
+cmd->xfer *= 40;
 break;
 case MEDIUM_SCAN:
-req->cmd.xfer *= 8;
+cmd->xfer *= 8;
 break;
 case WRITE_10:
 case WRITE_VERIFY:
@@ -295,7 +295,7 @@ static int scsi_req_length(SCSIRequest *req, uint8_t *cmd)
 case WRITE_VERIFY_12:
 case WRITE_16:
 case WRITE_VERIFY_16:
-req->cmd.xfer *= req->dev->blocksize;
+cmd->xfer *= dev->blocksize;
 break;
 case READ_10:
 case READ_6:
@@ -303,50 +303,51 @@ static int scsi_req_length(SCSIRequest *req, uint8_t *cmd)
 case RECOVER_BUFFERED_DATA:
 case READ_12:
 case READ_16:
-req->cmd.xfer *= req->dev->blocksize;
+cmd->xfer *= dev->blocksize;
 break;
 case INQUIRY:
-req->cmd.xfer = cmd[4] | (cmd[3] << 8);
+cmd->xfer = buf[4] | (buf[3] << 8);
 break;
 case MAINTENANCE_OUT:
 case MAINTENANCE_IN:
-if (req->dev->type == TYPE_ROM) {
+if (dev->type == TYPE_ROM) {
 /* GPCMD_REPORT_KEY and GPCMD_SEND_KEY from multi media commands */
-req->cmd.xfer = cmd[9] | (cmd[8] << 8);
+cmd->xfer = buf[9] | (buf[8] << 8);
 }
 break;
 }
 return 0;
 }
 
-static int scsi_req_stream_length(SCSIRequest *req, uint8_t *cmd)
+static int scsi_req_stream_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t 
*buf)
 {
-switch(cmd[0]) {
+switch (buf[0]) {
 /* stream commands */
 case READ_6:
 case READ_REVERSE:
 case RECOVER_BUFFERED_DATA:
 case WRITE_6:
-req->cmd.len = 6;
-req->cmd.xfer = cmd[4] | (cmd[3] << 8) | (cmd[2] << 16);
-if (cmd[1] & 0x01) /* fixed */
-req->cmd.xfer *= req->dev->blocksize;
+cmd->len = 6;
+cmd->xfer = buf[4] | (buf[3] << 8) | (buf[2] << 16);
+if (buf[1] & 0x01) { /* fixed */
+cmd->xfer *= dev->blocksize;
+}
 break;
 case REWIND:
 case START_STOP:
-req->cmd.len = 6;
-req->cmd.xfer = 0;
+cmd->len = 6;
+cmd->xfer = 0;
 break;
 /* generic commands */
 default:
-return scsi_req_length(req, cmd);
+return scsi_req_length(cmd, dev, buf);
 }
 return 0;
 }
 
-static void scsi_req_xfer_mode(SCSIRequest *req)
+static void scsi_cmd_xfer_mode(SCSICommand *cmd)
 {
- 

Re: [Qemu-devel] qemu-kvm aborts - vhost_dev_unassign_memory: Assertion `to >= 0' failed.

2011-08-03 Thread Wen Congyang
At 08/03/2011 05:01 PM, Avi Kivity Write:
> On 08/01/2011 08:44 PM, David Ahern wrote:
>> qemu-kvm.git as of:
>>
>> commit dacdc4b10bafbb21120e1c24a9665444768ef999
>> Merge: 7b69d4f 0af4922
>> Author: Avi Kivity
>> Date:   Sun Jul 31 11:42:26 2011 +0300
>>
>>  Merge branch 'upstream-merge' into next
>>
>> is aborting with the error:
>>
>> qemu-kvm: qemu-kvm.git/hw/vhost.c:123: vhost_dev_unassign_memory:
>> Assertion `to>= 0' failed.
>> Aborted
> 
> Full command line please?

I use the upstream qemu, and meet the same problem.

I use libvirt to start vm. Here is the command line:
2011-08-03 13:58:21.157: starting up
LC_ALL=C 
PATH=/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
 HOME=/root USER=root LOGNAME=root QEMU_AUDIO_DRV=none /usr/local2/bin/
qemu-system-x86_64 -S -M pc-0.14 -enable-kvm -m 512 -smp 
4,sockets=4,cores=1,threads=1 -name vm1 -uuid 
a1cd0309-72a3-48b7-835d-212c86de407f -nodefconfig -nodefaults -chardev soc
ket,id=charmonitor,path=/var/lib/libvirt/qemu/vm1.monitor,server,nowait -mon 
chardev=charmonitor,id=monitor,mode=control -rtc base=localtime -no-shutdown 
-device lsi,id=scsi0,bu
s=pci.0,multifunction=on,addr=0x5.0x0 -drive 
file=/var/lib/libvirt/images/vm1.img,if=none,id=drive-ide0-0-0,format=qcow2,cache=writethrough
 -device ide-drive,bus=ide.0,unit=0,dr
ive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 -drive 
file=/var/lib/libvirt/images/test.iso,if=none,media=cdrom,id=drive-ide0-1-0,readonly=on,format=raw
 -device ide-drive,bus=ide.1,
unit=0,drive=drive-ide0-1-0,id=ide0-1-0 -drive 
file=/var/lib/libvirt/images/test.img,if=none,id=drive-virtio-disk0,format=qcow2,serial=Fujitsu-virtio-0001
 -device virtio-blk-pci
,bus=pci.0,multifunction=on,addr=0x7.0x0,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=2
 -netdev tap,fd=25,id=hostnet0,vhost=on,vhostfd=26 -device 
virtio-net-pci,netdev=hos
tnet0,id=net0,mac=52:54:00:04:72:f2,bus=pci.0,multifunction=on,addr=0x3.0x0 
-netdev tap,fd=27,id=hostnet1 -device 
rtl8139,netdev=hostnet1,id=net1,mac=52:54:00:04:72:f3,bus=pci.0
,multifunction=on,addr=0x6.0x0 -chardev pty,id=charserial0 -device 
isa-serial,chardev=charserial0,id=serial0 -usb -vnc 0.0.0.0:1 -vga cirrus 
-device virtio-balloon-pci,id=balloo
n0,bus=pci.0,multifunction=on,addr=0x4.0x0
char device redirected to /dev/pts/7
qemu-system-x86_64: /home/wency/source/qemu/hw/vhost.c:123: 
vhost_dev_unassign_memory: Assertion `to >= 0' failed.
2011-08-03 13:58:21.400: shutting down

If I do not use vhost(command line does not include vhost=on,vhostfd=26), the 
vm can start succefully.

Thanks
Wen Congyang

> 




[Qemu-devel] [PATCH 15/16] scsi: report unit attention on reset

2011-08-03 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini 
---
 hw/scsi-bus.c |3 ++-
 hw/scsi-disk.c|4 ++--
 hw/scsi-generic.c |4 ++--
 hw/scsi.h |2 +-
 4 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index a5bb517..f6fb4f0 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -1089,7 +1089,7 @@ void scsi_req_abort(SCSIRequest *req, int status)
 scsi_req_complete(req, status);
 }
 
-void scsi_device_purge_requests(SCSIDevice *sdev)
+void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense)
 {
 SCSIRequest *req;
 
@@ -1097,6 +1097,7 @@ void scsi_device_purge_requests(SCSIDevice *sdev)
 req = QTAILQ_FIRST(&sdev->requests);
 scsi_req_cancel(req);
 }
+sdev->unit_attention = sense;
 }
 
 static char *scsibus_get_fw_dev_path(DeviceState *dev)
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 5f21d68..655fcda 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1098,7 +1098,7 @@ static void scsi_disk_reset(DeviceState *dev)
 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev.qdev, dev);
 uint64_t nb_sectors;
 
-scsi_device_purge_requests(&s->qdev);
+scsi_device_purge_requests(&s->qdev, SENSE_CODE(RESET));
 
 bdrv_get_geometry(s->bs, &nb_sectors);
 nb_sectors /= s->cluster_size;
@@ -1112,7 +1112,7 @@ static void scsi_destroy(SCSIDevice *dev)
 {
 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
 
-scsi_device_purge_requests(&s->qdev);
+scsi_device_purge_requests(&s->qdev, SENSE_CODE(NO_SENSE));
 blockdev_mark_auto_del(s->qdev.conf.bs);
 }
 
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index c122ad3..e8053da 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -381,14 +381,14 @@ static void scsi_generic_reset(DeviceState *dev)
 {
 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev.qdev, dev);
 
-scsi_device_purge_requests(&s->qdev);
+scsi_device_purge_requests(&s->qdev, SENSE_CODE(RESET));
 }
 
 static void scsi_destroy(SCSIDevice *d)
 {
 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
 
-scsi_device_purge_requests(&s->qdev);
+scsi_device_purge_requests(&s->qdev, SENSE_CODE(NO_SENSE));
 blockdev_mark_auto_del(s->qdev.conf.bs);
 }
 
diff --git a/hw/scsi.h b/hw/scsi.h
index 09c3606..98fd689 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -187,7 +187,7 @@ uint8_t *scsi_req_get_buf(SCSIRequest *req);
 int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len);
 void scsi_req_abort(SCSIRequest *req, int status);
 void scsi_req_cancel(SCSIRequest *req);
-void scsi_device_purge_requests(SCSIDevice *sdev);
+void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense);
 int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed);
 
 #endif
-- 
1.7.6





[Qemu-devel] [PATCH 07/16] scsi: pass cdb already to scsi_req_new

2011-08-03 Thread Paolo Bonzini
Right now the CDB is not passed to the SCSIBus until scsi_req_enqueue.
Passing it to scsi_req_new will let scsi_req_new dispatch common requests
through different reqops.

Moving the memcpy to scsi_req_new is a hack that will go away as
soon as scsi_req_new will also take care of the parsing.

Signed-off-by: Paolo Bonzini 
---
 hw/esp.c |4 ++--
 hw/lsi53c895a.c  |4 ++--
 hw/scsi-bus.c|   13 -
 hw/scsi.h|4 ++--
 hw/spapr_vscsi.c |4 ++--
 hw/usb-msd.c |4 ++--
 6 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/hw/esp.c b/hw/esp.c
index 9ddd637..be3a35d 100644
--- a/hw/esp.c
+++ b/hw/esp.c
@@ -244,8 +244,8 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t 
busid)
 
 DPRINTF("do_busid_cmd: busid 0x%x\n", busid);
 lun = busid & 7;
-s->current_req = scsi_req_new(s->current_dev, 0, lun, NULL);
-datalen = scsi_req_enqueue(s->current_req, buf);
+s->current_req = scsi_req_new(s->current_dev, 0, lun, buf, NULL);
+datalen = scsi_req_enqueue(s->current_req);
 s->ti_size = datalen;
 if (datalen != 0) {
 s->rregs[ESP_RSTAT] = STAT_TC;
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index e9904c4..dac176a 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -782,10 +782,10 @@ static void lsi_do_command(LSIState *s)
 assert(s->current == NULL);
 s->current = qemu_mallocz(sizeof(lsi_request));
 s->current->tag = s->select_tag;
-s->current->req = scsi_req_new(dev, s->current->tag, s->current_lun,
+s->current->req = scsi_req_new(dev, s->current->tag, s->current_lun, buf,
s->current);
 
-n = scsi_req_enqueue(s->current->req, buf);
+n = scsi_req_enqueue(s->current->req);
 if (n) {
 if (n > 0) {
 lsi_set_phase(s, PHASE_DI);
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index be73f29..9b81b9c 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -153,9 +153,12 @@ SCSIRequest *scsi_req_alloc(SCSIReqOps *reqops, SCSIDevice 
*d, uint32_t tag,
 }
 
 SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
-  void *hba_private)
+  uint8_t *buf, void *hba_private)
 {
-return d->info->alloc_req(d, tag, lun, hba_private);
+SCSIRequest *req;
+req = d->info->alloc_req(d, tag, lun, hba_private);
+memcpy(req->cmd.buf, buf, 16);
+return req;
 }
 
 uint8_t *scsi_req_get_buf(SCSIRequest *req)
@@ -189,7 +192,7 @@ void scsi_req_build_sense(SCSIRequest *req, SCSISense sense)
 req->sense_len = 18;
 }
 
-int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf)
+int32_t scsi_req_enqueue(SCSIRequest *req)
 {
 int32_t rc;
 
@@ -199,7 +202,7 @@ int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf)
 QTAILQ_INSERT_TAIL(&req->dev->requests, req, next);
 
 scsi_req_ref(req);
-rc = req->ops->send_command(req, buf);
+rc = req->ops->send_command(req, req->cmd.buf);
 scsi_req_unref(req);
 return rc;
 }
@@ -433,7 +436,7 @@ int scsi_req_parse(SCSIRequest *req, uint8_t *buf)
 if (rc != 0)
 return rc;
 
-memcpy(req->cmd.buf, buf, req->cmd.len);
+assert(buf == req->cmd.buf);
 scsi_req_xfer_mode(req);
 req->cmd.lba = scsi_req_lba(req);
 trace_scsi_req_parsed(req->dev->id, req->lun, req->tag, buf[0],
diff --git a/hw/scsi.h b/hw/scsi.h
index 5c0e076..7ed7550 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -154,8 +154,8 @@ 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_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
-  void *hba_private);
-int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf);
+  uint8_t *buf, void *hba_private);
+int32_t scsi_req_enqueue(SCSIRequest *req);
 void scsi_req_free(SCSIRequest *req);
 SCSIRequest *scsi_req_ref(SCSIRequest *req);
 void scsi_req_unref(SCSIRequest *req);
diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
index c65308c..d98d1fd 100644
--- a/hw/spapr_vscsi.c
+++ b/hw/spapr_vscsi.c
@@ -600,8 +600,8 @@ static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req)
 }
 
 req->lun = lun;
-req->sreq = scsi_req_new(sdev, req->qtag, lun, req);
-n = scsi_req_enqueue(req->sreq, srp->cmd.cdb);
+req->sreq = scsi_req_new(sdev, req->qtag, lun, srp->cmd.cdb, req);
+n = scsi_req_enqueue(req->sreq);
 
 dprintf("VSCSI: Queued command tag 0x%x CMD 0x%x ID %d LUN %d ret: %d\n",
 req->qtag, srp->cmd.cdb[0], id, lun, n);
diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index cdeac58..63305b8 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -380,8 +380,8 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p)
 s->tag, cbw.flags, cbw.cmd_len, s->data_len);
 s->residue = 0;
 s->scsi_len = 0;
-s->req = scsi_req_new(s->scsi_dev,

[Qemu-devel] [PATCH 06/16] scsi: move request-related callbacks from SCSIDeviceInfo to SCSIReqOps

2011-08-03 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini 
---
 hw/scsi-bus.c |   20 ++--
 hw/scsi-disk.c|   24 ++--
 hw/scsi-generic.c |   12 ++--
 hw/scsi.h |   13 +++--
 4 files changed, 29 insertions(+), 40 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 4709b19..be73f29 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -160,7 +160,7 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, 
uint32_t lun,
 
 uint8_t *scsi_req_get_buf(SCSIRequest *req)
 {
-return req->dev->info->get_buf(req);
+return req->ops->get_buf(req);
 }
 
 int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len)
@@ -199,7 +199,7 @@ int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf)
 QTAILQ_INSERT_TAIL(&req->dev->requests, req, next);
 
 scsi_req_ref(req);
-rc = req->dev->info->send_command(req, buf);
+rc = req->ops->send_command(req, buf);
 scsi_req_unref(req);
 return rc;
 }
@@ -663,8 +663,8 @@ SCSIRequest *scsi_req_ref(SCSIRequest *req)
 void scsi_req_unref(SCSIRequest *req)
 {
 if (--req->refcount == 0) {
-if (req->dev->info->free_req) {
-req->dev->info->free_req(req);
+if (req->ops->free_req) {
+req->ops->free_req(req);
 }
 qemu_free(req);
 }
@@ -676,9 +676,9 @@ void scsi_req_continue(SCSIRequest *req)
 {
 trace_scsi_req_continue(req->dev->id, req->lun, req->tag);
 if (req->cmd.mode == SCSI_XFER_TO_DEV) {
-req->dev->info->write_data(req);
+req->ops->write_data(req);
 } else {
-req->dev->info->read_data(req);
+req->ops->read_data(req);
 }
 }
 
@@ -742,8 +742,8 @@ void scsi_req_complete(SCSIRequest *req, int status)
 
 void scsi_req_cancel(SCSIRequest *req)
 {
-if (req->dev && req->dev->info->cancel_io) {
-req->dev->info->cancel_io(req);
+if (req->ops->cancel_io) {
+req->ops->cancel_io(req);
 }
 scsi_req_ref(req);
 scsi_req_dequeue(req);
@@ -755,8 +755,8 @@ void scsi_req_cancel(SCSIRequest *req)
 
 void scsi_req_abort(SCSIRequest *req, int status)
 {
-if (req->dev && req->dev->info->cancel_io) {
-req->dev->info->cancel_io(req);
+if (req->ops->cancel_io) {
+req->ops->cancel_io(req);
 }
 scsi_req_complete(req, status);
 }
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 7483638..ceb0e0a 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1223,6 +1223,12 @@ static int scsi_disk_initfn(SCSIDevice *dev)
 
 static SCSIReqOps scsi_disk_reqops = {
 .size = sizeof(SCSIDiskReq),
+.free_req = scsi_free_request,
+.send_command = scsi_send_command,
+.read_data= scsi_read_data,
+.write_data   = scsi_write_data,
+.cancel_io= scsi_cancel_io,
+.get_buf  = scsi_get_buf,
 };
 
 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag,
@@ -1253,12 +1259,6 @@ static SCSIDeviceInfo scsi_disk_info[] = {
 .init = scsi_hd_initfn,
 .destroy  = scsi_destroy,
 .alloc_req= scsi_new_request,
-.free_req = scsi_free_request,
-.send_command = scsi_send_command,
-.read_data= scsi_read_data,
-.write_data   = scsi_write_data,
-.cancel_io= scsi_cancel_io,
-.get_buf  = scsi_get_buf,
 .qdev.props   = (Property[]) {
 DEFINE_SCSI_DISK_PROPERTIES(),
 DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
@@ -1273,12 +1273,6 @@ static SCSIDeviceInfo scsi_disk_info[] = {
 .init = scsi_cd_initfn,
 .destroy  = scsi_destroy,
 .alloc_req= scsi_new_request,
-.free_req = scsi_free_request,
-.send_command = scsi_send_command,
-.read_data= scsi_read_data,
-.write_data   = scsi_write_data,
-.cancel_io= scsi_cancel_io,
-.get_buf  = scsi_get_buf,
 .qdev.props   = (Property[]) {
 DEFINE_SCSI_DISK_PROPERTIES(),
 DEFINE_PROP_END_OF_LIST(),
@@ -1292,12 +1286,6 @@ static SCSIDeviceInfo scsi_disk_info[] = {
 .init = scsi_disk_initfn,
 .destroy  = scsi_destroy,
 .alloc_req= scsi_new_request,
-.free_req = scsi_free_request,
-.send_command = scsi_send_command,
-.read_data= scsi_read_data,
-.write_data   = scsi_write_data,
-.cancel_io= scsi_cancel_io,
-.get_buf  = scsi_get_buf,
 .qdev.props   = (Property[]) {
 DEFINE_SCSI_DISK_PROPERTIES(),
 DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 87fb6ab..453a295 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -491,6 +491,12 @@ static int scsi_generic_initfn(SCSIDevice *dev)
 
 static SCSIReqOps scsi_generic_req_ops = {
 .size = sizeof(SCSIGenericReq),
+.free_req = scsi_free_request,
+.send_comma

[Qemu-devel] [PATCH 13/16] scsi: add a bunch more common sense codes

2011-08-03 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini 
---
 hw/scsi-bus.c |   30 ++
 hw/scsi.h |   12 
 2 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index fbb9801..0e2e4cd 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -698,6 +698,16 @@ const struct SCSISense sense_code_LUN_NOT_SUPPORTED = {
 .key = ILLEGAL_REQUEST, .asc = 0x25, .ascq = 0x00
 };
 
+/* Illegal request, Saving parameters not supported */
+const struct SCSISense sense_code_SAVING_PARAMS_NOT_SUPPORTED = {
+.key = ILLEGAL_REQUEST, .asc = 0x39, .ascq = 0x00
+};
+
+/* Illegal request, Incompatible medium installed */
+const struct SCSISense sense_code_INCOMPATIBLE_MEDIUM = {
+.key = ILLEGAL_REQUEST, .asc = 0x30, .ascq = 0x00
+};
+
 /* Command aborted, I/O process terminated */
 const struct SCSISense sense_code_IO_ERROR = {
 .key = ABORTED_COMMAND, .asc = 0x00, .ascq = 0x06
@@ -713,6 +723,26 @@ const struct SCSISense sense_code_LUN_FAILURE = {
 .key = ABORTED_COMMAND, .asc = 0x3e, .ascq = 0x01
 };
 
+/* Unit attention, Power on, reset or bus device reset occurred */
+const struct SCSISense sense_code_RESET = {
+.key = UNIT_ATTENTION, .asc = 0x29, .ascq = 0x00
+};
+
+/* Unit attention, Medium may have changed */
+const struct SCSISense sense_code_MEDIUM_CHANGED = {
+.key = UNIT_ATTENTION, .asc = 0x28, .ascq = 0x00
+};
+
+/* Unit attention, Reported LUNs data has changed */
+const struct SCSISense sense_code_REPORTED_LUNS_CHANGED = {
+.key = UNIT_ATTENTION, .asc = 0x3f, .ascq = 0x0e
+};
+
+/* Unit attention, Device internal reset */
+const struct SCSISense sense_code_DEVICE_INTERNAL_RESET = {
+.key = UNIT_ATTENTION, .asc = 0x29, .ascq = 0x04
+};
+
 /*
  * scsi_build_sense
  *
diff --git a/hw/scsi.h b/hw/scsi.h
index dec814a..4d5b596 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -144,12 +144,24 @@ extern const struct SCSISense sense_code_LBA_OUT_OF_RANGE;
 extern const struct SCSISense sense_code_INVALID_FIELD;
 /* Illegal request, LUN not supported */
 extern const struct SCSISense sense_code_LUN_NOT_SUPPORTED;
+/* Illegal request, Saving parameters not supported */
+extern const struct SCSISense sense_code_SAVING_PARAMS_NOT_SUPPORTED;
+/* Illegal request, Incompatible format */
+extern const struct SCSISense sense_code_INCOMPATIBLE_FORMAT;
 /* Command aborted, I/O process terminated */
 extern const struct SCSISense sense_code_IO_ERROR;
 /* Command aborted, I_T Nexus loss occurred */
 extern const struct SCSISense sense_code_I_T_NEXUS_LOSS;
 /* Command aborted, Logical Unit failure */
 extern const struct SCSISense sense_code_LUN_FAILURE;
+/* Unit attention, Power on, reset or bus device reset occurred */
+extern const struct SCSISense sense_code_RESET;
+/* Unit attention, Medium may have changed*/
+extern const struct SCSISense sense_code_MEDIUM_CHANGED;
+/* Unit attention, Reported LUNs data has changed */
+extern const struct SCSISense sense_code_REPORTED_LUNS_CHANGED;
+/* Unit attention, Device internal reset */
+extern const struct SCSISense sense_code_DEVICE_INTERNAL_RESET;
 
 #define SENSE_CODE(x) sense_code_ ## x
 
-- 
1.7.6





[Qemu-devel] [PATCH 01/16] scsi-disk: no need to call scsi_req_data on a short read

2011-08-03 Thread Paolo Bonzini
In fact, if the HBA's transfer_data callback goes on with scsi_req_continue
the request will be completed successfully instead of showing a failure.
It can even cause a segmentation fault.

An easy way to trigger it is "eject -f cd" during installation (during media
test if the installer does something like that).

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

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index f42a5d1..814bf74 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -217,9 +217,6 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, 
int type)
 bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
 vm_stop(VMSTOP_DISKFULL);
 } else {
-if (type == SCSI_REQ_STATUS_RETRY_READ) {
-scsi_req_data(&r->req, 0);
-}
 switch (error) {
 case ENOMEM:
 scsi_command_complete(r, CHECK_CONDITION,
-- 
1.7.6





[Qemu-devel] [PATCH 03/16] scsi: pass status when completing

2011-08-03 Thread Paolo Bonzini
A small improvement in the SCSI request API.  Pass the status
at the time the request is completed, so that we can assert that
no request is completed twice.  This would have detected the
problem fixed in the previous patch.

Signed-off-by: Paolo Bonzini 
---
 hw/scsi-bus.c |8 
 hw/scsi-disk.c|   15 ---
 hw/scsi-generic.c |   31 ---
 hw/scsi.h |2 +-
 4 files changed, 25 insertions(+), 31 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 8b1a412..bff2f5b 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -672,9 +672,10 @@ void scsi_req_print(SCSIRequest *req)
 }
 }
 
-void scsi_req_complete(SCSIRequest *req)
+void scsi_req_complete(SCSIRequest *req, int status)
 {
-assert(req->status != -1);
+assert(req->status == -1);
+req->status = status;
 scsi_req_ref(req);
 scsi_req_dequeue(req);
 req->bus->ops->complete(req, req->status);
@@ -696,11 +697,10 @@ void scsi_req_cancel(SCSIRequest *req)
 
 void scsi_req_abort(SCSIRequest *req, int status)
 {
-req->status = status;
 if (req->dev && req->dev->info->cancel_io) {
 req->dev->info->cancel_io(req);
 }
-scsi_req_complete(req);
+scsi_req_complete(req, status);
 }
 
 void scsi_device_purge_requests(SCSIDevice *sdev)
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 814bf74..8beaebf 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -105,21 +105,15 @@ static void scsi_disk_clear_sense(SCSIDiskState *s)
 memset(&s->sense, 0, sizeof(s->sense));
 }
 
-static void scsi_req_set_status(SCSIDiskReq *r, int status, SCSISense sense)
-{
-SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
-
-r->req.status = status;
-s->sense = sense;
-}
-
 /* Helper function for command completion.  */
 static void scsi_command_complete(SCSIDiskReq *r, int status, SCSISense sense)
 {
+SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
+
 DPRINTF("Command complete tag=0x%x status=%d sense=%d/%d/%d\n",
 r->req.tag, status, sense.key, sense.asc, sense.ascq);
-scsi_req_set_status(r, status, sense);
-scsi_req_complete(&r->req);
+s->sense = sense;
+scsi_req_complete(&r->req, status);
 }
 
 /* Cancel a pending data transfer.  */
@@ -979,7 +973,6 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r, 
uint8_t *outbuf)
 scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(INVALID_OPCODE));
 return -1;
 }
-scsi_req_set_status(r, GOOD, SENSE_CODE(NO_SENSE));
 return buflen;
 
 not_ready:
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 63361b3..f119f33 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -115,6 +115,7 @@ static void scsi_free_request(SCSIRequest *req)
 /* Helper function for command completion.  */
 static void scsi_command_complete(void *opaque, int ret)
 {
+int status;
 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
 
@@ -126,36 +127,37 @@ static void scsi_command_complete(void *opaque, int ret)
 if (ret != 0) {
 switch (ret) {
 case -EDOM:
-r->req.status = TASK_SET_FULL;
+status = TASK_SET_FULL;
 break;
 case -EINVAL:
-r->req.status = CHECK_CONDITION;
+status = CHECK_CONDITION;
 scsi_set_sense(s, SENSE_CODE(INVALID_FIELD));
 break;
 case -ENOMEM:
-r->req.status = CHECK_CONDITION;
+status = CHECK_CONDITION;
 scsi_set_sense(s, SENSE_CODE(TARGET_FAILURE));
 break;
 default:
-r->req.status = CHECK_CONDITION;
+status = CHECK_CONDITION;
 scsi_set_sense(s, SENSE_CODE(IO_ERROR));
 break;
 }
 } else {
 if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
-r->req.status = BUSY;
+status = BUSY;
 BADF("Driver Timeout\n");
-} else if (r->io_header.status)
-r->req.status = r->io_header.status;
-else if (s->driver_status & SG_ERR_DRIVER_SENSE)
-r->req.status = CHECK_CONDITION;
-else
-r->req.status = GOOD;
+} else if (r->io_header.status) {
+status = r->io_header.status;
+} else if (s->driver_status & SG_ERR_DRIVER_SENSE) {
+status = CHECK_CONDITION;
+} else {
+status = GOOD;
+}
 }
 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
-r, r->req.tag, r->req.status);
+r, r->req.tag, status);
 
-scsi_req_complete(&r->req);
+scsi_req_complete(&r->req, status);
 }
 
 /* Cancel a pending data transfer.  */
@@ -341,8 +343,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t 
*cmd)
 if (cmd[0] != REQUEST_SENSE && req->lun != s->lun) {
 DPRINTF("Unimplemented LUN %d\n", req->lun);
 scsi_set_sense(s, SENSE_COD

[Qemu-devel] [PATCH 14/16] scsi: add support for unit attention conditions

2011-08-03 Thread Paolo Bonzini
Unit attention conditions override any sense data the device already
has.  Their signaling and clearing is handled entirely by the SCSIBus
code, and they are completely transparent to the SCSIDevices.

Signed-off-by: Paolo Bonzini 
---
 hw/scsi-bus.c  |   93 ++-
 hw/scsi-defs.h |1 +
 hw/scsi.h  |2 +
 3 files changed, 94 insertions(+), 2 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 0e2e4cd..a5bb517 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -149,6 +149,24 @@ struct SCSIReqOps reqops_invalid_opcode = {
 .send_command = scsi_invalid_command
 };
 
+/* SCSIReqOps implementation for unit attention conditions.  */
+
+static int32_t scsi_unit_attention(SCSIRequest *req, uint8_t *buf)
+{
+if (req->dev && req->dev->unit_attention.key == UNIT_ATTENTION) {
+scsi_req_build_sense(req, req->dev->unit_attention);
+} else if (req->bus->unit_attention.key == UNIT_ATTENTION) {
+scsi_req_build_sense(req, req->bus->unit_attention);
+}
+scsi_req_complete(req, CHECK_CONDITION);
+return 0;
+}
+
+struct SCSIReqOps reqops_unit_attention = {
+.size = sizeof(SCSIRequest),
+.send_command = scsi_unit_attention
+};
+
 /* SCSIReqOps implementation for REPORT LUNS and for commands sent to
an invalid LUN.  */
 
@@ -344,6 +362,7 @@ SCSIRequest *scsi_req_alloc(SCSIReqOps *reqops, SCSIDevice 
*d, uint32_t tag,
 SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
   uint8_t *buf, void *hba_private)
 {
+SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus);
 SCSIRequest *req;
 SCSICommand cmd;
 
@@ -358,7 +377,15 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, 
uint32_t lun,
   cmd.lba);
 }
 
-if (lun != d->lun ||
+if ((d->unit_attention.key == UNIT_ATTENTION ||
+ bus->unit_attention.key == UNIT_ATTENTION) &&
+(buf[0] != INQUIRY &&
+ buf[0] != REPORT_LUNS &&
+ buf[0] != GET_CONFIGURATION &&
+ buf[0] != GET_EVENT_STATUS_NOTIFICATION)) {
+req = scsi_req_alloc(&reqops_unit_attention, d, tag, lun,
+ hba_private);
+} else if (lun != d->lun ||
 buf[0] == REPORT_LUNS ||
 buf[0] == REQUEST_SENSE) {
 req = scsi_req_alloc(&reqops_target_command, d, tag, lun,
@@ -377,13 +404,68 @@ uint8_t *scsi_req_get_buf(SCSIRequest *req)
 return req->ops->get_buf(req);
 }
 
+static void scsi_clear_unit_attention(SCSIRequest *req)
+{
+SCSISense *ua;
+if (req->dev->unit_attention.key != UNIT_ATTENTION &&
+req->bus->unit_attention.key != UNIT_ATTENTION) {
+return;
+}
+
+/*
+ * If an INQUIRY command enters the enabled command state,
+ * the device server shall [not] clear any unit attention condition;
+ * See also MMC-6, paragraphs 6.5 and 6.6.2.
+ */
+if (req->cmd.buf[0] == INQUIRY ||
+req->cmd.buf[0] == GET_CONFIGURATION ||
+req->cmd.buf[0] == GET_EVENT_STATUS_NOTIFICATION) {
+return;
+}
+
+if (req->dev->unit_attention.key == UNIT_ATTENTION) {
+ua = &req->dev->unit_attention;
+} else {
+ua = &req->bus->unit_attention;
+}
+
+/*
+ * If a REPORT LUNS command enters the enabled command state, [...]
+ * the device server shall clear any pending unit attention condition
+ * with an additional sense code of REPORTED LUNS DATA HAS CHANGED.
+ */
+if (req->cmd.buf[0] == REPORT_LUNS &&
+!(ua->asc == SENSE_CODE(REPORTED_LUNS_CHANGED).asc &&
+  ua->ascq == SENSE_CODE(REPORTED_LUNS_CHANGED).ascq)) {
+return;
+}
+
+*ua = SENSE_CODE(NO_SENSE);
+}
+
 int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len)
 {
+int ret;
+
 assert(len >= 14);
 if (!req->sense_len) {
 return 0;
 }
-return scsi_build_sense(req->sense, req->sense_len, buf, len, true);
+
+ret = scsi_build_sense(req->sense, req->sense_len, buf, len, true);
+
+/*
+ * FIXME: clearing unit attention conditions upon autosense should be done
+ * only if the UA_INTLCK_CTRL field in the Control mode page is set to 00b
+ * (SAM-5, 5.14).
+ *
+ * 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.
+ */
+scsi_clear_unit_attention(req);
+return ret;
 }
 
 int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed)
@@ -973,6 +1055,13 @@ void scsi_req_complete(SCSIRequest *req, int status)
 }
 req->dev->sense_len = req->sense_len;
 
+/*
+ * Unit attention state is now stored in the device's sense buffer
+ * if the HBA 

Re: [Qemu-devel] [PATCH] Revert "qxl: set mm_time in vga update"

2011-08-03 Thread Gerd Hoffmann

On 08/01/11 12:21, Alon Levy wrote:

This reverts commit 22795174a37e02200944c0d093d518e832650686.

Without this patch the windows logo animation during boot time was
correct, with it it jumps backwards and forwards erratically.


Looking at how the x11 qxl driver generates mm_time I see it just grabs 
the timestamp from qxl rom, which in turn is filled by the spice server 
callback.


So how about doing the same in vga mode (see patch, untested)?

cheers,
  Gerd
diff --git a/hw/qxl.c b/hw/qxl.c
index a6fb7f0..7be7c9a 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -319,6 +319,7 @@ static void interface_set_mm_time(QXLInstance *sin, 
uint32_t mm_time)
 
 qxl->shadow_rom.mm_clock = cpu_to_le32(mm_time);
 qxl->rom->mm_clock = cpu_to_le32(mm_time);
+qxl->ssd.mm_clock = mm_time;
 qxl_rom_set_dirty(qxl);
 }
 
diff --git a/ui/spice-display.c b/ui/spice-display.c
index f73..e5f3093 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -70,7 +70,6 @@ static SimpleSpiceUpdate 
*qemu_spice_create_update(SimpleSpiceDisplay *ssd)
 QXLCommand *cmd;
 uint8_t *src, *dst;
 int by, bw, bh;
-struct timespec time_space;
 
 if (qemu_spice_rect_is_empty(&ssd->dirty)) {
 return NULL;
@@ -97,10 +96,7 @@ static SimpleSpiceUpdate 
*qemu_spice_create_update(SimpleSpiceDisplay *ssd)
 drawable->surfaces_dest[0] = -1;
 drawable->surfaces_dest[1] = -1;
 drawable->surfaces_dest[2] = -1;
-clock_gettime(CLOCK_MONOTONIC, &time_space);
-/* time in milliseconds from epoch. */
-drawable->mm_time = time_space.tv_sec * 1000
-  + time_space.tv_nsec / 1000 / 1000;
+drawable->mm_time = ssd->mm_clock;
 
 drawable->u.copy.rop_descriptor  = SPICE_ROPD_OP_PUT;
 drawable->u.copy.src_bitmap  = (intptr_t)image;
@@ -290,8 +286,10 @@ static void interface_set_compression_level(QXLInstance 
*sin, int level)
 
 static void interface_set_mm_time(QXLInstance *sin, uint32_t mm_time)
 {
+SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
+
 dprint(3, "%s:\n", __FUNCTION__);
-/* nothing to do */
+ssd->mm_clock = mm_time;
 }
 
 static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
diff --git a/ui/spice-display.h b/ui/spice-display.h
index 2f95f68..68272e1 100644
--- a/ui/spice-display.h
+++ b/ui/spice-display.h
@@ -43,6 +43,7 @@ struct SimpleSpiceDisplay {
 QXLWorker *worker;
 QXLInstance qxl;
 uint32_t unique;
+uint32_t mm_clock;
 QemuPfConv *conv;
 
 QXLRect dirty;


[Qemu-devel] [PATCH 05/16] scsi: introduce SCSIReqOps

2011-08-03 Thread Paolo Bonzini
This will let allow requests to be dispatched through different callbacks,
either common or per-device.

This patch adjusts the API, the next one will move members to SCSIReqOps.

Signed-off-by: Paolo Bonzini 
---
 hw/scsi-bus.c |5 +++--
 hw/scsi-disk.c|   30 +-
 hw/scsi-generic.c |   22 +-
 hw/scsi.h |8 +++-
 4 files changed, 40 insertions(+), 25 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 067a615..4709b19 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -133,12 +133,12 @@ int scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
 return res;
 }
 
-SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag,
+SCSIRequest *scsi_req_alloc(SCSIReqOps *reqops, SCSIDevice *d, uint32_t tag,
 uint32_t lun, void *hba_private)
 {
 SCSIRequest *req;
 
-req = qemu_mallocz(size);
+req = qemu_mallocz(reqops->size);
 req->refcount = 1;
 req->bus = scsi_bus_from_device(d);
 req->dev = d;
@@ -147,6 +147,7 @@ SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, 
uint32_t tag,
 req->hba_private = hba_private;
 req->status = -1;
 req->sense_len = 0;
+req->ops = reqops;
 trace_scsi_req_alloc(req->dev->id, req->lun, req->tag);
 return req;
 }
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 4c1e58f..7483638 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -79,19 +79,6 @@ struct SCSIDiskState
 static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type);
 static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf);
 
-static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag,
- uint32_t lun, void *hba_private)
-{
-SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
-SCSIRequest *req;
-SCSIDiskReq *r;
-
-req = scsi_req_alloc(sizeof(SCSIDiskReq), &s->qdev, tag, lun, hba_private);
-r = DO_UPCAST(SCSIDiskReq, req, req);
-r->iov.iov_base = qemu_blockalign(s->bs, SCSI_DMA_BUF_SIZE);
-return req;
-}
-
 static void scsi_free_request(SCSIRequest *req)
 {
 SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
@@ -1234,6 +1221,23 @@ static int scsi_disk_initfn(SCSIDevice *dev)
 return scsi_initfn(dev, kind);
 }
 
+static SCSIReqOps scsi_disk_reqops = {
+.size = sizeof(SCSIDiskReq),
+};
+
+static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag,
+ uint32_t lun, void *hba_private)
+{
+SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
+SCSIRequest *req;
+SCSIDiskReq *r;
+
+req = scsi_req_alloc(&scsi_disk_reqops, &s->qdev, tag, lun, hba_private);
+r = DO_UPCAST(SCSIDiskReq, req, req);
+r->iov.iov_base = qemu_blockalign(s->bs, SCSI_DMA_BUF_SIZE);
+return req;
+}
+
 #define DEFINE_SCSI_DISK_PROPERTIES()   \
 DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf),  \
 DEFINE_PROP_STRING("ver",  SCSIDiskState, version), \
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index fc7cf01..87fb6ab 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -63,15 +63,6 @@ struct SCSIGenericState
 int lun;
 };
 
-static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
- void *hba_private)
-{
-SCSIRequest *req;
-
-req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun, hba_private);
-return req;
-}
-
 static void scsi_free_request(SCSIRequest *req)
 {
 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
@@ -498,6 +489,19 @@ static int scsi_generic_initfn(SCSIDevice *dev)
 return 0;
 }
 
+static SCSIReqOps scsi_generic_req_ops = {
+.size = sizeof(SCSIGenericReq),
+};
+
+static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
+ void *hba_private)
+{
+SCSIRequest *req;
+
+req = scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private);
+return req;
+}
+
 static SCSIDeviceInfo scsi_generic_info = {
 .qdev.name= "scsi-generic",
 .qdev.desc= "pass through generic scsi device (/dev/sg*)",
diff --git a/hw/scsi.h b/hw/scsi.h
index c1cb987..ee76c64 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -14,6 +14,7 @@ typedef struct SCSIBusOps SCSIBusOps;
 typedef struct SCSIDevice SCSIDevice;
 typedef struct SCSIDeviceInfo SCSIDeviceInfo;
 typedef struct SCSIRequest SCSIRequest;
+typedef struct SCSIReqOps SCSIReqOps;
 
 enum SCSIXferMode {
 SCSI_XFER_NONE,  /*  TEST_UNIT_READY, ...*/
@@ -32,6 +33,7 @@ typedef struct SCSISense {
 struct SCSIRequest {
 SCSIBus   *bus;
 SCSIDevice*dev;
+SCSIReqOps*ops;
 uint32_t  refcount;
 uint32_t  tag;
 uint32_t  lun;
@@ -69,6 +71,10 @@ int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, 
int start_track);
 int cdrom_read_toc_raw(int nb_sectors, ui

[Qemu-devel] [PATCH 09/16] scsi: push lun field to SCSIDevice

2011-08-03 Thread Paolo Bonzini
This will let SCSIBus detect requests sent to an invalid LUN, and
handle them itself.  However, there will be still support for only one
LUN per target

Signed-off-by: Paolo Bonzini 
---
 hw/scsi-bus.c |1 +
 hw/scsi-generic.c |5 +
 hw/scsi.h |1 +
 3 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 579f6b4..07d8704 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -16,6 +16,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_END_OF_LIST(),
 },
 };
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 453a295..699831a 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -60,7 +60,6 @@ struct SCSIGenericState
 {
 SCSIDevice qdev;
 BlockDriverState *bs;
-int lun;
 };
 
 static void scsi_free_request(SCSIRequest *req)
@@ -292,7 +291,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t 
*cmd)
 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
 int ret;
 
-if (cmd[0] != REQUEST_SENSE && req->lun != s->lun) {
+if (cmd[0] != REQUEST_SENSE && req->lun != s->qdev.lun) {
 DPRINTF("Unimplemented LUN %d\n", req->lun);
 scsi_req_build_sense(&r->req, SENSE_CODE(LUN_NOT_SUPPORTED));
 scsi_req_complete(&r->req, CHECK_CONDITION);
@@ -466,8 +465,6 @@ static int scsi_generic_initfn(SCSIDevice *dev)
 }
 
 /* define device state */
-s->lun = scsiid.lun;
-DPRINTF("LUN %d\n", s->lun);
 s->qdev.type = scsiid.scsi_type;
 DPRINTF("device type %d\n", s->qdev.type);
 if (s->qdev.type == TYPE_TAPE) {
diff --git a/hw/scsi.h b/hw/scsi.h
index f29d65f..5a1bbe2 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -65,6 +65,7 @@ struct SCSIDevice
 uint8_t sense[SCSI_SENSE_BUF_SIZE];
 uint32_t sense_len;
 QTAILQ_HEAD(, SCSIRequest) requests;
+uint32_t lun;
 int blocksize;
 int type;
 };
-- 
1.7.6





[Qemu-devel] [PATCH 16/16] scsi: add special traces for common commands

2011-08-03 Thread Paolo Bonzini
Can be useful when debugging the device scan phase.

Signed-off-by: Paolo Bonzini 
---
 hw/scsi-bus.c |   17 +
 trace-events  |4 
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index f6fb4f0..143c7eb 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -396,6 +396,23 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, 
uint32_t lun,
 }
 
 req->cmd = cmd;
+switch (buf[0]) {
+case INQUIRY:
+trace_scsi_inquiry(d->id, lun, tag, cmd.buf[1], cmd.buf[2]);
+break;
+case TEST_UNIT_READY:
+trace_scsi_test_unit_ready(d->id, lun, tag);
+break;
+case REPORT_LUNS:
+trace_scsi_report_luns(d->id, lun, tag);
+break;
+case REQUEST_SENSE:
+trace_scsi_request_sense(d->id, lun, tag);
+break;
+default:
+break;
+}
+
 return req;
 }
 
diff --git a/trace-events b/trace-events
index 55023b0..c565748 100644
--- a/trace-events
+++ b/trace-events
@@ -249,6 +249,10 @@ disable scsi_req_parsed(int target, int lun, int tag, int 
cmd, int mode, int xfe
 disable scsi_req_parsed_lba(int target, int lun, int tag, int cmd, uint64_t 
lba) "target %d lun %d tag %d command %d lba %"PRIu64""
 disable scsi_req_parse_bad(int target, int lun, int tag, int cmd) "target %d 
lun %d tag %d command %d"
 disable scsi_req_build_sense(int target, int lun, int tag, int key, int asc, 
int ascq) "target %d lun %d tag %d key %#02x asc %#02x ascq %#02x"
+disable scsi_report_luns(int target, int lun, int tag) "target %d lun %d tag 
%d"
+disable scsi_inquiry(int target, int lun, int tag, int cdb1, int cdb2) "target 
%d lun %d tag %d page %#02x/%#02x"
+disable scsi_test_unit_ready(int target, int lun, int tag) "target %d lun %d 
tag %d"
+disable scsi_request_sense(int target, int lun, int tag) "target %d lun %d tag 
%d"
 
 # vl.c
 disable vm_state_notify(int running, int reason) "running %d reason %d"
-- 
1.7.6




Re: [Qemu-devel] [Qemu-trivial] [PATCH] Correctly assign PCI domain numbers

2011-08-03 Thread Stefan Hajnoczi
On Mon, Aug 01, 2011 at 01:10:38PM +0300, Michael S. Tsirkin wrote:
> On Mon, Aug 01, 2011 at 04:51:02PM +1000, David Gibson wrote:
> > qemu already almost supports PCI domains; that is, several entirely
> > independent PCI host bridges on the same machine.  However, a bug in
> > pci_bus_new_inplace() means that every host bridge gets assigned domain
> > number zero and so can't be properly distinguished.  This patch fixes the
> > bug, giving each new host bridge a new domain number.
> > 
> > Signed-off-by: David Gibson 
> 
> OK, but I'd like to see the whole picture.
> How does the guest detect multiple domains,
> and how does it access them?
> 
> > ---
> >  hw/pci.c |5 -
> >  1 files changed, 4 insertions(+), 1 deletions(-)
> > 
> > diff --git a/hw/pci.c b/hw/pci.c
> > index 36db58b..2b4aecb 100644
> > --- a/hw/pci.c
> > +++ b/hw/pci.c
> > @@ -262,6 +262,8 @@ int pci_find_domain(const PCIBus *bus)
> >  return -1;
> >  }
> >  
> > +static int pci_next_domain; /* = 0 */
> > +
> >  void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
> >   const char *name,
> >   MemoryRegion *address_space,
> > @@ -274,7 +276,8 @@ void pci_bus_new_inplace(PCIBus *bus, DeviceState 
> > *parent,
> >  
> >  /* host bridge */
> >  QLIST_INIT(&bus->child);
> > -pci_host_bus_register(0, bus); /* for now only pci domain 0 is 
> > supported */
> > +
> > +pci_host_bus_register(pci_next_domain++, bus);
> 
> What happens when that overflows?

In what scenario do we reach such a high number?  (I'm not saying this
is harmless, just trying to understand if it should be an assert or
error return.)

Stefan



Re: [Qemu-devel] [Qemu-trivial] [PATCH] Check fread() results to avoid gcc 4.6 warnings

2011-08-03 Thread Stefan Hajnoczi
On Mon, Aug 01, 2011 at 11:19:38AM +0100, Stefan Hajnoczi wrote:
> On Mon, Aug 1, 2011 at 7:49 AM, David Gibson
>  wrote:
> > When compiling with gcc 4.6, some code in fw_cfg.c complains that fop_ret
> > is assigned but not used (which is true).  However, it looks like the
> > meaningless assignments to fop_ret were done to suppress other gcc warnings
> > due to the fact that fread() is labelled as warn_unused_result in glibc.
> >
> > This patch avoids both errors, by actually checking the fread() result code
> > and dropping out with an error message if it fails.
> >
> > Signed-off-by: David Gibson 
> > ---
> >  hw/fw_cfg.c |   13 +
> >  1 files changed, 13 insertions(+), 0 deletions(-)
> 
> Reviewed-by: Stefan Hajnoczi 

I'm not taking this into the trivial-patches tree because a build fix
like this should be merged sooner.  With trivial-patches I only send one
pull request per week and in the meantime people would have to
./configure --disable-werror which isn't good.

Stefan



[Qemu-devel] "Looking for MIPS Maintainer"

2011-08-03 Thread Khansa Butt
Hi!
we are waiting for approval of our Patches for MIPS64 user mode emulation.
Patch 1(linux-user) has already been reviewed by Riku Voipio but
target-mips
part is waiting forMIPS maintainer. Please review target-mips patches so
that
we'll be able to continue our contribution in mips world.

here are the  Patches in waiting queue.
[Qemu-devel] [PATCH 2/3] target-mips:Adding Octeon cpu
definitions
[Qemu-devel] [PATCH 3/3] target-mips:Support for Cavium specific
instructions
sent on Jul 5.

Thanks.


[Qemu-devel] [PATCH 2/3] HMP: Remove the duplicated info "info kvm" in hmp-commands.hx.

2011-08-03 Thread Stefan Hajnoczi
From: Zhi Yong Wu 

Signed-off-by: Zhi Yong Wu 
Signed-off-by: Stefan Hajnoczi 
---
 hmp-commands.hx |2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index c857827..0ccfb28 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1311,8 +1311,6 @@ show virtual to physical memory mappings (i386, SH4 and 
SPARC only)
 show the active virtual memory mappings (i386 only)
 @item info jit
 show dynamic compiler info
-@item info kvm
-show KVM information
 @item info numa
 show NUMA information
 @item info kvm
-- 
1.7.5.4




[Qemu-devel] [PULL 0/3] Trivial patches for July 28 to August 3 2011

2011-08-03 Thread Stefan Hajnoczi
The following changes since commit 927d721777e73339f73719f36eaf400ab641366c:

  microblaze: Add missing call to qemu_init_vcpu. (2011-07-31 06:40:13 +0200)

are available in the git repository at:
  ssh://repo.or.cz/srv/git/qemu/stefanha.git trivial-patches

Alexandre Raymond (1):
  Makefile: delete config.log in distclean

Brad (1):
  configure: display "no" for disabled kvm/vhost-net

Zhi Yong Wu (1):
  HMP: Remove the duplicated info "info kvm" in hmp-commands.hx.

 Makefile|1 +
 configure   |4 ++--
 hmp-commands.hx |2 --
 3 files changed, 3 insertions(+), 4 deletions(-)

-- 
1.7.5.4




[Qemu-devel] [PATCH 1/3] configure: display "no" for disabled kvm/vhost-net

2011-08-03 Thread Stefan Hajnoczi
From: Brad 

Fix configure display for non-Linux OS's and the KVM /
vhost-net features to show "no" output instead of nothing
at the end of the line.

Signed-off-by: Brad Smith 
Acked-by: Jan Kiszka 
Signed-off-by: Stefan Hajnoczi 
---
 configure |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index 77194cf..9d46780 100755
--- a/configure
+++ b/configure
@@ -113,7 +113,6 @@ curl=""
 curses=""
 docs=""
 fdt=""
-kvm=""
 nptl=""
 sdl=""
 vnc="yes"
@@ -129,9 +128,10 @@ xen=""
 xen_ctrl_version=""
 linux_aio=""
 attr=""
-vhost_net=""
 xfs=""
 
+vhost_net="no"
+kvm="no"
 gprof="no"
 debug_tcg="no"
 debug_mon="no"
-- 
1.7.5.4




[Qemu-devel] [PATCH 3/3] Makefile: delete config.log in distclean

2011-08-03 Thread Stefan Hajnoczi
From: Alexandre Raymond 

Distclean should remove anything created by the configure script.

Signed-off-by: Alexandre Raymond 
Signed-off-by: Stefan Hajnoczi 
---
 Makefile |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile
index 4855251..a0218a3 100644
--- a/Makefile
+++ b/Makefile
@@ -226,6 +226,7 @@ distclean: clean
rm -f qemu-doc.fn qemu-doc.fns qemu-doc.info qemu-doc.ky qemu-doc.kys
rm -f qemu-doc.log qemu-doc.pdf qemu-doc.pg qemu-doc.toc qemu-doc.tp
rm -f qemu-doc.vr
+   rm -f config.log
rm -f qemu-tech.info qemu-tech.aux qemu-tech.cp qemu-tech.dvi 
qemu-tech.fn qemu-tech.info qemu-tech.ky qemu-tech.log qemu-tech.pdf 
qemu-tech.pg qemu-tech.toc qemu-tech.tp qemu-tech.vr
for d in $(TARGET_DIRS) $(QEMULIBS); do \
rm -rf $$d || exit 1 ; \
-- 
1.7.5.4




Re: [Qemu-devel] [Qemu-trivial] [PATCH] Correctly assign PCI domain numbers

2011-08-03 Thread Michael S. Tsirkin
On Wed, Aug 03, 2011 at 11:13:15AM +0100, Stefan Hajnoczi wrote:
> On Mon, Aug 01, 2011 at 01:10:38PM +0300, Michael S. Tsirkin wrote:
> > On Mon, Aug 01, 2011 at 04:51:02PM +1000, David Gibson wrote:
> > > qemu already almost supports PCI domains; that is, several entirely
> > > independent PCI host bridges on the same machine.  However, a bug in
> > > pci_bus_new_inplace() means that every host bridge gets assigned domain
> > > number zero and so can't be properly distinguished.  This patch fixes the
> > > bug, giving each new host bridge a new domain number.
> > > 
> > > Signed-off-by: David Gibson 
> > 
> > OK, but I'd like to see the whole picture.
> > How does the guest detect multiple domains,
> > and how does it access them?
> > 
> > > ---
> > >  hw/pci.c |5 -
> > >  1 files changed, 4 insertions(+), 1 deletions(-)
> > > 
> > > diff --git a/hw/pci.c b/hw/pci.c
> > > index 36db58b..2b4aecb 100644
> > > --- a/hw/pci.c
> > > +++ b/hw/pci.c
> > > @@ -262,6 +262,8 @@ int pci_find_domain(const PCIBus *bus)
> > >  return -1;
> > >  }
> > >  
> > > +static int pci_next_domain; /* = 0 */
> > > +
> > >  void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
> > >   const char *name,
> > >   MemoryRegion *address_space,
> > > @@ -274,7 +276,8 @@ void pci_bus_new_inplace(PCIBus *bus, DeviceState 
> > > *parent,
> > >  
> > >  /* host bridge */
> > >  QLIST_INIT(&bus->child);
> > > -pci_host_bus_register(0, bus); /* for now only pci domain 0 is 
> > > supported */
> > > +
> > > +pci_host_bus_register(pci_next_domain++, bus);
> > 
> > What happens when that overflows?
> 
> In what scenario do we reach such a high number?  (I'm not saying this
> is harmless, just trying to understand if it should be an assert or
> error return.)
> 
> Stefan

Can bus ever get hot-plugged?



[Qemu-devel] [PATCH 02/11] spice: add qemu_spice_display_init_common

2011-08-03 Thread Gerd Hoffmann
Factor out SimpleSpiceDisplay initialization into
qemu_spice_display_init_common() and call it from
both qxl.c (for vga mode) and spice-display.c

Signed-off-by: Gerd Hoffmann 
---
 hw/qxl.c   |7 +--
 ui/spice-display.c |   17 +++--
 ui/spice-display.h |1 +
 3 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 5deb776..2127fa3 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1315,12 +1315,7 @@ static int qxl_init_primary(PCIDevice *dev)
 
 vga->ds = graphic_console_init(qxl_hw_update, qxl_hw_invalidate,
qxl_hw_screen_dump, qxl_hw_text_update, 
qxl);
-qxl->ssd.ds = vga->ds;
-qemu_mutex_init(&qxl->ssd.lock);
-qxl->ssd.mouse_x = -1;
-qxl->ssd.mouse_y = -1;
-qxl->ssd.bufsize = (16 * 1024 * 1024);
-qxl->ssd.buf = qemu_malloc(qxl->ssd.bufsize);
+qemu_spice_display_init_common(&qxl->ssd, vga->ds);
 
 qxl0 = qxl;
 register_displaychangelistener(vga->ds, &display_listener);
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 1e6a38f..93e25bf 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -286,6 +286,16 @@ void qemu_spice_vm_change_state_handler(void *opaque, int 
running, int reason)
 ssd->running = running;
 }
 
+void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds)
+{
+ssd->ds = ds;
+qemu_mutex_init(&ssd->lock);
+ssd->mouse_x = -1;
+ssd->mouse_y = -1;
+ssd->bufsize = (16 * 1024 * 1024);
+ssd->buf = qemu_malloc(ssd->bufsize);
+}
+
 /* display listener callbacks */
 
 void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
@@ -499,12 +509,7 @@ static DisplayChangeListener display_listener = {
 void qemu_spice_display_init(DisplayState *ds)
 {
 assert(sdpy.ds == NULL);
-sdpy.ds = ds;
-qemu_mutex_init(&sdpy.lock);
-sdpy.mouse_x = -1;
-sdpy.mouse_y = -1;
-sdpy.bufsize = (16 * 1024 * 1024);
-sdpy.buf = qemu_malloc(sdpy.bufsize);
+qemu_spice_display_init_common(&sdpy, ds);
 register_displaychangelistener(ds, &display_listener);
 
 sdpy.qxl.base.sif = &dpy_interface.base;
diff --git a/ui/spice-display.h b/ui/spice-display.h
index 5b06b11..eb7a573 100644
--- a/ui/spice-display.h
+++ b/ui/spice-display.h
@@ -75,6 +75,7 @@ void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd);
 void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd);
 void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd);
 void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason);
+void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds);
 
 void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
int x, int y, int w, int h);
-- 
1.7.1




[Qemu-devel] [PULL] spice: async i/o for qxl

2011-08-03 Thread Gerd Hoffmann
  Hi,

This spice/qxl pull fixes (for the most part) a design flaw in the qxl
device interface.

Some write operations to qxl I/O ports are blocking, i.e. they wait
for the spice server finish some work, then return to the guest.
Which adds noticable latencies.  This patch series adds non-blocking
versions of these operations which return without delay, then raise
a IRQ when complete.  The old ops remain functional for backward
compatibility reasons.  A guest driver update is needed to make use
of the new ops and get rid of the latencies.

The series also adds new ops which ask the spice server to process all
outstanding rendering commands.  This will effectively flush all spice
server state to qxl device memory and is needed for S3 support.

While being at extending the guest ABI we also add a error IRQ to the
qxl device.  Long-term plan is to convert all guest-triggerable asserts
in qxl.c into "ignore guest request and raise error IRQ".

All stuff listed above needs a new version of the spice server library,
thats why a bunch of ifdefs is needed so qxl continues to work with
older spice versions.  The plan is to raise the minimum required spice
server library when it is in widespread use (in a year or so), then
kill all the ugly #ifdefs.

Finally we raise the pci revision of the qxl device (with new
libspice-server) to signal the guest all the stuff listed above is
available.

please pull,
   Gerd

The following changes since commit 927d721777e73339f73719f36eaf400ab641366c:

  microblaze: Add missing call to qemu_init_vcpu. (2011-07-31 06:40:13 +0200)

are available in the git repository at:
  git://anongit.freedesktop.org/spice/qemu spice.v40

Alon Levy (5):
  qxl: add io_port_to_string
  qxl: make qxl_guest_bug take variable arguments
  qxl: only disallow specific io's in vga mode
  qxl: async io support using new spice api
  qxl: add QXL_IO_FLUSH_{SURFACES,RELEASE} for guest S3&S4 support

Gerd Hoffmann (6):
  spice: add worker wrapper functions.
  spice: add qemu_spice_display_init_common
  spice/qxl: move worker wrappers
  qxl: fix surface tracking & locking
  qxl: error handling fixes and cleanups.
  qxl: bump pci rev

 hw/qxl-render.c|4 +-
 hw/qxl.c   |  438 +---
 hw/qxl.h   |   34 -
 ui/spice-display.c |   93 ++--
 ui/spice-display.h |   28 
 5 files changed, 528 insertions(+), 69 deletions(-)



[Qemu-devel] [PATCH 08/11] qxl: only disallow specific io's in vga mode

2011-08-03 Thread Gerd Hoffmann
From: Alon Levy 

Since the driver is still in operation even after moving to UNDEFINED, i.e.
by destroying primary in any way.

Signed-off-by: Alon Levy 
Signed-off-by: Gerd Hoffmann 
---
 hw/qxl.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index c50eaf9..23e3240 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1055,8 +1055,9 @@ static void ioport_write(void *opaque, uint32_t addr, 
uint32_t val)
 case QXL_IO_LOG:
 break;
 default:
-if (d->mode == QXL_MODE_NATIVE || d->mode == QXL_MODE_COMPAT)
+if (d->mode != QXL_MODE_VGA) {
 break;
+}
 dprint(d, 1, "%s: unexpected port 0x%x (%s) in vga mode\n",
 __func__, io_port, io_port_to_string(io_port));
 return;
-- 
1.7.1




[Qemu-devel] [PATCH 07/11] qxl: make qxl_guest_bug take variable arguments

2011-08-03 Thread Gerd Hoffmann
From: Alon Levy 

Signed-off-by: Alon Levy 
Signed-off-by: Gerd Hoffmann 
---
 hw/qxl.c |9 +++--
 hw/qxl.h |2 +-
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 28c8b5d..c50eaf9 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -125,13 +125,18 @@ static void qxl_reset_memslots(PCIQXLDevice *d);
 static void qxl_reset_surfaces(PCIQXLDevice *d);
 static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
 
-void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg)
+void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...)
 {
 #if SPICE_INTERFACE_QXL_MINOR >= 1
 qxl_send_events(qxl, QXL_INTERRUPT_ERROR);
 #endif
 if (qxl->guestdebug) {
-fprintf(stderr, "qxl-%d: guest bug: %s\n", qxl->id, msg);
+va_list ap;
+va_start(ap, msg);
+fprintf(stderr, "qxl-%d: guest bug: ", qxl->id);
+vfprintf(stderr, msg, ap);
+fprintf(stderr, "\n");
+va_end(ap);
 }
 }
 
diff --git a/hw/qxl.h b/hw/qxl.h
index 5db9aae..32ca5a0 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -99,7 +99,7 @@ typedef struct PCIQXLDevice {
 
 /* qxl.c */
 void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id);
-void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg);
+void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...);
 
 void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
struct QXLRect *area, struct QXLRect *dirty_rects,
-- 
1.7.1




[Qemu-devel] [PATCH 01/11] spice: add worker wrapper functions.

2011-08-03 Thread Gerd Hoffmann
Add wrapper functions for all spice worker calls.

Signed-off-by: Gerd Hoffmann 
---
 hw/qxl-render.c|4 +-
 hw/qxl.c   |   32 +-
 ui/spice-display.c |   95 ---
 ui/spice-display.h |   22 
 4 files changed, 129 insertions(+), 24 deletions(-)

diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index 1316066..bef5f14 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -124,8 +124,8 @@ void qxl_render_update(PCIQXLDevice *qxl)
 update.bottom = qxl->guest_primary.surface.height;
 
 memset(dirty, 0, sizeof(dirty));
-qxl->ssd.worker->update_area(qxl->ssd.worker, 0, &update,
- dirty, ARRAY_SIZE(dirty), 1);
+qemu_spice_update_area(&qxl->ssd, 0, &update,
+   dirty, ARRAY_SIZE(dirty), 1);
 
 for (i = 0; i < ARRAY_SIZE(dirty); i++) {
 if (qemu_spice_rect_is_empty(dirty+i)) {
diff --git a/hw/qxl.c b/hw/qxl.c
index a6fb7f0..5deb776 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -684,8 +684,8 @@ static void qxl_hard_reset(PCIQXLDevice *d, int loadvm)
 dprint(d, 1, "%s: start%s\n", __FUNCTION__,
loadvm ? " (loadvm)" : "");
 
-d->ssd.worker->reset_cursor(d->ssd.worker);
-d->ssd.worker->reset_image_cache(d->ssd.worker);
+qemu_spice_reset_cursor(&d->ssd);
+qemu_spice_reset_image_cache(&d->ssd);
 qxl_reset_surfaces(d);
 qxl_reset_memslots(d);
 
@@ -790,7 +790,7 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t 
slot_id, uint64_t delta)
__FUNCTION__, memslot.slot_id,
memslot.virt_start, memslot.virt_end);
 
-d->ssd.worker->add_memslot(d->ssd.worker, &memslot);
+qemu_spice_add_memslot(&d->ssd, &memslot);
 d->guest_slots[slot_id].ptr = (void*)memslot.virt_start;
 d->guest_slots[slot_id].size = memslot.virt_end - memslot.virt_start;
 d->guest_slots[slot_id].delta = delta;
@@ -800,14 +800,14 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t 
slot_id, uint64_t delta)
 static void qxl_del_memslot(PCIQXLDevice *d, uint32_t slot_id)
 {
 dprint(d, 1, "%s: slot %d\n", __FUNCTION__, slot_id);
-d->ssd.worker->del_memslot(d->ssd.worker, MEMSLOT_GROUP_HOST, slot_id);
+qemu_spice_del_memslot(&d->ssd, MEMSLOT_GROUP_HOST, slot_id);
 d->guest_slots[slot_id].active = 0;
 }
 
 static void qxl_reset_memslots(PCIQXLDevice *d)
 {
 dprint(d, 1, "%s:\n", __FUNCTION__);
-d->ssd.worker->reset_memslots(d->ssd.worker);
+qemu_spice_reset_memslots(&d->ssd);
 memset(&d->guest_slots, 0, sizeof(d->guest_slots));
 }
 
@@ -815,7 +815,7 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
 {
 dprint(d, 1, "%s:\n", __FUNCTION__);
 d->mode = QXL_MODE_UNDEFINED;
-d->ssd.worker->destroy_surfaces(d->ssd.worker);
+qemu_spice_destroy_surfaces(&d->ssd);
 memset(&d->guest_surfaces.cmds, 0, sizeof(d->guest_surfaces.cmds));
 }
 
@@ -869,7 +869,7 @@ static void qxl_create_guest_primary(PCIQXLDevice *qxl, int 
loadvm)
 
 qxl->mode = QXL_MODE_NATIVE;
 qxl->cmdflags = 0;
-qxl->ssd.worker->create_primary_surface(qxl->ssd.worker, 0, &surface);
+qemu_spice_create_primary_surface(&qxl->ssd, 0, &surface);
 
 /* for local rendering */
 qxl_render_resize(qxl);
@@ -884,7 +884,7 @@ static void qxl_destroy_primary(PCIQXLDevice *d)
 dprint(d, 1, "%s\n", __FUNCTION__);
 
 d->mode = QXL_MODE_UNDEFINED;
-d->ssd.worker->destroy_primary_surface(d->ssd.worker, 0);
+qemu_spice_destroy_primary_surface(&d->ssd, 0);
 }
 
 static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
@@ -956,15 +956,15 @@ static void ioport_write(void *opaque, uint32_t addr, 
uint32_t val)
 case QXL_IO_UPDATE_AREA:
 {
 QXLRect update = d->ram->update_area;
-d->ssd.worker->update_area(d->ssd.worker, d->ram->update_surface,
-   &update, NULL, 0, 0);
+qemu_spice_update_area(&d->ssd, d->ram->update_surface,
+   &update, NULL, 0, 0);
 break;
 }
 case QXL_IO_NOTIFY_CMD:
-d->ssd.worker->wakeup(d->ssd.worker);
+qemu_spice_wakeup(&d->ssd);
 break;
 case QXL_IO_NOTIFY_CURSOR:
-d->ssd.worker->wakeup(d->ssd.worker);
+qemu_spice_wakeup(&d->ssd);
 break;
 case QXL_IO_UPDATE_IRQ:
 qxl_set_irq(d);
@@ -978,7 +978,7 @@ static void ioport_write(void *opaque, uint32_t addr, 
uint32_t val)
 break;
 }
 d->oom_running = 1;
-d->ssd.worker->oom(d->ssd.worker);
+qemu_spice_oom(&d->ssd);
 d->oom_running = 0;
 break;
 case QXL_IO_SET_MODE:
@@ -1016,10 +1016,10 @@ static void ioport_write(void *opaque, uint32_t addr, 
uint32_t val)
 qxl_destroy_primary(d);
 break;
 case QXL_IO_DESTROY_SURFACE_WAIT:
-d->ssd.worker->destroy_surface_wait(d->ssd.worker, val);
+qemu_spice_destroy_surface_wait(&d->ssd, val);
 break;
 ca

[Qemu-devel] [PATCH 10/11] qxl: add QXL_IO_FLUSH_{SURFACES, RELEASE} for guest S3&S4 support

2011-08-03 Thread Gerd Hoffmann
From: Alon Levy 

Add two new IOs.
 QXL_IO_FLUSH_SURFACES - equivalent to update area for all surfaces, used
  to reduce vmexits from NumSurfaces to 1 on guest S3, S4 and resolution change 
(windows
  driver implementation is such that this is done on each of those occasions).
 QXL_IO_FLUSH_RELEASE - used to ensure anything on last_release is put on the 
release ring
  for the client to free.

Signed-off-by: Yonit Halperin 
Signed-off-by: Alon Levy 
Signed-off-by: Gerd Hoffmann 
---
 hw/qxl.c |   30 ++
 1 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index d3109e4..847a9b8 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -185,6 +185,13 @@ static void qxl_spice_destroy_surface_wait(PCIQXLDevice 
*qxl, uint32_t id,
 }
 }
 
+#if SPICE_INTERFACE_QXL_MINOR >= 1
+static void qxl_spice_flush_surfaces_async(PCIQXLDevice *qxl)
+{
+spice_qxl_flush_surfaces_async(&qxl->ssd.qxl, 0);
+}
+#endif
+
 void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
uint32_t count)
 {
@@ -1184,6 +1191,8 @@ static void ioport_write(void *opaque, uint32_t addr, 
uint32_t val)
 goto async_common;
 case QXL_IO_DESTROY_ALL_SURFACES_ASYNC:
 io_port = QXL_IO_DESTROY_ALL_SURFACES;
+goto async_common;
+case QXL_IO_FLUSH_SURFACES_ASYNC:
 async_common:
 async = QXL_ASYNC;
 qemu_mutex_lock(&d->async_lock);
@@ -1296,6 +1305,27 @@ async_common:
 }
 qxl_spice_destroy_surface_wait(d, val, async);
 break;
+#if SPICE_INTERFACE_QXL_MINOR >= 1
+case QXL_IO_FLUSH_RELEASE: {
+QXLReleaseRing *ring = &d->ram->release_ring;
+if (ring->prod - ring->cons + 1 == ring->num_items) {
+fprintf(stderr,
+"ERROR: no flush, full release ring [p%d,%dc]\n",
+ring->prod, ring->cons);
+}
+qxl_push_free_res(d, 1 /* flush */);
+dprint(d, 1, "QXL_IO_FLUSH_RELEASE exit (%s, s#=%d, res#=%d,%p)\n",
+qxl_mode_to_string(d->mode), d->guest_surfaces.count,
+d->num_free_res, d->last_release);
+break;
+}
+case QXL_IO_FLUSH_SURFACES_ASYNC:
+dprint(d, 1, "QXL_IO_FLUSH_SURFACES_ASYNC (%d) (%s, s#=%d, res#=%d)\n",
+   val, qxl_mode_to_string(d->mode), d->guest_surfaces.count,
+   d->num_free_res);
+qxl_spice_flush_surfaces_async(d);
+break;
+#endif
 case QXL_IO_DESTROY_ALL_SURFACES:
 d->mode = QXL_MODE_UNDEFINED;
 qxl_spice_destroy_surfaces(d, async);
-- 
1.7.1




[Qemu-devel] [PATCH 11/11] qxl: bump pci rev

2011-08-03 Thread Gerd Hoffmann
Inform guest drivers about the new features I/O commands we have
now (async commands, S3 support) if building with newer spice, i.e.
if SPICE_INTERFACE_QXL_MINOR >= 1.

sneaked in some 81+ column line spliting.

Signed-off-by: Gerd Hoffmann 
Signed-off-by: Alon Levy 
---
 hw/qxl.c |   25 ++---
 hw/qxl.h |6 ++
 2 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 847a9b8..b684608 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1566,9 +1566,14 @@ static int qxl_init_common(PCIQXLDevice *qxl)
 pci_device_rev = QXL_REVISION_STABLE_V04;
 break;
 case 2: /* spice 0.6 -- qxl-2 */
-default:
 pci_device_rev = QXL_REVISION_STABLE_V06;
 break;
+#if SPICE_INTERFACE_QXL_MINOR >= 1
+case 3: /* qxl-3 */
+#endif
+default:
+pci_device_rev = QXL_DEFAULT_REVISION;
+break;
 }
 
 pci_set_byte(&config[PCI_REVISION_ID], pci_device_rev);
@@ -1830,9 +1835,12 @@ static PCIDeviceInfo qxl_info_primary = {
 .device_id= QXL_DEVICE_ID_STABLE,
 .class_id = PCI_CLASS_DISPLAY_VGA,
 .qdev.props = (Property[]) {
-DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * 1024 
* 1024),
-DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size, 64 * 1024 * 
1024),
-DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision, 2),
+DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size,
+   64 * 1024 * 1024),
+DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size,
+   64 * 1024 * 1024),
+DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision,
+   QXL_DEFAULT_REVISION),
 DEFINE_PROP_UINT32("debug", PCIQXLDevice, debug, 0),
 DEFINE_PROP_UINT32("guestdebug", PCIQXLDevice, guestdebug, 0),
 DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0),
@@ -1851,9 +1859,12 @@ static PCIDeviceInfo qxl_info_secondary = {
 .device_id= QXL_DEVICE_ID_STABLE,
 .class_id = PCI_CLASS_DISPLAY_OTHER,
 .qdev.props = (Property[]) {
-DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * 1024 
* 1024),
-DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size, 64 * 1024 * 
1024),
-DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision, 2),
+DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size,
+   64 * 1024 * 1024),
+DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size,
+   64 * 1024 * 1024),
+DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision,
+   QXL_DEFAULT_REVISION),
 DEFINE_PROP_UINT32("debug", PCIQXLDevice, debug, 0),
 DEFINE_PROP_UINT32("guestdebug", PCIQXLDevice, guestdebug, 0),
 DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0),
diff --git a/hw/qxl.h b/hw/qxl.h
index 1046205..4bcf7e1 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -102,6 +102,12 @@ typedef struct PCIQXLDevice {
 }   \
 } while (0)
 
+#if SPICE_INTERFACE_QXL_MINOR >= 1
+#define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V10
+#else
+#define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V06
+#endif
+
 /* qxl.c */
 void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id);
 void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...);
-- 
1.7.1




Re: [Qemu-devel] [PATCH V4 1/2] [SLIRP] Simple ARP table

2011-08-03 Thread Fabien Chouteau
On 03/08/2011 11:13, Jan Kiszka wrote:
> On 2011-08-02 15:19, Fabien Chouteau wrote:
>> This patch adds a simple ARP table in Slirp and also adds handling of
>> gratuitous ARP requests.
> ...
> Looks good now and work here as well.

Great!

> One last thing (I swear): We need a proper license header for
> arp_table.c.

Sure, I'll send V5 in a few minutes.

> Then I'll apply this and v3 of 2/2 and send out a pull
> request (Anthony asked me to look after slirp).

Thanks,

-- 
Fabien Chouteau



[Qemu-devel] [PATCH V5 1/2] [SLIRP] Simple ARP table

2011-08-03 Thread Fabien Chouteau
This patch adds a simple ARP table in Slirp and also adds handling of
gratuitous ARP requests.

Signed-off-by: Fabien Chouteau 
---
 Makefile.objs |2 +-
 slirp/arp_table.c |   95 +
 slirp/bootp.c |   21 +++
 slirp/slirp.c |   63 +--
 slirp/slirp.h |   47 --
 5 files changed, 169 insertions(+), 59 deletions(-)
 create mode 100644 slirp/arp_table.c

diff --git a/Makefile.objs b/Makefile.objs
index 6991a9f..0c10557 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -151,7 +151,7 @@ common-obj-y += qemu-timer.o qemu-timer-common.o
 
 slirp-obj-y = cksum.o if.o ip_icmp.o ip_input.o ip_output.o
 slirp-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o
-slirp-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o
+slirp-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o arp_table.o
 common-obj-$(CONFIG_SLIRP) += $(addprefix slirp/, $(slirp-obj-y))
 
 # xen backend driver support
diff --git a/slirp/arp_table.c b/slirp/arp_table.c
new file mode 100644
index 000..820dee2
--- /dev/null
+++ b/slirp/arp_table.c
@@ -0,0 +1,95 @@
+/*
+ * ARP table
+ *
+ * Copyright (c) 2011 AdaCore
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "slirp.h"
+
+void arp_table_add(Slirp *slirp, int ip_addr, uint8_t ethaddr[ETH_ALEN])
+{
+const in_addr_t broadcast_addr =
+~slirp->vnetwork_mask.s_addr | slirp->vnetwork_addr.s_addr;
+ArpTable *arptbl = &slirp->arp_table;
+int i;
+
+DEBUG_CALL("arp_table_add");
+DEBUG_ARG("ip = 0x%x", ip_addr);
+DEBUG_ARGS((dfd, " hw addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
+ethaddr[0], ethaddr[1], ethaddr[2],
+ethaddr[3], ethaddr[4], ethaddr[5]));
+
+/* Check 0.0.0.0/8 invalid source-only addresses */
+assert((ip_addr & htonl(~(0xf << 28))) != 0);
+
+if (ip_addr == 0x || ip_addr == broadcast_addr) {
+/* Do not register broadcast addresses */
+return;
+}
+
+/* Search for an entry */
+for (i = 0; i < ARP_TABLE_SIZE; i++) {
+if (arptbl->table[i].ar_sip == ip_addr) {
+/* Update the entry */
+memcpy(arptbl->table[i].ar_sha, ethaddr, ETH_ALEN);
+return;
+}
+}
+
+/* No entry found, create a new one */
+arptbl->table[arptbl->next_victim].ar_sip = ip_addr;
+memcpy(arptbl->table[arptbl->next_victim].ar_sha,  ethaddr, ETH_ALEN);
+arptbl->next_victim = (arptbl->next_victim + 1) % ARP_TABLE_SIZE;
+}
+
+bool arp_table_search(Slirp *slirp, int in_ip_addr,
+  uint8_t out_ethaddr[ETH_ALEN])
+{
+const in_addr_t broadcast_addr =
+~slirp->vnetwork_mask.s_addr | slirp->vnetwork_addr.s_addr;
+ArpTable *arptbl = &slirp->arp_table;
+int i;
+
+DEBUG_CALL("arp_table_search");
+DEBUG_ARG("ip = 0x%x", in_ip_addr);
+
+/* Check 0.0.0.0/8 invalid source-only addresses */
+assert((in_ip_addr & htonl(~(0xf << 28))) != 0);
+
+/* If broadcast address */
+if (in_ip_addr == 0x || in_ip_addr == broadcast_addr) {
+/* return Ethernet broadcast address */
+memset(out_ethaddr, 0xff, ETH_ALEN);
+return 1;
+}
+
+for (i = 0; i < ARP_TABLE_SIZE; i++) {
+if (arptbl->table[i].ar_sip == in_ip_addr) {
+memcpy(out_ethaddr, arptbl->table[i].ar_sha,  ETH_ALEN);
+DEBUG_ARGS((dfd, " found hw addr = 
%02x:%02x:%02x:%02x:%02x:%02x\n",
+out_ethaddr[0], out_ethaddr[1], out_ethaddr[2],
+out_ethaddr[3], out_ethaddr[4], out_ethaddr[5]));
+return 1;
+}
+}
+
+return 0;
+}
diff --git a/slirp/bootp.c b/slirp/bootp.c
index 1eb2ed1..efd1fe7 100644
--- a/slirp/bootp.c
+++ b/slirp/bootp.c
@@ -149,6 +149,7 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t 
*bp)
 struct in_addr

[Qemu-devel] [PATCH 05/11] qxl: add io_port_to_string

2011-08-03 Thread Gerd Hoffmann
From: Alon Levy 

Signed-off-by: Alon Levy 
Signed-off-by: Gerd Hoffmann 
---
 hw/qxl.c |   40 +++-
 1 files changed, 39 insertions(+), 1 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 416bd48..6e66021 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -409,6 +409,43 @@ static const char *qxl_mode_to_string(int mode)
 return "INVALID";
 }
 
+static const char *io_port_to_string(uint32_t io_port)
+{
+if (io_port >= QXL_IO_RANGE_SIZE) {
+return "out of range";
+}
+static const char *io_port_to_string[QXL_IO_RANGE_SIZE + 1] = {
+[QXL_IO_NOTIFY_CMD] = "QXL_IO_NOTIFY_CMD",
+[QXL_IO_NOTIFY_CURSOR]  = "QXL_IO_NOTIFY_CURSOR",
+[QXL_IO_UPDATE_AREA]= "QXL_IO_UPDATE_AREA",
+[QXL_IO_UPDATE_IRQ] = "QXL_IO_UPDATE_IRQ",
+[QXL_IO_NOTIFY_OOM] = "QXL_IO_NOTIFY_OOM",
+[QXL_IO_RESET]  = "QXL_IO_RESET",
+[QXL_IO_SET_MODE]   = "QXL_IO_SET_MODE",
+[QXL_IO_LOG]= "QXL_IO_LOG",
+[QXL_IO_MEMSLOT_ADD]= "QXL_IO_MEMSLOT_ADD",
+[QXL_IO_MEMSLOT_DEL]= "QXL_IO_MEMSLOT_DEL",
+[QXL_IO_DETACH_PRIMARY] = "QXL_IO_DETACH_PRIMARY",
+[QXL_IO_ATTACH_PRIMARY] = "QXL_IO_ATTACH_PRIMARY",
+[QXL_IO_CREATE_PRIMARY] = "QXL_IO_CREATE_PRIMARY",
+[QXL_IO_DESTROY_PRIMARY]= "QXL_IO_DESTROY_PRIMARY",
+[QXL_IO_DESTROY_SURFACE_WAIT]   = "QXL_IO_DESTROY_SURFACE_WAIT",
+[QXL_IO_DESTROY_ALL_SURFACES]   = "QXL_IO_DESTROY_ALL_SURFACES",
+#if SPICE_INTERFACE_QXL_MINOR >= 1
+[QXL_IO_UPDATE_AREA_ASYNC]  = "QXL_IO_UPDATE_AREA_ASYNC",
+[QXL_IO_MEMSLOT_ADD_ASYNC]  = "QXL_IO_MEMSLOT_ADD_ASYNC",
+[QXL_IO_CREATE_PRIMARY_ASYNC]   = "QXL_IO_CREATE_PRIMARY_ASYNC",
+[QXL_IO_DESTROY_PRIMARY_ASYNC]  = "QXL_IO_DESTROY_PRIMARY_ASYNC",
+[QXL_IO_DESTROY_SURFACE_ASYNC]  = "QXL_IO_DESTROY_SURFACE_ASYNC",
+[QXL_IO_DESTROY_ALL_SURFACES_ASYNC]
+= "QXL_IO_DESTROY_ALL_SURFACES_ASYNC",
+[QXL_IO_FLUSH_SURFACES_ASYNC]   = "QXL_IO_FLUSH_SURFACES_ASYNC",
+[QXL_IO_FLUSH_RELEASE]  = "QXL_IO_FLUSH_RELEASE",
+#endif
+};
+return io_port_to_string[io_port];
+}
+
 /* called from spice server thread context only */
 static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
 {
@@ -1005,7 +1042,8 @@ static void ioport_write(void *opaque, uint32_t addr, 
uint32_t val)
 default:
 if (d->mode == QXL_MODE_NATIVE || d->mode == QXL_MODE_COMPAT)
 break;
-dprint(d, 1, "%s: unexpected port 0x%x in vga mode\n", __FUNCTION__, 
io_port);
+dprint(d, 1, "%s: unexpected port 0x%x (%s) in vga mode\n",
+__func__, io_port, io_port_to_string(io_port));
 return;
 }
 
-- 
1.7.1




[Qemu-devel] [PATCH 09/11] qxl: async io support using new spice api

2011-08-03 Thread Gerd Hoffmann
From: Alon Levy 

Some of the QXL port i/o commands are waiting for the spice server to
complete certain actions.  Add async versions for these commands, so we
don't block the vcpu while the spice server processses the command.
Instead the qxl device will raise an IRQ when done.

The async command processing relies on an added QXLInterface::async_complete
and added QXLWorker::*_async additions, in spice server qxl >= 3.1

Signed-off-by: Gerd Hoffmann 
Signed-off-by: Alon Levy 
---
 hw/qxl-render.c|2 +-
 hw/qxl.c   |  240 
 hw/qxl.h   |   16 +++-
 ui/spice-display.c |   47 --
 ui/spice-display.h |   23 +-
 5 files changed, 274 insertions(+), 54 deletions(-)

diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index 60b822d..643ff2d 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -125,7 +125,7 @@ void qxl_render_update(PCIQXLDevice *qxl)
 
 memset(dirty, 0, sizeof(dirty));
 qxl_spice_update_area(qxl, 0, &update,
-  dirty, ARRAY_SIZE(dirty), 1);
+  dirty, ARRAY_SIZE(dirty), 1, QXL_SYNC);
 
 for (i = 0; i < ARRAY_SIZE(dirty); i++) {
 if (qemu_spice_rect_is_empty(dirty+i)) {
diff --git a/hw/qxl.c b/hw/qxl.c
index 23e3240..d3109e4 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -120,7 +120,7 @@ static QXLMode qxl_modes[] = {
 static PCIQXLDevice *qxl0;
 
 static void qxl_send_events(PCIQXLDevice *d, uint32_t events);
-static void qxl_destroy_primary(PCIQXLDevice *d);
+static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async);
 static void qxl_reset_memslots(PCIQXLDevice *d);
 static void qxl_reset_surfaces(PCIQXLDevice *d);
 static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
@@ -144,22 +144,47 @@ void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, 
...)
 void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
struct QXLRect *area, struct QXLRect *dirty_rects,
uint32_t num_dirty_rects,
-   uint32_t clear_dirty_region)
+   uint32_t clear_dirty_region,
+   qxl_async_io async)
 {
-qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area, 
dirty_rects,
- num_dirty_rects, clear_dirty_region);
+if (async == QXL_SYNC) {
+qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area,
+dirty_rects, num_dirty_rects, clear_dirty_region);
+} else {
+#if SPICE_INTERFACE_QXL_MINOR >= 1
+spice_qxl_update_area_async(&qxl->ssd.qxl, surface_id, area,
+clear_dirty_region, 0);
+#else
+abort();
+#endif
+}
 }
 
-void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id)
+static void qxl_spice_destroy_surface_wait_complete(PCIQXLDevice *qxl,
+uint32_t id)
 {
 qemu_mutex_lock(&qxl->track_lock);
-PANIC_ON(id >= NUM_SURFACES);
-qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
 qxl->guest_surfaces.cmds[id] = 0;
 qxl->guest_surfaces.count--;
 qemu_mutex_unlock(&qxl->track_lock);
 }
 
+static void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id,
+   qxl_async_io async)
+{
+if (async) {
+#if SPICE_INTERFACE_QXL_MINOR < 1
+abort();
+#else
+spice_qxl_destroy_surface_async(&qxl->ssd.qxl, id,
+(uint64_t)id);
+#endif
+} else {
+qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
+qxl_spice_destroy_surface_wait_complete(qxl, id);
+}
+}
+
 void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
uint32_t count)
 {
@@ -176,15 +201,28 @@ void qxl_spice_reset_memslots(PCIQXLDevice *qxl)
 qxl->ssd.worker->reset_memslots(qxl->ssd.worker);
 }
 
-void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl)
+static void qxl_spice_destroy_surfaces_complete(PCIQXLDevice *qxl)
 {
 qemu_mutex_lock(&qxl->track_lock);
-qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker);
 memset(&qxl->guest_surfaces.cmds, 0, sizeof(qxl->guest_surfaces.cmds));
 qxl->guest_surfaces.count = 0;
 qemu_mutex_unlock(&qxl->track_lock);
 }
 
+static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, qxl_async_io async)
+{
+if (async) {
+#if SPICE_INTERFACE_QXL_MINOR < 1
+abort();
+#else
+spice_qxl_destroy_surfaces_async(&qxl->ssd.qxl, 0);
+#endif
+} else {
+qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker);
+qxl_spice_destroy_surfaces_complete(qxl);
+}
+}
+
 void qxl_spice_reset_image_cache(PCIQXLDevice *qxl)
 {
 qxl->ssd.worker->reset_image_cache(qxl->ssd.worker);
@@ -689,6 +727,38 @@ static int interface_flush_resources(QXLInstance *sin)
 return ret;
 }
 
+static void qxl_create_guest_primary_complete(

[Qemu-devel] [PATCH 04/11] qxl: fix surface tracking & locking

2011-08-03 Thread Gerd Hoffmann
Surface tracking needs proper locking since it is used from vcpu and spice
worker threads, add it.  Also reset the surface counter when zapping all
surfaces.

Signed-off-by: Gerd Hoffmann 
---
 hw/qxl.c |   13 -
 hw/qxl.h |2 ++
 2 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 803a364..416bd48 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -137,7 +137,12 @@ void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t 
surface_id,
 
 void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id)
 {
+qemu_mutex_lock(&qxl->track_lock);
+PANIC_ON(id >= NUM_SURFACES);
 qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
+qxl->guest_surfaces.cmds[id] = 0;
+qxl->guest_surfaces.count--;
+qemu_mutex_unlock(&qxl->track_lock);
 }
 
 void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
@@ -158,7 +163,11 @@ void qxl_spice_reset_memslots(PCIQXLDevice *qxl)
 
 void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl)
 {
+qemu_mutex_lock(&qxl->track_lock);
 qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker);
+memset(&qxl->guest_surfaces.cmds, 0, sizeof(qxl->guest_surfaces.cmds));
+qxl->guest_surfaces.count = 0;
+qemu_mutex_unlock(&qxl->track_lock);
 }
 
 void qxl_spice_reset_image_cache(PCIQXLDevice *qxl)
@@ -317,6 +326,7 @@ static void qxl_track_command(PCIQXLDevice *qxl, struct 
QXLCommandExt *ext)
 QXLSurfaceCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
 uint32_t id = le32_to_cpu(cmd->surface_id);
 PANIC_ON(id >= NUM_SURFACES);
+qemu_mutex_lock(&qxl->track_lock);
 if (cmd->type == QXL_SURFACE_CMD_CREATE) {
 qxl->guest_surfaces.cmds[id] = ext->cmd.data;
 qxl->guest_surfaces.count++;
@@ -327,6 +337,7 @@ static void qxl_track_command(PCIQXLDevice *qxl, struct 
QXLCommandExt *ext)
 qxl->guest_surfaces.cmds[id] = 0;
 qxl->guest_surfaces.count--;
 }
+qemu_mutex_unlock(&qxl->track_lock);
 break;
 }
 case QXL_CMD_CURSOR:
@@ -863,7 +874,6 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
 dprint(d, 1, "%s:\n", __FUNCTION__);
 d->mode = QXL_MODE_UNDEFINED;
 qxl_spice_destroy_surfaces(d);
-memset(&d->guest_surfaces.cmds, 0, sizeof(d->guest_surfaces.cmds));
 }
 
 /* called from spice server thread context only */
@@ -1283,6 +1293,7 @@ static int qxl_init_common(PCIQXLDevice *qxl)
 qxl->generation = 1;
 qxl->num_memslots = NUM_MEMSLOTS;
 qxl->num_surfaces = NUM_SURFACES;
+qemu_mutex_init(&qxl->track_lock);
 
 switch (qxl->revision) {
 case 1: /* spice 0.4 -- qxl-1 */
diff --git a/hw/qxl.h b/hw/qxl.h
index e62b9d0..5d0e85e 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -55,6 +55,8 @@ typedef struct PCIQXLDevice {
 } guest_surfaces;
 QXLPHYSICALguest_cursor;
 
+QemuMutex  track_lock;
+
 /* thread signaling */
 pthread_t  main;
 intpipe[2];
-- 
1.7.1




[Qemu-devel] [PATCH 03/11] spice/qxl: move worker wrappers

2011-08-03 Thread Gerd Hoffmann
Move the wrapper functions which are used by qxl only to qxl.c.
Rename them from qemu_spice_* to qxl_spice_*.  Also pass in a
qxl state pointer instead of a SimpleSpiceDisplay pointer.

Signed-off-by: Gerd Hoffmann 
---
 hw/qxl-render.c|4 +-
 hw/qxl.c   |   67 ---
 hw/qxl.h   |   13 ++
 ui/spice-display.c |   46 ---
 ui/spice-display.h |   12 -
 5 files changed, 72 insertions(+), 70 deletions(-)

diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index bef5f14..60b822d 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -124,8 +124,8 @@ void qxl_render_update(PCIQXLDevice *qxl)
 update.bottom = qxl->guest_primary.surface.height;
 
 memset(dirty, 0, sizeof(dirty));
-qemu_spice_update_area(&qxl->ssd, 0, &update,
-   dirty, ARRAY_SIZE(dirty), 1);
+qxl_spice_update_area(qxl, 0, &update,
+  dirty, ARRAY_SIZE(dirty), 1);
 
 for (i = 0; i < ARRAY_SIZE(dirty); i++) {
 if (qemu_spice_rect_is_empty(dirty+i)) {
diff --git a/hw/qxl.c b/hw/qxl.c
index 2127fa3..803a364 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -125,6 +125,53 @@ static void qxl_reset_memslots(PCIQXLDevice *d);
 static void qxl_reset_surfaces(PCIQXLDevice *d);
 static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
 
+
+void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
+   struct QXLRect *area, struct QXLRect *dirty_rects,
+   uint32_t num_dirty_rects,
+   uint32_t clear_dirty_region)
+{
+qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area, 
dirty_rects,
+ num_dirty_rects, clear_dirty_region);
+}
+
+void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id)
+{
+qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
+}
+
+void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
+   uint32_t count)
+{
+qxl->ssd.worker->loadvm_commands(qxl->ssd.worker, ext, count);
+}
+
+void qxl_spice_oom(PCIQXLDevice *qxl)
+{
+qxl->ssd.worker->oom(qxl->ssd.worker);
+}
+
+void qxl_spice_reset_memslots(PCIQXLDevice *qxl)
+{
+qxl->ssd.worker->reset_memslots(qxl->ssd.worker);
+}
+
+void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl)
+{
+qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker);
+}
+
+void qxl_spice_reset_image_cache(PCIQXLDevice *qxl)
+{
+qxl->ssd.worker->reset_image_cache(qxl->ssd.worker);
+}
+
+void qxl_spice_reset_cursor(PCIQXLDevice *qxl)
+{
+qxl->ssd.worker->reset_cursor(qxl->ssd.worker);
+}
+
+
 static inline uint32_t msb_mask(uint32_t val)
 {
 uint32_t mask;
@@ -684,8 +731,8 @@ static void qxl_hard_reset(PCIQXLDevice *d, int loadvm)
 dprint(d, 1, "%s: start%s\n", __FUNCTION__,
loadvm ? " (loadvm)" : "");
 
-qemu_spice_reset_cursor(&d->ssd);
-qemu_spice_reset_image_cache(&d->ssd);
+qxl_spice_reset_cursor(d);
+qxl_spice_reset_image_cache(d);
 qxl_reset_surfaces(d);
 qxl_reset_memslots(d);
 
@@ -807,7 +854,7 @@ static void qxl_del_memslot(PCIQXLDevice *d, uint32_t 
slot_id)
 static void qxl_reset_memslots(PCIQXLDevice *d)
 {
 dprint(d, 1, "%s:\n", __FUNCTION__);
-qemu_spice_reset_memslots(&d->ssd);
+qxl_spice_reset_memslots(d);
 memset(&d->guest_slots, 0, sizeof(d->guest_slots));
 }
 
@@ -815,7 +862,7 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
 {
 dprint(d, 1, "%s:\n", __FUNCTION__);
 d->mode = QXL_MODE_UNDEFINED;
-qemu_spice_destroy_surfaces(&d->ssd);
+qxl_spice_destroy_surfaces(d);
 memset(&d->guest_surfaces.cmds, 0, sizeof(d->guest_surfaces.cmds));
 }
 
@@ -956,8 +1003,8 @@ static void ioport_write(void *opaque, uint32_t addr, 
uint32_t val)
 case QXL_IO_UPDATE_AREA:
 {
 QXLRect update = d->ram->update_area;
-qemu_spice_update_area(&d->ssd, d->ram->update_surface,
-   &update, NULL, 0, 0);
+qxl_spice_update_area(d, d->ram->update_surface,
+  &update, NULL, 0, 0);
 break;
 }
 case QXL_IO_NOTIFY_CMD:
@@ -978,7 +1025,7 @@ static void ioport_write(void *opaque, uint32_t addr, 
uint32_t val)
 break;
 }
 d->oom_running = 1;
-qemu_spice_oom(&d->ssd);
+qxl_spice_oom(d);
 d->oom_running = 0;
 break;
 case QXL_IO_SET_MODE:
@@ -1016,10 +1063,10 @@ static void ioport_write(void *opaque, uint32_t addr, 
uint32_t val)
 qxl_destroy_primary(d);
 break;
 case QXL_IO_DESTROY_SURFACE_WAIT:
-qemu_spice_destroy_surface_wait(&d->ssd, val);
+qxl_spice_destroy_surface_wait(d, val);
 break;
 case QXL_IO_DESTROY_ALL_SURFACES:
-qemu_spice_destroy_surfaces(&d->ssd);
+qxl_spice_destroy_surfaces(d);
 break;
 default:
 fprintf(stderr, "%s: ioport=0x%x, abo

[Qemu-devel] [PATCH 06/11] qxl: error handling fixes and cleanups.

2011-08-03 Thread Gerd Hoffmann
Add qxl_guest_bug() function which is supposed to be called in case
sanity checks of guest requests fail.  It raises an error IRQ and
logs a message in case guest debugging is enabled.

Make PANIC_ON() abort instead of exit.  That macro should be used
for qemu bugs only, any guest-triggerable stuff should use the new
qxl_guest_bug() function instead.

Convert a few easy cases from PANIC_ON() to qxl_guest_bug() to
show intended usage.

Signed-off-by: Gerd Hoffmann 
---
 hw/qxl.c |   34 ++
 hw/qxl.h |3 ++-
 2 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 6e66021..28c8b5d 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -125,6 +125,16 @@ static void qxl_reset_memslots(PCIQXLDevice *d);
 static void qxl_reset_surfaces(PCIQXLDevice *d);
 static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
 
+void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg)
+{
+#if SPICE_INTERFACE_QXL_MINOR >= 1
+qxl_send_events(qxl, QXL_INTERRUPT_ERROR);
+#endif
+if (qxl->guestdebug) {
+fprintf(stderr, "qxl-%d: guest bug: %s\n", qxl->id, msg);
+}
+}
+
 
 void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
struct QXLRect *area, struct QXLRect *dirty_rects,
@@ -1091,22 +1101,38 @@ static void ioport_write(void *opaque, uint32_t addr, 
uint32_t val)
 qxl_hard_reset(d, 0);
 break;
 case QXL_IO_MEMSLOT_ADD:
-PANIC_ON(val >= NUM_MEMSLOTS);
-PANIC_ON(d->guest_slots[val].active);
+if (val >= NUM_MEMSLOTS) {
+qxl_guest_bug(d, "QXL_IO_MEMSLOT_ADD: val out of range");
+break;
+}
+if (d->guest_slots[val].active) {
+qxl_guest_bug(d, "QXL_IO_MEMSLOT_ADD: memory slot already active");
+break;
+}
 d->guest_slots[val].slot = d->ram->mem_slot;
 qxl_add_memslot(d, val, 0);
 break;
 case QXL_IO_MEMSLOT_DEL:
+if (val >= NUM_MEMSLOTS) {
+qxl_guest_bug(d, "QXL_IO_MEMSLOT_DEL: val out of range");
+break;
+}
 qxl_del_memslot(d, val);
 break;
 case QXL_IO_CREATE_PRIMARY:
-PANIC_ON(val != 0);
+if (val != 0) {
+qxl_guest_bug(d, "QXL_IO_CREATE_PRIMARY: val != 0");
+break;
+}
 dprint(d, 1, "QXL_IO_CREATE_PRIMARY\n");
 d->guest_primary.surface = d->ram->create_surface;
 qxl_create_guest_primary(d, 0);
 break;
 case QXL_IO_DESTROY_PRIMARY:
-PANIC_ON(val != 0);
+if (val != 0) {
+qxl_guest_bug(d, "QXL_IO_DESTROY_PRIMARY: val != 0");
+break;
+}
 dprint(d, 1, "QXL_IO_DESTROY_PRIMARY (%s)\n", 
qxl_mode_to_string(d->mode));
 qxl_destroy_primary(d);
 break;
diff --git a/hw/qxl.h b/hw/qxl.h
index 5d0e85e..5db9aae 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -86,7 +86,7 @@ typedef struct PCIQXLDevice {
 
 #define PANIC_ON(x) if ((x)) { \
 printf("%s: PANIC %s failed\n", __FUNCTION__, #x); \
-exit(-1);  \
+abort();   \
 }
 
 #define dprint(_qxl, _level, _fmt, ...) \
@@ -99,6 +99,7 @@ typedef struct PCIQXLDevice {
 
 /* qxl.c */
 void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id);
+void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg);
 
 void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
struct QXLRect *area, struct QXLRect *dirty_rects,
-- 
1.7.1




[Qemu-devel] [PATCH 1/3] slirp: Take maintainer token

2011-08-03 Thread Jan Kiszka
Anthony asked me to pick up the maintenance of this subsystem, and I
agreed.

Signed-off-by: Jan Kiszka 
---
 MAINTAINERS |5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 6115e4e..7cbcd7e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -431,9 +431,10 @@ S: Maintained
 F: net/
 
 SLIRP
-M: qemu-devel@nongnu.org
-S: Orphan
+M: Jan Kiszka 
+S: Maintained
 F: slirp/
+T: git://git.kiszka.org/qemu.git queues/slirp
 
 Usermode Emulation
 --
-- 
1.7.3.4




[Qemu-devel] [PATCH 3/3] Delayed IP packets

2011-08-03 Thread Jan Kiszka
From: Fabien Chouteau 

In the current implementation, if Slirp tries to send an IP packet to a client
with an unknown hardware address, the packet is simply dropped and an ARP
request is sent (if_encap in slirp/slirp.c).

With this patch, Slirp will send the ARP request, re-queue the packet and try
to send it later. The packet is dropped after one second if the ARP reply is
not received.

Signed-off-by: Fabien Chouteau 
Signed-off-by: Jan Kiszka 
---
 slirp/if.c|   28 +++---
 slirp/main.h  |2 +-
 slirp/mbuf.c  |2 +
 slirp/mbuf.h  |2 +
 slirp/slirp.c |   72 +++-
 5 files changed, 69 insertions(+), 37 deletions(-)

diff --git a/slirp/if.c b/slirp/if.c
index 0f04e13..2d79e45 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -6,6 +6,7 @@
  */
 
 #include 
+#include "qemu-timer.h"
 
 #define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm))
 
@@ -105,6 +106,9 @@ if_output(struct socket *so, struct mbuf *ifm)
ifs_init(ifm);
insque(ifm, ifq);
 
+/* Expiration date = Now + 1 second */
+ifm->expiration_date = qemu_get_clock_ns(rt_clock) + 10ULL;
+
 diddit:
slirp->if_queued++;
 
@@ -153,6 +157,9 @@ diddit:
 void
 if_start(Slirp *slirp)
 {
+int requeued = 0;
+uint64_t now;
+
struct mbuf *ifm, *ifqt;
 
DEBUG_CALL("if_start");
@@ -165,6 +172,8 @@ if_start(Slirp *slirp)
 if (!slirp_can_output(slirp->opaque))
 return;
 
+now = qemu_get_clock_ns(rt_clock);
+
/*
 * See which queue to get next packet from
 * If there's something in the fastq, select it immediately
@@ -199,11 +208,22 @@ if_start(Slirp *slirp)
   ifm->ifq_so->so_nqueued = 0;
}
 
-   /* Encapsulate the packet for sending */
-if_encap(slirp, (uint8_t *)ifm->m_data, ifm->m_len);
-
-m_free(ifm);
+if (ifm->expiration_date < now) {
+/* Expired */
+m_free(ifm);
+} else {
+/* Encapsulate the packet for sending */
+if (if_encap(slirp, ifm)) {
+m_free(ifm);
+} else {
+/* re-queue */
+insque(ifm, ifqt);
+requeued++;
+}
+}
 
if (slirp->if_queued)
   goto again;
+
+slirp->if_queued = requeued;
 }
diff --git a/slirp/main.h b/slirp/main.h
index 0dd8d81..028df4b 100644
--- a/slirp/main.h
+++ b/slirp/main.h
@@ -42,5 +42,5 @@ extern int tcp_keepintvl;
 #define PROTO_PPP 0x2
 #endif
 
-void if_encap(Slirp *slirp, const uint8_t *ip_data, int ip_data_len);
+int if_encap(Slirp *slirp, struct mbuf *ifm);
 ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags);
diff --git a/slirp/mbuf.c b/slirp/mbuf.c
index ce2eb84..c699c75 100644
--- a/slirp/mbuf.c
+++ b/slirp/mbuf.c
@@ -70,6 +70,8 @@ m_get(Slirp *slirp)
m->m_len = 0;
 m->m_nextpkt = NULL;
 m->m_prevpkt = NULL;
+m->arp_requested = false;
+m->expiration_date = (uint64_t)-1;
 end_error:
DEBUG_ARG("m = %lx", (long )m);
return m;
diff --git a/slirp/mbuf.h b/slirp/mbuf.h
index b74544b..55170e5 100644
--- a/slirp/mbuf.h
+++ b/slirp/mbuf.h
@@ -86,6 +86,8 @@ struct mbuf {
charm_dat_[1]; /* ANSI don't like 0 sized arrays */
char*m_ext_;
} M_dat;
+bool arp_requested;
+uint64_t expiration_date;
 };
 
 #define m_next m_hdr.mh_next
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 4a9a4d5..a86cc6e 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -692,55 +692,63 @@ void slirp_input(Slirp *slirp, const uint8_t *pkt, int 
pkt_len)
 }
 }
 
-/* output the IP packet to the ethernet device */
-void if_encap(Slirp *slirp, const uint8_t *ip_data, int ip_data_len)
+/* Output the IP packet to the ethernet device. Returns 0 if the packet must be
+ * re-queued.
+ */
+int if_encap(Slirp *slirp, struct mbuf *ifm)
 {
 uint8_t buf[1600];
 struct ethhdr *eh = (struct ethhdr *)buf;
 uint8_t ethaddr[ETH_ALEN];
-const struct ip *iph = (const struct ip *)ip_data;
+const struct ip *iph = (const struct ip *)ifm->m_data;
 
-if (ip_data_len + ETH_HLEN > sizeof(buf))
-return;
+if (ifm->m_len + ETH_HLEN > sizeof(buf)) {
+return 1;
+}
 
 if (!arp_table_search(slirp, iph->ip_dst.s_addr, ethaddr)) {
 uint8_t arp_req[ETH_HLEN + sizeof(struct arphdr)];
 struct ethhdr *reh = (struct ethhdr *)arp_req;
 struct arphdr *rah = (struct arphdr *)(arp_req + ETH_HLEN);
 
-/* If the client addr is not known, there is no point in
-   sending the packet to it. Normally the sender should have
-   done an ARP request to get its MAC address. Here we do it
-   in place of sending the packet and we hope that the sender
-   will retry sending its packet. */
-memset(reh->h_dest, 0xff, ETH_ALEN);

[Qemu-devel] [PATCH 0/3] [PULL] slirp: ARP table improvements

2011-08-03 Thread Jan Kiszka
The following changes since commit 927d721777e73339f73719f36eaf400ab641366c:

  microblaze: Add missing call to qemu_init_vcpu. (2011-07-31 06:40:13 +0200)

are available in the git repository at:
  git://git.kiszka.org/qemu.git queues/slirp

Anthony asked me to look after slirp patches, and I agreed. So here
comes the first pull request. It improves the so far minimalistic ARP
support of slirp by avoiding premature packet drops when addressing not
yet resolved client IPs.


CC: Fabien Chouteau 

Fabien Chouteau (2):
  Simple ARP table
  Delayed IP packets

Jan Kiszka (1):
  slirp: Take maintainer token

 MAINTAINERS   |5 +-
 Makefile.objs |2 +-
 slirp/arp_table.c |   95 +
 slirp/bootp.c |   21 +---
 slirp/if.c|   28 +--
 slirp/main.h  |2 +-
 slirp/mbuf.c  |2 +
 slirp/mbuf.h  |2 +
 slirp/slirp.c |  135 ++---
 slirp/slirp.h |   47 +-
 10 files changed, 241 insertions(+), 98 deletions(-)
 create mode 100644 slirp/arp_table.c

-- 
1.7.3.4




[Qemu-devel] [PATCH 2/3] Simple ARP table

2011-08-03 Thread Jan Kiszka
From: Fabien Chouteau 

This patch adds a simple ARP table in Slirp and also adds handling of
gratuitous ARP requests.

Signed-off-by: Fabien Chouteau 
Signed-off-by: Jan Kiszka 
---
 Makefile.objs |2 +-
 slirp/arp_table.c |   95 +
 slirp/bootp.c |   21 +++
 slirp/slirp.c |   63 +--
 slirp/slirp.h |   47 --
 5 files changed, 169 insertions(+), 59 deletions(-)
 create mode 100644 slirp/arp_table.c

diff --git a/Makefile.objs b/Makefile.objs
index 6991a9f..0c10557 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -151,7 +151,7 @@ common-obj-y += qemu-timer.o qemu-timer-common.o
 
 slirp-obj-y = cksum.o if.o ip_icmp.o ip_input.o ip_output.o
 slirp-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o
-slirp-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o
+slirp-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o arp_table.o
 common-obj-$(CONFIG_SLIRP) += $(addprefix slirp/, $(slirp-obj-y))
 
 # xen backend driver support
diff --git a/slirp/arp_table.c b/slirp/arp_table.c
new file mode 100644
index 000..820dee2
--- /dev/null
+++ b/slirp/arp_table.c
@@ -0,0 +1,95 @@
+/*
+ * ARP table
+ *
+ * Copyright (c) 2011 AdaCore
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "slirp.h"
+
+void arp_table_add(Slirp *slirp, int ip_addr, uint8_t ethaddr[ETH_ALEN])
+{
+const in_addr_t broadcast_addr =
+~slirp->vnetwork_mask.s_addr | slirp->vnetwork_addr.s_addr;
+ArpTable *arptbl = &slirp->arp_table;
+int i;
+
+DEBUG_CALL("arp_table_add");
+DEBUG_ARG("ip = 0x%x", ip_addr);
+DEBUG_ARGS((dfd, " hw addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
+ethaddr[0], ethaddr[1], ethaddr[2],
+ethaddr[3], ethaddr[4], ethaddr[5]));
+
+/* Check 0.0.0.0/8 invalid source-only addresses */
+assert((ip_addr & htonl(~(0xf << 28))) != 0);
+
+if (ip_addr == 0x || ip_addr == broadcast_addr) {
+/* Do not register broadcast addresses */
+return;
+}
+
+/* Search for an entry */
+for (i = 0; i < ARP_TABLE_SIZE; i++) {
+if (arptbl->table[i].ar_sip == ip_addr) {
+/* Update the entry */
+memcpy(arptbl->table[i].ar_sha, ethaddr, ETH_ALEN);
+return;
+}
+}
+
+/* No entry found, create a new one */
+arptbl->table[arptbl->next_victim].ar_sip = ip_addr;
+memcpy(arptbl->table[arptbl->next_victim].ar_sha,  ethaddr, ETH_ALEN);
+arptbl->next_victim = (arptbl->next_victim + 1) % ARP_TABLE_SIZE;
+}
+
+bool arp_table_search(Slirp *slirp, int in_ip_addr,
+  uint8_t out_ethaddr[ETH_ALEN])
+{
+const in_addr_t broadcast_addr =
+~slirp->vnetwork_mask.s_addr | slirp->vnetwork_addr.s_addr;
+ArpTable *arptbl = &slirp->arp_table;
+int i;
+
+DEBUG_CALL("arp_table_search");
+DEBUG_ARG("ip = 0x%x", in_ip_addr);
+
+/* Check 0.0.0.0/8 invalid source-only addresses */
+assert((in_ip_addr & htonl(~(0xf << 28))) != 0);
+
+/* If broadcast address */
+if (in_ip_addr == 0x || in_ip_addr == broadcast_addr) {
+/* return Ethernet broadcast address */
+memset(out_ethaddr, 0xff, ETH_ALEN);
+return 1;
+}
+
+for (i = 0; i < ARP_TABLE_SIZE; i++) {
+if (arptbl->table[i].ar_sip == in_ip_addr) {
+memcpy(out_ethaddr, arptbl->table[i].ar_sha,  ETH_ALEN);
+DEBUG_ARGS((dfd, " found hw addr = 
%02x:%02x:%02x:%02x:%02x:%02x\n",
+out_ethaddr[0], out_ethaddr[1], out_ethaddr[2],
+out_ethaddr[3], out_ethaddr[4], out_ethaddr[5]));
+return 1;
+}
+}
+
+return 0;
+}
diff --git a/slirp/bootp.c b/slirp/bootp.c
index 1eb2ed1..efd1fe7 100644
--- a/slirp/bootp.c
+++ b/slirp/bootp.c
@@ -149,6 +149,7 @@ static void bootp_reply(Slirp *sl

Re: [Qemu-devel] qemu-kvm aborts - vhost_dev_unassign_memory: Assertion `to >= 0' failed.

2011-08-03 Thread Avi Kivity

On 08/01/2011 08:44 PM, David Ahern wrote:

qemu-kvm.git as of:

commit dacdc4b10bafbb21120e1c24a9665444768ef999
Merge: 7b69d4f 0af4922
Author: Avi Kivity
Date:   Sun Jul 31 11:42:26 2011 +0300

 Merge branch 'upstream-merge' into next

is aborting with the error:

qemu-kvm: qemu-kvm.git/hw/vhost.c:123: vhost_dev_unassign_memory:
Assertion `to>= 0' failed.
Aborted



It's a bug in vhost:

/* Assign/unassign. Keep an unsorted array of non-overlapping
 * memory regions in dev->mem. */
static void vhost_dev_unassign_memory(struct vhost_dev *dev,
  uint64_t start_addr,
  uint64_t size)
{
int from, to, n = dev->mem->nregions;
/* Track overlapping/split regions for sanity checking. */
int overlap_start = 0, overlap_end = 0, overlap_middle = 0, split = 0;

for (from = 0, to = 0; from < n; ++from, ++to) {
struct vhost_memory_region *reg = dev->mem->regions + to;
uint64_t reglast;
uint64_t memlast;
uint64_t change;

/* clone old region */
if (to != from) {
memcpy(reg, dev->mem->regions + from, sizeof *reg);
}

/* No overlap is simple */
if (!ranges_overlap(reg->guest_phys_addr, reg->memory_size,
start_addr, size)) {
continue;
}

/* Split only happens if supplied region
 * is in the middle of an existing one. Thus it can not
 * overlap with any other existing region. */
assert(!split);

reglast = range_get_last(reg->guest_phys_addr, reg->memory_size);
memlast = range_get_last(start_addr, size);

/* Remove whole region */
if (start_addr <= reg->guest_phys_addr && memlast >= reglast) {
--dev->mem->nregions;
--to;
assert(to >= 0);
++overlap_middle;
continue;
}


We're removing the first region, and 'to' goes negative.  Michael?

--
error compiling committee.c: too many arguments to function




Re: [Qemu-devel] [PATCH] memory: use signed arithmetic

2011-08-03 Thread Benjamin Herrenschmidt
On Wed, 2011-08-03 at 11:26 +0300, Avi Kivity wrote:
> On 08/03/2011 01:15 AM, Richard Henderson wrote:
> > On 08/02/2011 03:06 PM, Avi Kivity wrote:
> > >  I don't think there's any cpu which has a real 64-bit physical
> > >  address space? Don't they all truncate it?
> >
> > I don't know.  You're right that x86_64 does, at 48 bits.
> > The alpha system I'm trying to emulate does, at 50 bits.
> >
> > I guess if IBM agrees wrt p-series and z-series emulation, then
> > I'd be ok, so long as you add a comment above that structure that
> > says no existing hw implementation actually uses 63 address bits.
> 
> Ben, can you confirm that pseries physical addresses are 63 bits wide or 
> smaller?
> 
> IIRC zseries has no mmio, and Zettabyte machines are still rare.

We are fine yes. We might grow to 50 bits but I doubt we'll ever do the
full 64, especially since we have some hard-wired assumptions that in
real mode (MMU off) the top 2 bits are ignored.

Cheers,
Ben.
 




[Qemu-devel] [PATCH v2 01/38] pci: add API to get a BAR's mapped address

2011-08-03 Thread Avi Kivity
This is a hack, for devices that have a back-channel to read this
address back outside the normal configuration mechanisms, such
as VMware svga.

Reviewed-by: Richard Henderson 
Signed-off-by: Avi Kivity 
---
 hw/pci.c |5 +
 hw/pci.h |1 +
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 36db58b..912f849 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -952,6 +952,11 @@ void pci_register_bar_region(PCIDevice *pci_dev, int 
region_num,
 pci_dev->io_regions[region_num].memory = memory;
 }
 
+pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num)
+{
+return pci_dev->io_regions[region_num].addr;
+}
+
 static void pci_bridge_filter(PCIDevice *d, pcibus_t *addr, pcibus_t *size,
   uint8_t type)
 {
diff --git a/hw/pci.h b/hw/pci.h
index c51156d..64282ad 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -207,6 +207,7 @@ void pci_register_bar_simple(PCIDevice *pci_dev, int 
region_num,
  pcibus_t size, uint8_t attr, ram_addr_t ram_addr);
 void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
  uint8_t attr, MemoryRegion *memory);
+pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num);
 
 int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
uint8_t offset, uint8_t size);
-- 
1.7.5.3




[Qemu-devel] [PATCH v2 00/38] Memory API, batch 2: PCI devices

2011-08-03 Thread Avi Kivity
This is a mostly mindless conversion of all QEMU PCI devices to the memory API.
After this patchset is applied, it is no longer possible to create a PCI device
using the old API.

An immediate benefit is that PCI BARs that overlap each other are now handled
correctly: currently, the sequence

  map BAR 0
  map BAR 1 at an overlapping address
  unmap either BAR 0 or BAR 1

will leave a hole where the overlap exists.  With the patchset, the memory map
is restored correctly.

Note that overlaps of PCI BARs with memory or non-PCI resources are still not
resolved correctly; this will be fixed later on.

The vga patches have ugly intermediate states; however the result is fairly 
clean.

This patchset should be merged after

  memory: synchronize dirty bitmap before unmapping a range
  memory: use signed arithmetic

though there's no hard dependency.

Changes from v1:
 - cmd646 type fix
 - folded a fixlet into its parent


Avi Kivity (38):
  pci: add API to get a BAR's mapped address
  vmsvga: don't remember pci BAR address in callback any more
  vga: convert vga and its derivatives to the memory API
  cirrus: simplify mmio BAR access functions
  cirrus: simplify bitblt BAR access functions
  cirrus: simplify vga window mmio access functions
  vga: simplify vga window mmio access functions
  cirrus: simplify linear framebuffer access functions
  Integrate I/O memory regions into qemu
  pci: pass I/O address space to new PCI bus
  pci: allow I/O BARs to be registered with pci_register_bar_region()
  rtl8139: convert to memory API
  ac97: convert to memory API
  e1000: convert to memory API
  eepro100: convert to memory API
  es1370: convert to memory API
  ide: convert to memory API
  ivshmem: convert to memory API
  virtio-pci: convert to memory API
  ahci: convert to memory API
  intel-hda: convert to memory API
  lsi53c895a: convert to memory API
  ppc: convert to memory API
  ne2000: convert to memory API
  pcnet: convert to memory API
  i6300esb: convert to memory API
  isa-mmio: concert to memory API
  sun4u: convert to memory API
  ehci: convert to memory API
  uhci: convert to memory API
  xen-platform: convert to memory API
  msix: convert to memory API
  pci: remove pci_register_bar_simple()
  pci: convert pci rom to memory API
  pci: remove pci_register_bar()
  pci: fold BAR mapping function into its caller
  pci: rename pci_register_bar_region() to pci_register_bar()
  pci: remove support for pre memory API BARs

 exec-memory.h  |2 +
 exec.c |   10 ++
 hw/ac97.c  |   88 ++-
 hw/apb_pci.c   |1 +
 hw/bonito.c|1 +
 hw/cirrus_vga.c|  458 ---
 hw/cuda.c  |6 +-
 hw/e1000.c |  113 ++
 hw/eepro100.c  |  181 -
 hw/es1370.c|   43 +++--
 hw/escc.c  |   42 +++---
 hw/escc.h  |2 +-
 hw/grackle_pci.c   |8 +-
 hw/gt64xxx.c   |4 +-
 hw/heathrow_pic.c  |   29 ++--
 hw/ide.h   |2 +-
 hw/ide/ahci.c  |   31 ++--
 hw/ide/ahci.h  |2 +-
 hw/ide/cmd646.c|  204 +++-
 hw/ide/ich.c   |3 +-
 hw/ide/macio.c |   36 +++--
 hw/ide/pci.c   |   25 ++--
 hw/ide/pci.h   |   19 ++-
 hw/ide/piix.c  |   63 ++--
 hw/ide/via.c   |   64 ++--
 hw/intel-hda.c |   35 +++--
 hw/isa.h   |2 +
 hw/isa_mmio.c  |   30 ++--
 hw/ivshmem.c   |  158 +++
 hw/lance.c |   31 ++--
 hw/lsi53c895a.c|  257 +++---
 hw/mac_dbdma.c |   32 ++--
 hw/mac_dbdma.h |4 +-
 hw/mac_nvram.c |   39 ++---
 hw/macio.c |   73 -
 hw/msix.c  |   64 +++-
 hw/msix.h  |6 +-
 hw/ne2000-isa.c|   14 +--
 hw/ne2000.c|   77 ++---
 hw/ne2000.h|8 +-
 hw/openpic.c   |   81 +-
 hw/openpic.h   |2 +-
 hw/pc.h|4 +-
 hw/pc_piix.c   |6 +-
 hw/pci.c   |  133 +---
 hw/pci.h   |   26 ++--
 hw/pci_internals.h |3 +-
 hw/pcnet-pci.c |   74 +
 hw/pcnet.h |4 +-
 hw/piix_pci.c  |   14 +-
 hw/ppc4xx_pci.c|1 +
 hw/ppc_mac.h   |   27 ++--
 hw/ppc_newworld.c  |   34 ++--
 hw/ppc_oldworld.c  |   27 ++--
 hw/ppc_prep.c  |2 +-
 hw/ppce500_pci.c   |7 +-
 hw/prep_pci.c  |8 +-
 hw/prep_pci.h  |4 +-
 hw/qxl-render.c|2 +-
 hw/qxl.c   |  129 ++--
 hw/qxl.h   |6 +-
 hw/rtl8139.c   |   70 
 hw/sh_pci.c|4 +-
 hw/sun4u.c |   53 +++
 hw/unin_pci.c  |   16 ++-
 hw/usb-ehci.c  |   36 +---
 hw/usb-ohci.c  |2 +-
 hw/usb-uhci.c  |   41 +++--
 hw/versatile_pci.c |2 +-
 hw/vga-isa-mm.c|   45 --
 hw/vga-isa.c   |   11 +-
 hw/vga-pci.c   |   27 +---
 hw/vga.c   |  179 -
 hw/vga_int.h   |   18 +--
 hw/virtio

[Qemu-devel] [PATCH v2 13/38] ac97: convert to memory API

2011-08-03 Thread Avi Kivity
fixes BAR sizing as well.

Reviewed-by: Richard Henderson 
Signed-off-by: Avi Kivity 
---
 hw/ac97.c |   88 +++-
 1 files changed, 51 insertions(+), 37 deletions(-)

diff --git a/hw/ac97.c b/hw/ac97.c
index 0b59896..bcddaa6 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -160,8 +160,9 @@ typedef struct AC97LinkState {
 SWVoiceIn *voice_mc;
 int invalid_freq[3];
 uint8_t silence[128];
-uint32_t base[2];
 int bup_flag;
+MemoryRegion io_nam;
+MemoryRegion io_nabm;
 } AC97LinkState;
 
 enum {
@@ -583,7 +584,7 @@ static uint32_t nam_readw (void *opaque, uint32_t addr)
 {
 AC97LinkState *s = opaque;
 uint32_t val = ~0U;
-uint32_t index = addr - s->base[0];
+uint32_t index = addr;
 s->cas = 0;
 val = mixer_load (s, index);
 return val;
@@ -611,7 +612,7 @@ static void nam_writeb (void *opaque, uint32_t addr, 
uint32_t val)
 static void nam_writew (void *opaque, uint32_t addr, uint32_t val)
 {
 AC97LinkState *s = opaque;
-uint32_t index = addr - s->base[0];
+uint32_t index = addr;
 s->cas = 0;
 switch (index) {
 case AC97_Reset:
@@ -714,7 +715,7 @@ static uint32_t nabm_readb (void *opaque, uint32_t addr)
 {
 AC97LinkState *s = opaque;
 AC97BusMasterRegs *r = NULL;
-uint32_t index = addr - s->base[1];
+uint32_t index = addr;
 uint32_t val = ~0U;
 
 switch (index) {
@@ -769,7 +770,7 @@ static uint32_t nabm_readw (void *opaque, uint32_t addr)
 {
 AC97LinkState *s = opaque;
 AC97BusMasterRegs *r = NULL;
-uint32_t index = addr - s->base[1];
+uint32_t index = addr;
 uint32_t val = ~0U;
 
 switch (index) {
@@ -798,7 +799,7 @@ static uint32_t nabm_readl (void *opaque, uint32_t addr)
 {
 AC97LinkState *s = opaque;
 AC97BusMasterRegs *r = NULL;
-uint32_t index = addr - s->base[1];
+uint32_t index = addr;
 uint32_t val = ~0U;
 
 switch (index) {
@@ -848,7 +849,7 @@ static void nabm_writeb (void *opaque, uint32_t addr, 
uint32_t val)
 {
 AC97LinkState *s = opaque;
 AC97BusMasterRegs *r = NULL;
-uint32_t index = addr - s->base[1];
+uint32_t index = addr;
 switch (index) {
 case PI_LVI:
 case PO_LVI:
@@ -904,7 +905,7 @@ static void nabm_writew (void *opaque, uint32_t addr, 
uint32_t val)
 {
 AC97LinkState *s = opaque;
 AC97BusMasterRegs *r = NULL;
-uint32_t index = addr - s->base[1];
+uint32_t index = addr;
 switch (index) {
 case PI_SR:
 case PO_SR:
@@ -924,7 +925,7 @@ static void nabm_writel (void *opaque, uint32_t addr, 
uint32_t val)
 {
 AC97LinkState *s = opaque;
 AC97BusMasterRegs *r = NULL;
-uint32_t index = addr - s->base[1];
+uint32_t index = addr;
 switch (index) {
 case PI_BDBAR:
 case PO_BDBAR:
@@ -1230,31 +1231,33 @@ static const VMStateDescription vmstate_ac97 = {
 }
 };
 
-static void ac97_map (PCIDevice *pci_dev, int region_num,
-  pcibus_t addr, pcibus_t size, int type)
-{
-AC97LinkState *s = DO_UPCAST (AC97LinkState, dev, pci_dev);
-PCIDevice *d = &s->dev;
-
-if (!region_num) {
-s->base[0] = addr;
-register_ioport_read (addr, 256 * 1, 1, nam_readb, d);
-register_ioport_read (addr, 256 * 2, 2, nam_readw, d);
-register_ioport_read (addr, 256 * 4, 4, nam_readl, d);
-register_ioport_write (addr, 256 * 1, 1, nam_writeb, d);
-register_ioport_write (addr, 256 * 2, 2, nam_writew, d);
-register_ioport_write (addr, 256 * 4, 4, nam_writel, d);
-}
-else {
-s->base[1] = addr;
-register_ioport_read (addr, 64 * 1, 1, nabm_readb, d);
-register_ioport_read (addr, 64 * 2, 2, nabm_readw, d);
-register_ioport_read (addr, 64 * 4, 4, nabm_readl, d);
-register_ioport_write (addr, 64 * 1, 1, nabm_writeb, d);
-register_ioport_write (addr, 64 * 2, 2, nabm_writew, d);
-register_ioport_write (addr, 64 * 4, 4, nabm_writel, d);
-}
-}
+static const MemoryRegionPortio nam_portio[] = {
+{ 0, 256 * 1, 1, .read = nam_readb, },
+{ 0, 256 * 2, 2, .read = nam_readw, },
+{ 0, 256 * 4, 4, .read = nam_readl, },
+{ 0, 256 * 1, 1, .write = nam_writeb, },
+{ 0, 256 * 2, 2, .write = nam_writew, },
+{ 0, 256 * 4, 4, .write = nam_writel, },
+PORTIO_END,
+};
+
+static const MemoryRegionOps ac97_io_nam_ops = {
+.old_portio = nam_portio,
+};
+
+static const MemoryRegionPortio nabm_portio[] = {
+{ 0, 64 * 1, 1, .read = nabm_readb, },
+{ 0, 64 * 2, 2, .read = nabm_readw, },
+{ 0, 64 * 4, 4, .read = nabm_readl, },
+{ 0, 64 * 1, 1, .write = nabm_writeb, },
+{ 0, 64 * 2, 2, .write = nabm_writew, },
+{ 0, 64 * 4, 4, .write = nabm_writel, },
+PORTIO_END
+};
+
+static const MemoryRegionOps ac97_io_nabm_ops = {
+.old_portio = nabm_portio,
+};
 
 static void ac97_on_reset (void *opaque)
 {
@@ -1311,15 +1314,25 @@ static int ac97_initfn (PCIDevice *dev)
 /* TODO: RST

[Qemu-devel] [PATCH v2 21/38] intel-hda: convert to memory API

2011-08-03 Thread Avi Kivity
Reviewed-by: Richard Henderson 
Signed-off-by: Avi Kivity 
---
 hw/intel-hda.c |   35 +++
 1 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 5a2bc3a..1e4c71e 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -177,7 +177,7 @@ struct IntelHDAState {
 IntelHDAStream st[8];
 
 /* state */
-int mmio_addr;
+MemoryRegion mmio;
 uint32_t rirb_count;
 int64_t wall_base_ns;
 
@@ -1084,16 +1084,20 @@ static uint32_t intel_hda_mmio_readl(void *opaque, 
target_phys_addr_t addr)
 return intel_hda_reg_read(d, reg, 0x);
 }
 
-static CPUReadMemoryFunc * const intel_hda_mmio_read[3] = {
-intel_hda_mmio_readb,
-intel_hda_mmio_readw,
-intel_hda_mmio_readl,
-};
-
-static CPUWriteMemoryFunc * const intel_hda_mmio_write[3] = {
-intel_hda_mmio_writeb,
-intel_hda_mmio_writew,
-intel_hda_mmio_writel,
+static const MemoryRegionOps intel_hda_mmio_ops = {
+.old_mmio = {
+.read = {
+intel_hda_mmio_readb,
+intel_hda_mmio_readw,
+intel_hda_mmio_readl,
+},
+.write = {
+intel_hda_mmio_writeb,
+intel_hda_mmio_writew,
+intel_hda_mmio_writel,
+},
+},
+.endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 /* - */
@@ -1130,10 +1134,9 @@ static int intel_hda_init(PCIDevice *pci)
 /* HDCTL off 0x40 bit 0 selects signaling mode (1-HDA, 0 - Ac97) 18.1.19 */
 conf[0x40] = 0x01;
 
-d->mmio_addr = cpu_register_io_memory(intel_hda_mmio_read,
-  intel_hda_mmio_write, d,
-  DEVICE_NATIVE_ENDIAN);
-pci_register_bar_simple(&d->pci, 0, 0x4000, 0, d->mmio_addr);
+memory_region_init_io(&d->mmio, &intel_hda_mmio_ops, d,
+  "intel-hda", 0x4000);
+pci_register_bar_region(&d->pci, 0, 0, &d->mmio);
 if (d->msi) {
 msi_init(&d->pci, 0x50, 1, true, false);
 }
@@ -1149,7 +1152,7 @@ static int intel_hda_exit(PCIDevice *pci)
 IntelHDAState *d = DO_UPCAST(IntelHDAState, pci, pci);
 
 msi_uninit(&d->pci);
-cpu_unregister_io_memory(d->mmio_addr);
+memory_region_destroy(&d->mmio);
 return 0;
 }
 
-- 
1.7.5.3




[Qemu-devel] [PATCH v2 24/38] ne2000: convert to memory API

2011-08-03 Thread Avi Kivity
Reviewed-by: Richard Henderson 
Signed-off-by: Avi Kivity 
---
 hw/ne2000-isa.c |   14 +++---
 hw/ne2000.c |   77 +-
 hw/ne2000.h |8 +
 3 files changed, 59 insertions(+), 40 deletions(-)

diff --git a/hw/ne2000-isa.c b/hw/ne2000-isa.c
index e41dbba..ce7b365 100644
--- a/hw/ne2000-isa.c
+++ b/hw/ne2000-isa.c
@@ -61,24 +61,18 @@ static const VMStateDescription vmstate_isa_ne2000 = {
 }
 };
 
+#include "exec-memory.h"
+
 static int isa_ne2000_initfn(ISADevice *dev)
 {
 ISANE2000State *isa = DO_UPCAST(ISANE2000State, dev, dev);
 NE2000State *s = &isa->ne2000;
 
-register_ioport_write(isa->iobase, 16, 1, ne2000_ioport_write, s);
-register_ioport_read(isa->iobase, 16, 1, ne2000_ioport_read, s);
+ne2000_setup_io(s, 0x20);
 isa_init_ioport_range(dev, isa->iobase, 16);
-
-register_ioport_write(isa->iobase + 0x10, 1, 1, ne2000_asic_ioport_write, 
s);
-register_ioport_read(isa->iobase + 0x10, 1, 1, ne2000_asic_ioport_read, s);
-register_ioport_write(isa->iobase + 0x10, 2, 2, ne2000_asic_ioport_write, 
s);
-register_ioport_read(isa->iobase + 0x10, 2, 2, ne2000_asic_ioport_read, s);
 isa_init_ioport_range(dev, isa->iobase + 0x10, 2);
-
-register_ioport_write(isa->iobase + 0x1f, 1, 1, ne2000_reset_ioport_write, 
s);
-register_ioport_read(isa->iobase + 0x1f, 1, 1, ne2000_reset_ioport_read, 
s);
 isa_init_ioport(dev, isa->iobase + 0x1f);
+memory_region_add_subregion(get_system_io(), isa->iobase, &s->io);
 
 isa_init_irq(dev, &s->irq, isa->isairq);
 
diff --git a/hw/ne2000.c b/hw/ne2000.c
index f8acaae..5b76acf 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -297,7 +297,7 @@ ssize_t ne2000_receive(VLANClientState *nc, const uint8_t 
*buf, size_t size_)
 return size_;
 }
 
-void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 {
 NE2000State *s = opaque;
 int offset, page, index;
@@ -394,7 +394,7 @@ void ne2000_ioport_write(void *opaque, uint32_t addr, 
uint32_t val)
 }
 }
 
-uint32_t ne2000_ioport_read(void *opaque, uint32_t addr)
+static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr)
 {
 NE2000State *s = opaque;
 int offset, page, ret;
@@ -544,7 +544,7 @@ static inline void ne2000_dma_update(NE2000State *s, int 
len)
 }
 }
 
-void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 {
 NE2000State *s = opaque;
 
@@ -564,7 +564,7 @@ void ne2000_asic_ioport_write(void *opaque, uint32_t addr, 
uint32_t val)
 }
 }
 
-uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr)
+static uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr)
 {
 NE2000State *s = opaque;
 int ret;
@@ -612,12 +612,12 @@ static uint32_t ne2000_asic_ioport_readl(void *opaque, 
uint32_t addr)
 return ret;
 }
 
-void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+static void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t 
val)
 {
 /* nothing to do (end of reset pulse) */
 }
 
-uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr)
+static uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr)
 {
 NE2000State *s = opaque;
 ne2000_reset(s);
@@ -676,27 +676,55 @@ static const VMStateDescription vmstate_pci_ne2000 = {
 }
 };
 
-/***/
-/* PCI NE2000 definitions */
+static uint64_t ne2000_read(void *opaque, target_phys_addr_t addr,
+unsigned size)
+{
+NE2000State *s = opaque;
 
-static void ne2000_map(PCIDevice *pci_dev, int region_num,
-   pcibus_t addr, pcibus_t size, int type)
+if (addr < 0x10 && size == 1) {
+return ne2000_ioport_read(s, addr);
+} else if (addr == 0x10) {
+if (size <= 2) {
+return ne2000_asic_ioport_read(s, addr);
+} else {
+return ne2000_asic_ioport_readl(s, addr);
+}
+} else if (addr == 0x1f && size == 1) {
+return ne2000_reset_ioport_read(s, addr);
+}
+return ((uint64_t)1 << (size * 8)) - 1;
+}
+
+static void ne2000_write(void *opaque, target_phys_addr_t addr,
+ uint64_t data, unsigned size)
 {
-PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
-NE2000State *s = &d->ne2000;
+NE2000State *s = opaque;
+
+if (addr < 0x10 && size == 1) {
+return ne2000_ioport_write(s, addr, data);
+} else if (addr == 0x10) {
+if (size <= 2) {
+return ne2000_asic_ioport_write(s, addr, data);
+} else {
+return ne2000_asic_ioport_writel(s, addr, data);
+}
+} else if (addr == 0x1f && size == 1) {
+return ne2000_reset_ioport_write(s, addr, data);
+}
+}
 
-register_ioport_write(addr, 16, 

[Qemu-devel] [PATCH v2 32/38] msix: convert to memory API

2011-08-03 Thread Avi Kivity
The msix table is defined as a subregion, to allow for a BAR that
mixes device specific regions with the msix table.

Reviewed-by: Richard Henderson 
Signed-off-by: Avi Kivity 
---
 hw/ivshmem.c|   11 +
 hw/msix.c   |   64 +++
 hw/msix.h   |6 +---
 hw/pci.h|2 +-
 hw/virtio-pci.c |   16 -
 hw/virtio-pci.h |1 +
 6 files changed, 42 insertions(+), 58 deletions(-)

diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index f80e7b6..bacba60 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -65,6 +65,7 @@ typedef struct IVShmemState {
  */
 MemoryRegion bar;
 MemoryRegion ivshmem;
+MemoryRegion msix_bar;
 uint64_t ivshmem_size; /* size of shared memory region */
 int shm_fd; /* shared memory file descriptor */
 
@@ -540,11 +541,11 @@ static void ivshmem_setup_msi(IVShmemState * s) {
 
 /* allocate the MSI-X vectors */
 
-if (!msix_init(&s->dev, s->vectors, 1, 0)) {
-pci_register_bar(&s->dev, 1,
- msix_bar_size(&s->dev),
- PCI_BASE_ADDRESS_SPACE_MEMORY,
- msix_mmio_map);
+memory_region_init(&s->msix_bar, "ivshmem-msix", 4096);
+if (!msix_init(&s->dev, s->vectors, &s->msix_bar, 1, 0)) {
+pci_register_bar_region(&s->dev, 1,
+PCI_BASE_ADDRESS_SPACE_MEMORY,
+&s->msix_bar);
 IVSHMEM_DPRINTF("msix initialized (%d vectors)\n", s->vectors);
 } else {
 IVSHMEM_DPRINTF("msix initialization failed\n");
diff --git a/hw/msix.c b/hw/msix.c
index e67e700..8536c3f 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -82,7 +82,8 @@ static int msix_add_config(struct PCIDevice *pdev, unsigned 
short nentries,
 return 0;
 }
 
-static uint32_t msix_mmio_readl(void *opaque, target_phys_addr_t addr)
+static uint64_t msix_mmio_read(void *opaque, target_phys_addr_t addr,
+   unsigned size)
 {
 PCIDevice *dev = opaque;
 unsigned int offset = addr & (MSIX_PAGE_SIZE - 1) & ~0x3;
@@ -91,12 +92,6 @@ static uint32_t msix_mmio_readl(void *opaque, 
target_phys_addr_t addr)
 return pci_get_long(page + offset);
 }
 
-static uint32_t msix_mmio_read_unallowed(void *opaque, target_phys_addr_t addr)
-{
-fprintf(stderr, "MSI-X: only dword read is allowed!\n");
-return 0;
-}
-
 static uint8_t msix_pending_mask(int vector)
 {
 return 1 << (vector % 8);
@@ -169,8 +164,8 @@ void msix_write_config(PCIDevice *dev, uint32_t addr,
 }
 }
 
-static void msix_mmio_writel(void *opaque, target_phys_addr_t addr,
- uint32_t val)
+static void msix_mmio_write(void *opaque, target_phys_addr_t addr,
+uint64_t val, unsigned size)
 {
 PCIDevice *dev = opaque;
 unsigned int offset = addr & (MSIX_PAGE_SIZE - 1) & ~0x3;
@@ -179,37 +174,25 @@ static void msix_mmio_writel(void *opaque, 
target_phys_addr_t addr,
 msix_handle_mask_update(dev, vector);
 }
 
-static void msix_mmio_write_unallowed(void *opaque, target_phys_addr_t addr,
-  uint32_t val)
-{
-fprintf(stderr, "MSI-X: only dword write is allowed!\n");
-}
-
-static CPUWriteMemoryFunc * const msix_mmio_write[] = {
-msix_mmio_write_unallowed, msix_mmio_write_unallowed, msix_mmio_writel
-};
-
-static CPUReadMemoryFunc * const msix_mmio_read[] = {
-msix_mmio_read_unallowed, msix_mmio_read_unallowed, msix_mmio_readl
+static const MemoryRegionOps msix_mmio_ops = {
+.read = msix_mmio_read,
+.write = msix_mmio_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.valid = {
+.min_access_size = 4,
+.max_access_size = 4,
+},
 };
 
-/* Should be called from device's map method. */
-void msix_mmio_map(PCIDevice *d, int region_num,
-   pcibus_t addr, pcibus_t size, int type)
+static void msix_mmio_setup(PCIDevice *d, MemoryRegion *bar)
 {
 uint8_t *config = d->config + d->msix_cap;
 uint32_t table = pci_get_long(config + PCI_MSIX_TABLE);
 uint32_t offset = table & ~(MSIX_PAGE_SIZE - 1);
 /* TODO: for assigned devices, we'll want to make it possible to map
  * pending bits separately in case they are in a separate bar. */
-int table_bir = table & PCI_MSIX_FLAGS_BIRMASK;
 
-if (table_bir != region_num)
-return;
-if (size <= offset)
-return;
-cpu_register_physical_memory(addr + offset, size - offset,
- d->msix_mmio_index);
+memory_region_add_subregion(bar, offset, &d->msix_mmio);
 }
 
 static void msix_mask_all(struct PCIDevice *dev, unsigned nentries)
@@ -225,6 +208,7 @@ static void msix_mask_all(struct PCIDevice *dev, unsigned 
nentries)
 /* Initialize the MSI-X structures. Note: if MSI-X is supported, BAR size is
  * modified, it should be retrieved with msix_bar_size. */
 int msix_init(struct PCIDevice *dev, unsigned short nentries,
+ 

[Qemu-devel] [PATCH v2 17/38] ide: convert to memory API

2011-08-03 Thread Avi Kivity
Reviewed-by: Richard Henderson 
Signed-off-by: Avi Kivity 
---
 hw/ide/cmd646.c |  208 +++
 hw/ide/pci.c|   25 ---
 hw/ide/pci.h|   19 -
 hw/ide/piix.c   |   64 +
 hw/ide/via.c|   65 +
 5 files changed, 261 insertions(+), 120 deletions(-)

diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index 56302b5..13e6f2f 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -44,35 +44,95 @@
 
 static void cmd646_update_irq(PCIIDEState *d);
 
-static void ide_map(PCIDevice *pci_dev, int region_num,
-pcibus_t addr, pcibus_t size, int type)
+static uint64_t cmd646_cmd_read(void *opaque, target_phys_addr_t addr,
+unsigned size)
 {
-PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev);
-IDEBus *bus;
-
-if (region_num <= 3) {
-bus = &d->bus[(region_num >> 1)];
-if (region_num & 1) {
-register_ioport_read(addr + 2, 1, 1, ide_status_read, bus);
-register_ioport_write(addr + 2, 1, 1, ide_cmd_write, bus);
+CMD646BAR *cmd646bar = opaque;
+
+if (addr != 2 || size != 1) {
+return ((uint64_t)1 << (size * 8)) - 1;
+}
+return ide_status_read(cmd646bar->bus, addr + 2);
+}
+
+static void cmd646_cmd_write(void *opaque, target_phys_addr_t addr,
+ uint64_t data, unsigned size)
+{
+CMD646BAR *cmd646bar = opaque;
+
+if (addr != 2 || size != 1) {
+return;
+}
+ide_cmd_write(cmd646bar->bus, addr + 2, data);
+}
+
+static MemoryRegionOps cmd646_cmd_ops = {
+.read = cmd646_cmd_read,
+.write = cmd646_cmd_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static uint64_t cmd646_data_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
+{
+CMD646BAR *cmd646bar = opaque;
+
+if (size == 1) {
+return ide_ioport_read(cmd646bar->bus, addr);
+} else if (addr == 0) {
+if (size == 2) {
+return ide_data_readw(cmd646bar->bus, addr);
 } else {
-register_ioport_write(addr, 8, 1, ide_ioport_write, bus);
-register_ioport_read(addr, 8, 1, ide_ioport_read, bus);
-
-/* data ports */
-register_ioport_write(addr, 2, 2, ide_data_writew, bus);
-register_ioport_read(addr, 2, 2, ide_data_readw, bus);
-register_ioport_write(addr, 4, 4, ide_data_writel, bus);
-register_ioport_read(addr, 4, 4, ide_data_readl, bus);
+return ide_data_readl(cmd646bar->bus, addr);
 }
 }
+return ((uint64_t)1 << (size * 8)) - 1;
 }
 
-static uint32_t bmdma_readb_common(PCIIDEState *pci_dev, BMDMAState *bm,
-   uint32_t addr)
+static void cmd646_data_write(void *opaque, target_phys_addr_t addr,
+ uint64_t data, unsigned size)
 {
+CMD646BAR *cmd646bar = opaque;
+
+if (size == 1) {
+return ide_ioport_write(cmd646bar->bus, addr, data);
+} else if (addr == 0) {
+if (size == 2) {
+return ide_data_writew(cmd646bar->bus, addr, data);
+} else {
+return ide_data_writel(cmd646bar->bus, addr, data);
+}
+}
+}
+
+static MemoryRegionOps cmd646_data_ops = {
+.read = cmd646_data_read,
+.write = cmd646_data_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void setup_cmd646_bar(PCIIDEState *d, int bus_num)
+{
+IDEBus *bus = &d->bus[bus_num];
+CMD646BAR *bar = &d->cmd646_bar[bus_num];
+
+bar->bus = bus;
+bar->pci_dev = d;
+memory_region_init_io(&bar->cmd, &cmd646_cmd_ops, bar, "cmd646-cmd", 4);
+memory_region_init_io(&bar->data, &cmd646_data_ops, bar, "cmd646-data", 8);
+}
+
+static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr,
+   unsigned size)
+{
+BMDMAState *bm = opaque;
+PCIIDEState *pci_dev = bm->pci_dev;
 uint32_t val;
 
+if (size != 1) {
+return ((uint64_t)1 << (size * 8)) - 1;
+}
+
 switch(addr & 3) {
 case 0:
 val = bm->cmd;
@@ -100,31 +160,22 @@ static uint32_t bmdma_readb_common(PCIIDEState *pci_dev, 
BMDMAState *bm,
 return val;
 }
 
-static uint32_t bmdma_readb_0(void *opaque, uint32_t addr)
+static void bmdma_write(void *opaque, target_phys_addr_t addr,
+uint64_t val, unsigned size)
 {
-PCIIDEState *pci_dev = opaque;
-BMDMAState *bm = &pci_dev->bmdma[0];
-
-return bmdma_readb_common(pci_dev, bm, addr);
-}
+BMDMAState *bm = opaque;
+PCIIDEState *pci_dev = bm->pci_dev;
 
-static uint32_t bmdma_readb_1(void *opaque, uint32_t addr)
-{
-PCIIDEState *pci_dev = opaque;
-BMDMAState *bm = &pci_dev->bmdma[1];
-
-return bmdma_readb_common(pci_dev, bm, addr);
-}
+if (size != 1) {
+return;
+}
 
-static void bmdma_writeb_common(PCIIDEState *pci_dev, BMDMAState *bm,
-uint

[Qemu-devel] [PATCH v2 27/38] isa-mmio: concert to memory API

2011-08-03 Thread Avi Kivity
Reviewed-by: Richard Henderson 
Signed-off-by: Avi Kivity 
---
 hw/isa.h  |2 ++
 hw/isa_mmio.c |   30 +++---
 2 files changed, 17 insertions(+), 15 deletions(-)

diff --git a/hw/isa.h b/hw/isa.h
index d2b6126..f1f2181 100644
--- a/hw/isa.h
+++ b/hw/isa.h
@@ -4,6 +4,7 @@
 /* ISA bus */
 
 #include "ioport.h"
+#include "memory.h"
 #include "qdev.h"
 
 typedef struct ISABus ISABus;
@@ -37,6 +38,7 @@ ISADevice *isa_create_simple(const char *name);
 
 extern target_phys_addr_t isa_mem_base;
 
+void isa_mmio_setup(MemoryRegion *mr, target_phys_addr_t size);
 void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size);
 
 /* dma.c */
diff --git a/hw/isa_mmio.c b/hw/isa_mmio.c
index ca957fb..600225f 100644
--- a/hw/isa_mmio.c
+++ b/hw/isa_mmio.c
@@ -58,25 +58,25 @@ static uint32_t isa_mmio_readl(void *opaque, 
target_phys_addr_t addr)
 return cpu_inl(addr & IOPORTS_MASK);
 }
 
-static CPUWriteMemoryFunc * const isa_mmio_write[] = {
-&isa_mmio_writeb,
-&isa_mmio_writew,
-&isa_mmio_writel,
+static const MemoryRegionOps isa_mmio_ops = {
+.old_mmio = {
+.write = { isa_mmio_writeb, isa_mmio_writew, isa_mmio_writel },
+.read = { isa_mmio_readb, isa_mmio_readw, isa_mmio_readl, },
+},
+.endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static CPUReadMemoryFunc * const isa_mmio_read[] = {
-&isa_mmio_readb,
-&isa_mmio_readw,
-&isa_mmio_readl,
-};
+void isa_mmio_setup(MemoryRegion *mr, target_phys_addr_t size)
+{
+memory_region_init_io(mr, &isa_mmio_ops, NULL, "isa-mmio", size);
+}
+
+#include "exec-memory.h"
 
 void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size)
 {
-int isa_mmio_iomemtype;
+MemoryRegion *mr = qemu_malloc(sizeof(*mr));
 
-isa_mmio_iomemtype = cpu_register_io_memory(isa_mmio_read,
-isa_mmio_write,
-NULL,
-DEVICE_LITTLE_ENDIAN);
-cpu_register_physical_memory(base, size, isa_mmio_iomemtype);
+isa_mmio_setup(mr, size);
+memory_region_add_subregion(get_system_memory(), base, mr);
 }
-- 
1.7.5.3




Re: [Qemu-devel] [PATCH 44/55] spitz tosa: Simplify "drive is suitable for microdrive" test

2011-08-03 Thread andrzej zaborowski
On 3 August 2011 10:12, Markus Armbruster  wrote:
> Peter Maydell  writes:
>
>> On 1 August 2011 13:33, Markus Armbruster  wrote:
>>> andrzej zaborowski  writes:
 On 20 July 2011 18:24, Markus Armbruster  wrote:
> We try the drive defined with -drive if=ide,index=0 (or equivalent
> sugar).  We use it only if (dinfo && bdrv_is_inserted(dinfo->bdrv) &&
> !bdrv_is_removable(dinfo->bdrv)).  This is a convoluted way to test
> for "drive media can't be removed".
>
> The only way to create such a drive with -drive if=ide is media=cdrom.
> And that sets dinfo->media_cd, so just test that.

 This is a less generic test and more prone to be broken inadvertently,
 so it seems like a step back.  What's the argument against the
 convoluted and explicit test?
>>>
>>> My motivation for changing it was to reduce the uses of BlockDriverState
>>> member removable prior to nuking it from orbit [PATCH 45/55].
>>>
>>> I consider my change an improvement, because I find "dinfo->media_cd"
>>> clearer than
>>> "bdrv_is_inserted(dinfo->bdrv) && !bdrv_is_removable(dinfo->bdrv)".
>>
>> This seems like an argument for providing a bdrv_supports_eject()
>> or whatever we're actually trying to test for here. I kind of felt
>> the same way as Andrzej when I saw this patch going past but it
>> got lost in my mail folder...
>
> Well, what are you trying to test for here?
>
> Let's start with figuring out what we actually test for right now (may
> not be what you *want* to test for, but it's a start).  The test code is
> "bdrv_is_inserted(bs) && !bdrv_is_removable(bs)".
>
> bdrv_is_removable() is a confused mess.  It is true when an ide-cd,
> scsi-cd or floppy qdev is attached, or when the BlockDriverState was
> created with -drive if={floppy,sd} or -drive
> if={ide,scsi,xen,none},media=cdrom, except when an ide-hd, scsi-hd,
> scsi-generic or virtio-blk qdev is attached.
>
> Since we're about to attach a device here, no other device can be
> attached, and the mess simplifies into "when the BlockDriverState was
> created with -drive if={floppy,sd} or -drive
> if={ide,scsi,xen,none},media=cdrom".
>
> Since we're getting IF_IDE, it further simplifies into "when the
> BlockDriverState was created with -drive if=ide,media=cdrom".

What's wrong with that again?  All sounds sensible to me.

> Which is
> what my patch tests.

It's like if you changed the named constants/#defines in a project for
their preprocessed values... Behaviour is preserved but it makes worse
code, and its easier to break too, when someone updates the value of
some constant.

>
> The bdrv_is_inserted() part is actually redundant, because it can only
> be false if bdrv_is_removable() is true: the only way to create an IDE
> drive empty is with media=cdrom (makes bdrv_is_removable() true), and
> media is ejectable only when bdrv_is_removable() is true.
>
> Therefore, my patch preserves behavior.
>
>
> Testing for "block driver supports eject" is something else entirely.
> Block drivers "host_cdrom" and "host_floppy" implement method
> bdrv_eject()[*].  Is that what you want?

No, from your description of ejectable it looks like we want to check
if the device supports the monitor command "eject", although
additionally testing for "block driver supports eject" may make sense.

Cheers



Re: [Qemu-devel] [PATCH] Avoid allocating TCG resources in non-TCG mode

2011-08-03 Thread Anthony PERARD
On Tue, Aug 2, 2011 at 15:10, Jan Kiszka  wrote:
> Do not allocate TCG-only resources like the translation buffer when
> running over KVM or XEN. Saves a "few" bytes in the qemu address space
> and is also conceptually cleaner.
>
> Signed-off-by: Jan Kiszka 
> ---
>
> Note: Only tested on x86.

This patch works fine with Xen and looks good.

Thanks,

-- 
Anthony PERARD



Re: [Qemu-devel] qemu-kvm aborts - vhost_dev_unassign_memory: Assertion `to >= 0' failed.

2011-08-03 Thread Michael S. Tsirkin
On Wed, Aug 03, 2011 at 02:48:05PM +0300, Avi Kivity wrote:
> On 08/01/2011 08:44 PM, David Ahern wrote:
> >qemu-kvm.git as of:
> >
> >commit dacdc4b10bafbb21120e1c24a9665444768ef999
> >Merge: 7b69d4f 0af4922
> >Author: Avi Kivity
> >Date:   Sun Jul 31 11:42:26 2011 +0300
> >
> > Merge branch 'upstream-merge' into next
> >
> >is aborting with the error:
> >
> >qemu-kvm: qemu-kvm.git/hw/vhost.c:123: vhost_dev_unassign_memory:
> >Assertion `to>= 0' failed.
> >Aborted
> >
> 
> It's a bug in vhost:
> 
> /* Assign/unassign. Keep an unsorted array of non-overlapping
>  * memory regions in dev->mem. */
> static void vhost_dev_unassign_memory(struct vhost_dev *dev,
>   uint64_t start_addr,
>   uint64_t size)
> {
> int from, to, n = dev->mem->nregions;
> /* Track overlapping/split regions for sanity checking. */
> int overlap_start = 0, overlap_end = 0, overlap_middle = 0, split = 0;
> 
> for (from = 0, to = 0; from < n; ++from, ++to) {
> struct vhost_memory_region *reg = dev->mem->regions + to;
> uint64_t reglast;
> uint64_t memlast;
> uint64_t change;
> 
> /* clone old region */
> if (to != from) {
> memcpy(reg, dev->mem->regions + from, sizeof *reg);
> }
> 
> /* No overlap is simple */
> if (!ranges_overlap(reg->guest_phys_addr, reg->memory_size,
> start_addr, size)) {
> continue;
> }
> 
> /* Split only happens if supplied region
>  * is in the middle of an existing one. Thus it can not
>  * overlap with any other existing region. */
> assert(!split);
> 
> reglast = range_get_last(reg->guest_phys_addr, reg->memory_size);
> memlast = range_get_last(start_addr, size);
> 
> /* Remove whole region */
> if (start_addr <= reg->guest_phys_addr && memlast >= reglast) {
> --dev->mem->nregions;
> --to;
> assert(to >= 0);
> ++overlap_middle;
> continue;
> }
> 
> 
> We're removing the first region, and 'to' goes negative.  Michael?

Yes, that assert is wrong.

--->
Subject: vhost: remove an incorrect assert

The 'to' can go negative when the first region gets removed
(it gets incremented by to 0 immediately afterward), which
makes the assertion fail. Nothing breaks if
to < 0 here so just remove the assert.

Signed-off-by: Michael S. Tsirkin 



diff --git a/hw/vhost.c b/hw/vhost.c
index c3d8821..19e7255 100644
--- a/hw/vhost.c
+++ b/hw/vhost.c
@@ -120,7 +120,6 @@ static void vhost_dev_unassign_memory(struct vhost_dev *dev,
 if (start_addr <= reg->guest_phys_addr && memlast >= reglast) {
 --dev->mem->nregions;
 --to;
-assert(to >= 0);
 ++overlap_middle;
 continue;
 }




[Qemu-devel] Stellaris RCC2 Support

2011-08-03 Thread Engin AYDOGAN
Based on the work http://patchwork.ozlabs.org/patch/31469/ , here's the
patch for HEAD.

>From f91c8fb57b599b59f603b2fd9c81c6f9d7e3aad6 Mon Sep 17 00:00:00 2001
From: Engin AYDOGAN 
Date: Wed, 3 Aug 2011 00:36:47 -0700
Subject: [PATCH] Stellaris RCC2 support


Signed-off-by: Engin AYDOGAN 
---
 hw/stellaris.c |   70
+--
 1 files changed, 67 insertions(+), 3 deletions(-)

diff --git a/hw/stellaris.c b/hw/stellaris.c
index a280930..d886a03 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -332,6 +332,7 @@ typedef struct {
 uint32_t int_mask;
 uint32_t resc;
 uint32_t rcc;
+uint32_t rcc2;
 uint32_t rcgc[3];
 uint32_t scgc[3];
 uint32_t dcgc[3];
@@ -386,6 +387,36 @@ static uint32_t pllcfg_fury[16] = {
 0xb11c /* 8.192 Mhz */
 };

+#define DID0_VER_MASK0x7000
+#define DID0_VER_0   0x
+#define DID0_VER_1   0x1000
+
+#define DID0_CLASS_MASK  0x00FF
+#define DID0_CLASS_SANDSTORM 0x
+#define DID0_CLASS_FURY  0x0001
+
+static bool ssys_is_sandstorm(ssys_state *s)
+{
+uint32_t did0 = s->board->did0;
+
+switch (did0 & DID0_VER_MASK) {
+case DID0_VER_0:
+return 1;
+case DID0_VER_1:
+return ((did0 & DID0_CLASS_MASK) == DID0_CLASS_SANDSTORM);
+default:
+return 0;
+}
+}
+
+static bool ssys_is_fury(ssys_state *s)
+{
+uint32_t did0 = s->board->did0;
+
+return (((did0 & DID0_VER_MASK) == DID0_VER_1)
+   && ((did0 & DID0_CLASS_MASK) == DID0_CLASS_FURY));
+}
+
 static uint32_t ssys_read(void *opaque, target_phys_addr_t offset)
 {
 ssys_state *s = (ssys_state *)opaque;
@@ -429,12 +460,14 @@ static uint32_t ssys_read(void *opaque,
target_phys_addr_t offset)
 {
 int xtal;
 xtal = (s->rcc >> 6) & 0xf;
-if (s->board->did0 & (1 << 16)) {
+if (ssys_is_fury(s)) {
 return pllcfg_fury[xtal];
 } else {
 return pllcfg_sandstorm[xtal];
 }
 }
+case 0x070: /* RCC2 */
+return s->rcc2;
 case 0x100: /* RCGC0 */
 return s->rcgc[0];
 case 0x104: /* RCGC1 */
@@ -467,9 +500,21 @@ static uint32_t ssys_read(void *opaque,
target_phys_addr_t offset)
 }
 }

+static bool ssys_use_rcc2(ssys_state *s)
+{
+return (s->rcc2 >> 31) & 0x1;
+}
+
+/*
+ * Caculate the sys. clock period in ms.
+ */
 static void ssys_calculate_system_clock(ssys_state *s)
 {
-system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
+if (ssys_use_rcc2(s)) {
+system_clock_scale = 5 * (((s->rcc2 >> 23) & 0x3f) + 1);
+} else {
+system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
+}
 }

 static void ssys_write(void *opaque, target_phys_addr_t offset, uint32_t
value)
@@ -505,6 +550,18 @@ static void ssys_write(void *opaque, target_phys_addr_t
offset, uint32_t value)
 s->rcc = value;
 ssys_calculate_system_clock(s);
 break;
+case 0x070: /* RCC2 */
+if (ssys_is_sandstorm(s)) {
+break;
+}
+
+if ((s->rcc2 & (1 << 13)) != 0 && (value & (1 << 13)) == 0) {
+/* PLL enable.  */
+s->int_status |= (1 << 6);
+}
+s->rcc2 = value;
+ssys_calculate_system_clock(s);
+break;
 case 0x100: /* RCGC0 */
 s->rcgc[0] = value;
 break;
@@ -562,6 +619,12 @@ static void ssys_reset(void *opaque)

 s->pborctl = 0x7ffd;
 s->rcc = 0x078e3ac0;
+
+if (ssys_is_sandstorm(s)) {
+s->rcc2 = 0;
+} else {
+s->rcc2 = 0x07802810;
+}
 s->rcgc[0] = 1;
 s->scgc[0] = 1;
 s->dcgc[0] = 1;
@@ -578,7 +641,7 @@ static int stellaris_sys_post_load(void *opaque, int
version_id)

 static const VMStateDescription vmstate_stellaris_sys = {
 .name = "stellaris_sys",
-.version_id = 1,
+.version_id = 2,
 .minimum_version_id = 1,
 .minimum_version_id_old = 1,
 .post_load = stellaris_sys_post_load,
@@ -589,6 +652,7 @@ static const VMStateDescription vmstate_stellaris_sys =
{
 VMSTATE_UINT32(int_status, ssys_state),
 VMSTATE_UINT32(resc, ssys_state),
 VMSTATE_UINT32(rcc, ssys_state),
+VMSTATE_UINT32_V(rcc2, ssys_state, 2),
 VMSTATE_UINT32_ARRAY(rcgc, ssys_state, 3),
 VMSTATE_UINT32_ARRAY(scgc, ssys_state, 3),
 VMSTATE_UINT32_ARRAY(dcgc, ssys_state, 3),
-- 
1.7.4.1


0001-Stellaris-RCC2-support.patch
Description: Binary data


[Qemu-devel] [PATCH] monitor: HMP: fix consecutive integer expression parsing

2011-08-03 Thread Alon Levy
Currently a command that takes two consecutive integer operations, like
client_migrate_info, will be incorrectly parsed by the human monitor if
the second expression begins with a minus ('-') or plus ('+') sign:

client_migrate_info
client_migrate_info spice localhost 5900 -1
=> port = 5899 = 5900 - 1
   tls-port = -1
But expected by the user to be:
   port = 5900
   tls-port = -1

The fix is that for any required integer (ilM) expression followed by another
integer expression (ilM) the first expression will be parsed by expr_unary
instead of expr_sum. So you can still use arithmetic, but you have to enclose
it in parenthesis:

Command line | Old parsed result | With patch result
(1+1) 2  | 2, 2  | 2, 2
1 -1 | 0, -1 | 1, -1
The rest are bizarre but not any worse then before
1+2+3| 6, 5  | 1, 5
(1+2)+3  | 3, 3  | 3, 3

Signed-off-by: Alon Levy 
---
 monitor.c |   27 ---
 1 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/monitor.c b/monitor.c
index 1b8ba2c..45e2d6c 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3889,7 +3889,7 @@ static int64_t expr_sum(Monitor *mon)
 return val;
 }
 
-static int get_expr(Monitor *mon, int64_t *pval, const char **pp)
+static int get_expr(Monitor *mon, int64_t *pval, const char **pp, int unary)
 {
 pch = *pp;
 if (setjmp(expr_env)) {
@@ -3898,7 +3898,11 @@ static int get_expr(Monitor *mon, int64_t *pval, const 
char **pp)
 }
 while (qemu_isspace(*pch))
 pch++;
-*pval = expr_sum(mon);
+if (unary) {
+*pval = expr_unary(mon);
+} else {
+*pval = expr_sum(mon);
+}
 *pp = pch;
 return 0;
 }
@@ -4267,6 +4271,9 @@ static const mon_cmd_t *monitor_parse_command(Monitor 
*mon,
 case 'M':
 {
 int64_t val;
+int unary = 0;
+char *next_key;
+char *next;
 
 while (qemu_isspace(*p))
 p++;
@@ -4288,7 +4295,21 @@ static const mon_cmd_t *monitor_parse_command(Monitor 
*mon,
 }
 typestr++;
 }
-if (get_expr(mon, &val, &p))
+next = key_get_info(typestr, &next_key);
+qemu_free(next_key);
+if (*next == 'i' || *next == 'l' || *next == 'M') {
+/* If a command has two consecutive ii parameters the first
+ * get_expr will also parse the second parameter if it
+ * starts with a - or +. To avoid this only parse unary in
+ * this case, i.e.:
+ * client_migrate_info spice localhost 1 -1
+ *  => 1, -1
+ * client_migrate_info spice localhost (1+3) -1
+ *  => 4, -1
+ */
+unary = 1;
+}
+if (get_expr(mon, &val, &p, unary))
 goto fail;
 /* Check if 'i' is greater than 32-bit */
 if ((c == 'i') && ((val >> 32) & 0x)) {
-- 
1.7.6




[Qemu-devel] [PATCH v2 07/38] vga: simplify vga window mmio access functions

2011-08-03 Thread Avi Kivity
Make use of the memory API's ability to satisfy multi-byte accesses via
multiple single-byte accesses.

We have to keep vga_mem_{read,write}b() since they're used by cirrus.

Reviewed-by: Richard Henderson 
Signed-off-by: Avi Kivity 
---
 hw/cirrus_vga.c |4 +-
 hw/vga.c|   56 +++---
 hw/vga_int.h|4 +-
 3 files changed, 12 insertions(+), 52 deletions(-)

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 92696d9..3db15bf 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -1965,7 +1965,7 @@ static uint64_t cirrus_vga_mem_read(void *opaque,
 uint32_t val;
 
 if ((s->vga.sr[0x07] & 0x01) == 0) {
-   return vga_mem_readb(s, addr);
+return vga_mem_readb(&s->vga, addr);
 }
 
 if (addr < 0x1) {
@@ -2010,7 +2010,7 @@ static void cirrus_vga_mem_write(void *opaque,
 unsigned mode;
 
 if ((s->vga.sr[0x07] & 0x01) == 0) {
-   vga_mem_writeb(s, addr, mem_value);
+vga_mem_writeb(&s->vga, addr, mem_value);
 return;
 }
 
diff --git a/hw/vga.c b/hw/vga.c
index cdd8255..f5dd519 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -707,9 +707,8 @@ static void vbe_ioport_write_data(void *opaque, uint32_t 
addr, uint32_t val)
 #endif
 
 /* called for accesses between 0xa and 0xc */
-uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr)
+uint32_t vga_mem_readb(VGACommonState *s, target_phys_addr_t addr)
 {
-VGACommonState *s = opaque;
 int memory_map_mode, plane;
 uint32_t ret;
 
@@ -763,28 +762,9 @@ uint32_t vga_mem_readb(void *opaque, target_phys_addr_t 
addr)
 return ret;
 }
 
-static uint32_t vga_mem_readw(void *opaque, target_phys_addr_t addr)
-{
-uint32_t v;
-v = vga_mem_readb(opaque, addr);
-v |= vga_mem_readb(opaque, addr + 1) << 8;
-return v;
-}
-
-static uint32_t vga_mem_readl(void *opaque, target_phys_addr_t addr)
-{
-uint32_t v;
-v = vga_mem_readb(opaque, addr);
-v |= vga_mem_readb(opaque, addr + 1) << 8;
-v |= vga_mem_readb(opaque, addr + 2) << 16;
-v |= vga_mem_readb(opaque, addr + 3) << 24;
-return v;
-}
-
 /* called for accesses between 0xa and 0xc */
-void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+void vga_mem_writeb(VGACommonState *s, target_phys_addr_t addr, uint32_t val)
 {
-VGACommonState *s = opaque;
 int memory_map_mode, plane, write_mode, b, func_select, mask;
 uint32_t write_mask, bit_mask, set_mask;
 
@@ -916,20 +896,6 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, 
uint32_t val)
 }
 }
 
-static void vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-vga_mem_writeb(opaque, addr, val & 0xff);
-vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-}
-
-static void vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-vga_mem_writeb(opaque, addr, val & 0xff);
-vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff);
-vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-}
-
 typedef void vga_draw_glyph8_func(uint8_t *d, int linesize,
  const uint8_t *font_ptr, int h,
  uint32_t fgcol, uint32_t bgcol);
@@ -2104,12 +2070,7 @@ static uint64_t vga_mem_read(void *opaque, 
target_phys_addr_t addr,
 {
 VGACommonState *s = opaque;
 
-switch (size) {
-case 1: return vga_mem_readb(s, addr);
-case 2: return vga_mem_readw(s, addr);
-case 4: return vga_mem_readl(s, addr);
-default: abort();
-}
+return vga_mem_readb(s, addr);
 }
 
 static void vga_mem_write(void *opaque, target_phys_addr_t addr,
@@ -2117,18 +2078,17 @@ static void vga_mem_write(void *opaque, 
target_phys_addr_t addr,
 {
 VGACommonState *s = opaque;
 
-switch (size) {
-case 1: return vga_mem_writeb(s, addr, data);
-case 2: return vga_mem_writew(s, addr, data);
-case 4: return vga_mem_writel(s, addr, data);
-default: abort();
-}
+return vga_mem_writeb(s, addr, data);
 }
 
 const MemoryRegionOps vga_mem_ops = {
 .read = vga_mem_read,
 .write = vga_mem_write,
 .endianness = DEVICE_LITTLE_ENDIAN,
+.impl = {
+.min_access_size = 1,
+.max_access_size = 1,
+},
 };
 
 static int vga_common_post_load(void *opaque, int version_id)
diff --git a/hw/vga_int.h b/hw/vga_int.h
index 4592d2c..100d98c 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -198,8 +198,8 @@ void vga_dirty_log_restart(VGACommonState *s);
 extern const VMStateDescription vmstate_vga_common;
 uint32_t vga_ioport_read(void *opaque, uint32_t addr);
 void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val);
-uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr);
-void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val);
+uint32_t vga_mem_readb(VGACommonState *s, target_phys_addr_t addr);
+void vga_mem_writeb(VGACommonState *s, target_phys_addr_t addr

Re: [Qemu-devel] [SeaBIOS] SeaBIOS error with Juniper FreeBSD kernel

2011-08-03 Thread Bjørn Mork
"Kevin O'Connor"  writes:
> On Tue, Aug 02, 2011 at 11:33:09AM +0200, Bjørn Mork wrote:
>> "Kevin O'Connor"  writes:
>> > Also, it's possible the code could try to use the f-segment if there
>> > are less than say 16 cpus and use high memory when more cpus are
>> > present.
>> 
>> How about a variant over the last suggestion: Don't actually care bout
>> the number of CPUs, but just fall back to malloc_high if malloc_fseg
>> fails?
>
> This could make testing painful - small changes in the code could
> cause a different table layout that is OS visible.  I'd prefer a more
> strict cutoff.  Though, I suppose the cutoff could be by the table
> size itself instead of by number of CPUs.

This is of course your call to make...

But I must admit that I fail to see the advantage.  I agree that having
the table moved around depending on some variable is a problem.  Which
variable doesn't really matter. At least I don't see a fixed cutoff size
as any more predictable than a f-segment allocation failure, given that
I have no clue as to what SMBIOS table size is to be expected.  Maybe go
for the number of CPUs then.  But what if additional data is added to
the table, making f-segment allocation fail?  Then you will end up with
three different results depending on small changes instead of two:

 1) nCPU <= 16 and f-segment allocation OK: SMBIOS in f-segment
 2) nCPU > 16: SMBIOS in high mem
 3) nCPU <= 16 and f-segment allocation failed: no SMBIOS table

I don't think that makes testing any less painful...

Anyway, I would appreciate if some solution was found which allowed
JUNOS to boot with an unmodified SeaBIOS with SMBIOS enabled, as long as
the number of CPUs is limited.


Bjørn



[Qemu-devel] [PATCH v2 22/38] lsi53c895a: convert to memory API

2011-08-03 Thread Avi Kivity
An optimization that fast-pathed DMA reads from the SCRIPTS memory
was removed int the process.  Likely it breaks with iommus anyway.

Reviewed-by: Richard Henderson 
Signed-off-by: Avi Kivity 
---
 hw/lsi53c895a.c |  258 ---
 1 files changed, 56 insertions(+), 202 deletions(-)

diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index e9904c4..0ab8c78 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -185,9 +185,9 @@ typedef struct lsi_request {
 
 typedef struct {
 PCIDevice dev;
-int mmio_io_addr;
-int ram_io_addr;
-uint32_t script_ram_base;
+MemoryRegion mmio_io;
+MemoryRegion ram_io;
+MemoryRegion io_io;
 
 int carry; /* ??? Should this be an a visible register somewhere?  */
 int status;
@@ -391,10 +391,9 @@ static inline uint32_t read_dword(LSIState *s, uint32_t 
addr)
 {
 uint32_t buf;
 
-/* Optimize reading from SCRIPTS RAM.  */
-if ((addr & 0xe000) == s->script_ram_base) {
-return s->script_ram[(addr & 0x1fff) >> 2];
-}
+/* XXX: an optimization here used to fast-path the read from scripts
+ * memory.  But that bypasses any iommu.
+ */
 cpu_physical_memory_read(addr, (uint8_t *)&buf, 4);
 return cpu_to_le32(buf);
 }
@@ -1899,232 +1898,90 @@ static void lsi_reg_writeb(LSIState *s, int offset, 
uint8_t val)
 #undef CASE_SET_REG32
 }
 
-static void lsi_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t 
val)
+static void lsi_mmio_write(void *opaque, target_phys_addr_t addr,
+   uint64_t val, unsigned size)
 {
 LSIState *s = opaque;
 
 lsi_reg_writeb(s, addr & 0xff, val);
 }
 
-static void lsi_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t 
val)
-{
-LSIState *s = opaque;
-
-addr &= 0xff;
-lsi_reg_writeb(s, addr, val & 0xff);
-lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
-}
-
-static void lsi_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t 
val)
-{
-LSIState *s = opaque;
-
-addr &= 0xff;
-lsi_reg_writeb(s, addr, val & 0xff);
-lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
-lsi_reg_writeb(s, addr + 2, (val >> 16) & 0xff);
-lsi_reg_writeb(s, addr + 3, (val >> 24) & 0xff);
-}
-
-static uint32_t lsi_mmio_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t lsi_mmio_read(void *opaque, target_phys_addr_t addr,
+  unsigned size)
 {
 LSIState *s = opaque;
 
 return lsi_reg_readb(s, addr & 0xff);
 }
 
-static uint32_t lsi_mmio_readw(void *opaque, target_phys_addr_t addr)
-{
-LSIState *s = opaque;
-uint32_t val;
-
-addr &= 0xff;
-val = lsi_reg_readb(s, addr);
-val |= lsi_reg_readb(s, addr + 1) << 8;
-return val;
-}
-
-static uint32_t lsi_mmio_readl(void *opaque, target_phys_addr_t addr)
-{
-LSIState *s = opaque;
-uint32_t val;
-addr &= 0xff;
-val = lsi_reg_readb(s, addr);
-val |= lsi_reg_readb(s, addr + 1) << 8;
-val |= lsi_reg_readb(s, addr + 2) << 16;
-val |= lsi_reg_readb(s, addr + 3) << 24;
-return val;
-}
-
-static CPUReadMemoryFunc * const lsi_mmio_readfn[3] = {
-lsi_mmio_readb,
-lsi_mmio_readw,
-lsi_mmio_readl,
-};
-
-static CPUWriteMemoryFunc * const lsi_mmio_writefn[3] = {
-lsi_mmio_writeb,
-lsi_mmio_writew,
-lsi_mmio_writel,
+static const MemoryRegionOps lsi_mmio_ops = {
+.read = lsi_mmio_read,
+.write = lsi_mmio_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.impl = {
+.min_access_size = 1,
+.max_access_size = 1,
+},
 };
 
-static void lsi_ram_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+static void lsi_ram_write(void *opaque, target_phys_addr_t addr,
+  uint64_t val, unsigned size)
 {
 LSIState *s = opaque;
 uint32_t newval;
+uint32_t mask;
 int shift;
 
-addr &= 0x1fff;
 newval = s->script_ram[addr >> 2];
 shift = (addr & 3) * 8;
-newval &= ~(0xff << shift);
+mask = ((uint64_t)1 << (size * 8)) - 1;
+newval &= ~(mask << shift);
 newval |= val << shift;
 s->script_ram[addr >> 2] = newval;
 }
 
-static void lsi_ram_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-LSIState *s = opaque;
-uint32_t newval;
-
-addr &= 0x1fff;
-newval = s->script_ram[addr >> 2];
-if (addr & 2) {
-newval = (newval & 0x) | (val << 16);
-} else {
-newval = (newval & 0x) | val;
-}
-s->script_ram[addr >> 2] = newval;
-}
-
-
-static void lsi_ram_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-LSIState *s = opaque;
-
-addr &= 0x1fff;
-s->script_ram[addr >> 2] = val;
-}
-
-static uint32_t lsi_ram_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t lsi_ram_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
 {
 LSIState *s = opaque;
 uint32_t val;
+uint32_t mask;
 
-addr &= 0x1fff;
 v

[Qemu-devel] [PATCH v2 25/38] pcnet: convert to memory API

2011-08-03 Thread Avi Kivity
Also related chips.

Reviewed-by: Richard Henderson 
Signed-off-by: Avi Kivity 
---
 hw/lance.c |   31 ++-
 hw/pcnet-pci.c |   74 +--
 hw/pcnet.h |4 ++-
 3 files changed, 61 insertions(+), 48 deletions(-)

diff --git a/hw/lance.c b/hw/lance.c
index ddb1cbb..8e20360 100644
--- a/hw/lance.c
+++ b/hw/lance.c
@@ -55,8 +55,8 @@ static void parent_lance_reset(void *opaque, int irq, int 
level)
 pcnet_h_reset(&d->state);
 }
 
-static void lance_mem_writew(void *opaque, target_phys_addr_t addr,
- uint32_t val)
+static void lance_mem_write(void *opaque, target_phys_addr_t addr,
+uint64_t val, unsigned size)
 {
 SysBusPCNetState *d = opaque;
 
@@ -64,7 +64,8 @@ static void lance_mem_writew(void *opaque, target_phys_addr_t 
addr,
 pcnet_ioport_writew(&d->state, addr, val & 0x);
 }
 
-static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
+static uint64_t lance_mem_read(void *opaque, target_phys_addr_t addr,
+   unsigned size)
 {
 SysBusPCNetState *d = opaque;
 uint32_t val;
@@ -74,16 +75,14 @@ static uint32_t lance_mem_readw(void *opaque, 
target_phys_addr_t addr)
 return val & 0x;
 }
 
-static CPUReadMemoryFunc * const lance_mem_read[3] = {
-NULL,
-lance_mem_readw,
-NULL,
-};
-
-static CPUWriteMemoryFunc * const lance_mem_write[3] = {
-NULL,
-lance_mem_writew,
-NULL,
+static const MemoryRegionOps lance_mem_ops = {
+.read = lance_mem_read,
+.write = lance_mem_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.valid = {
+.min_access_size = 2,
+.max_access_size = 2,
+},
 };
 
 static void lance_cleanup(VLANClientState *nc)
@@ -117,13 +116,11 @@ static int lance_init(SysBusDevice *dev)
 SysBusPCNetState *d = FROM_SYSBUS(SysBusPCNetState, dev);
 PCNetState *s = &d->state;
 
-s->mmio_index =
-cpu_register_io_memory(lance_mem_read, lance_mem_write, d,
-   DEVICE_NATIVE_ENDIAN);
+memory_region_init_io(&s->mmio, &lance_mem_ops, s, "lance-mmio", 4);
 
 qdev_init_gpio_in(&dev->qdev, parent_lance_reset, 1);
 
-sysbus_init_mmio(dev, 4, s->mmio_index);
+sysbus_init_mmio_region(dev, &s->mmio);
 
 sysbus_init_irq(dev, &s->irq);
 
diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c
index 216cf81..a25f565 100644
--- a/hw/pcnet-pci.c
+++ b/hw/pcnet-pci.c
@@ -46,6 +46,7 @@
 typedef struct {
 PCIDevice pci_dev;
 PCNetState state;
+MemoryRegion io_bar;
 } PCIPCNetState;
 
 static void pcnet_aprom_writeb(void *opaque, uint32_t addr, uint32_t val)
@@ -69,25 +70,41 @@ static uint32_t pcnet_aprom_readb(void *opaque, uint32_t 
addr)
 return val;
 }
 
-static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
+static uint64_t pcnet_ioport_read(void *opaque, target_phys_addr_t addr,
+  unsigned size)
 {
-PCNetState *d = &DO_UPCAST(PCIPCNetState, pci_dev, pci_dev)->state;
+PCNetState *d = opaque;
 
-#ifdef PCNET_DEBUG_IO
-printf("pcnet_ioport_map addr=0x%04"FMT_PCIBUS" size=0x%04"FMT_PCIBUS"\n",
-   addr, size);
-#endif
+if (addr < 16 && size == 1) {
+return pcnet_aprom_readb(d, addr);
+} else if (addr >= 0x10 && addr < 0x20 && size == 2) {
+return pcnet_ioport_readw(d, addr);
+} else if (addr >= 0x10 && addr < 0x20 && size == 4) {
+return pcnet_ioport_readl(d, addr);
+}
+return ((uint64_t)1 << (size * 8)) - 1;
+}
 
-register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d);
-register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d);
+static void pcnet_ioport_write(void *opaque, target_phys_addr_t addr,
+   uint64_t data, unsigned size)
+{
+PCNetState *d = opaque;
 
-register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d);
-register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d);
-register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d);
-register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d);
+if (addr < 16 && size == 1) {
+return pcnet_aprom_writeb(d, addr, data);
+} else if (addr >= 0x10 && addr < 0x20 && size == 2) {
+return pcnet_ioport_writew(d, addr, data);
+} else if (addr >= 0x10 && addr < 0x20 && size == 4) {
+return pcnet_ioport_writel(d, addr, data);
+}
 }
 
+static const MemoryRegionOps pcnet_io_ops = {
+.read = pcnet_ioport_read,
+.write = pcnet_ioport_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+};
+
 static void pcnet_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t 
val)
 {
 PCNetState *d = opaque;
@@ -202,16 +219,12 @@ static const VMStateDescription vmstate_pci_pcnet = {
 
 /* PCI interface */
 
-static CPUWriteMemoryFunc * const pcnet_mmio_write[] =

[Qemu-devel] [PATCH v2 08/38] cirrus: simplify linear framebuffer access functions

2011-08-03 Thread Avi Kivity
Make use of the memory API's ability to satisfy multi-byte accesses via
multiple single-byte accesses.

Reviewed-by: Richard Henderson 
Signed-off-by: Avi Kivity 
---
 hw/cirrus_vga.c |   74 ++-
 1 files changed, 8 insertions(+), 66 deletions(-)

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 3db15bf..15ccf4a 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2249,7 +2249,8 @@ static void cirrus_cursor_draw_line(VGACommonState *s1, 
uint8_t *d1, int scr_y)
  *
  ***/
 
-static uint32_t cirrus_linear_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t cirrus_linear_read(void *opaque, target_phys_addr_t addr,
+   unsigned size)
 {
 CirrusVGAState *s = opaque;
 uint32_t ret;
@@ -2277,28 +2278,8 @@ static uint32_t cirrus_linear_readb(void *opaque, 
target_phys_addr_t addr)
 return ret;
 }
 
-static uint32_t cirrus_linear_readw(void *opaque, target_phys_addr_t addr)
-{
-uint32_t v;
-
-v = cirrus_linear_readb(opaque, addr);
-v |= cirrus_linear_readb(opaque, addr + 1) << 8;
-return v;
-}
-
-static uint32_t cirrus_linear_readl(void *opaque, target_phys_addr_t addr)
-{
-uint32_t v;
-
-v = cirrus_linear_readb(opaque, addr);
-v |= cirrus_linear_readb(opaque, addr + 1) << 8;
-v |= cirrus_linear_readb(opaque, addr + 2) << 16;
-v |= cirrus_linear_readb(opaque, addr + 3) << 24;
-return v;
-}
-
-static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr,
-uint32_t val)
+static void cirrus_linear_write(void *opaque, target_phys_addr_t addr,
+uint64_t val, unsigned size)
 {
 CirrusVGAState *s = opaque;
 unsigned mode;
@@ -2338,49 +2319,6 @@ static void cirrus_linear_writeb(void *opaque, 
target_phys_addr_t addr,
 }
 }
 
-static void cirrus_linear_writew(void *opaque, target_phys_addr_t addr,
-uint32_t val)
-{
-cirrus_linear_writeb(opaque, addr, val & 0xff);
-cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-}
-
-static void cirrus_linear_writel(void *opaque, target_phys_addr_t addr,
-uint32_t val)
-{
-cirrus_linear_writeb(opaque, addr, val & 0xff);
-cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-cirrus_linear_writeb(opaque, addr + 2, (val >> 16) & 0xff);
-cirrus_linear_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-}
-
-
-static uint64_t cirrus_linear_read(void *opaque, target_phys_addr_t addr,
-   unsigned size)
-{
-CirrusVGAState *s = opaque;
-
-switch (size) {
-case 1: return cirrus_linear_readb(s, addr);
-case 2: return cirrus_linear_readw(s, addr);
-case 4: return cirrus_linear_readl(s, addr);
-default: abort();
-}
-}
-
-static void cirrus_linear_write(void *opaque, target_phys_addr_t addr,
-uint64_t data, unsigned size)
-{
-CirrusVGAState *s = opaque;
-
-switch (size) {
-case 1: return cirrus_linear_writeb(s, addr, data);
-case 2: return cirrus_linear_writew(s, addr, data);
-case 4: return cirrus_linear_writel(s, addr, data);
-default: abort();
-}
-}
-
 /***
  *
  *  system to screen memory access
@@ -2860,6 +2798,10 @@ static const MemoryRegionOps cirrus_linear_io_ops = {
 .read = cirrus_linear_read,
 .write = cirrus_linear_write,
 .endianness = DEVICE_LITTLE_ENDIAN,
+.impl = {
+.min_access_size = 1,
+.max_access_size = 1,
+},
 };
 
 static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
-- 
1.7.5.3




[Qemu-devel] [PATCH v2 11/38] pci: allow I/O BARs to be registered with pci_register_bar_region()

2011-08-03 Thread Avi Kivity
Reviewed-by: Richard Henderson 
Signed-off-by: Avi Kivity 
---
 hw/pci.c   |   43 +++
 hw/pci.h   |1 +
 hw/pci_internals.h |3 ++-
 3 files changed, 26 insertions(+), 21 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 2659d96..980840f 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -271,7 +271,8 @@ void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
 qbus_create_inplace(&bus->qbus, &pci_bus_info, parent, name);
 assert(PCI_FUNC(devfn_min) == 0);
 bus->devfn_min = devfn_min;
-bus->address_space = address_space_mem;
+bus->address_space_mem = address_space_mem;
+bus->address_space_io = address_space_io;
 
 /* host bridge */
 QLIST_INIT(&bus->child);
@@ -847,12 +848,11 @@ static void pci_unregister_io_regions(PCIDevice *pci_dev)
 r = &pci_dev->io_regions[i];
 if (!r->size || r->addr == PCI_BAR_UNMAPPED)
 continue;
-if (r->type == PCI_BASE_ADDRESS_SPACE_IO) {
-isa_unassign_ioport(r->addr, r->filtered_size);
+if (r->memory) {
+memory_region_del_subregion(r->address_space, r->memory);
 } else {
-if (r->memory) {
-memory_region_del_subregion(pci_dev->bus->address_space,
-r->memory);
+if (r->type == PCI_BASE_ADDRESS_SPACE_IO) {
+isa_unassign_ioport(r->addr, r->filtered_size);
 } else {
 cpu_register_physical_memory(pci_to_cpu_addr(pci_dev->bus,
  r->addr),
@@ -934,9 +934,11 @@ static void pci_simple_bar_mapfunc_region(PCIDevice 
*pci_dev, int region_num,
   pcibus_t addr, pcibus_t size,
   int type)
 {
-memory_region_add_subregion_overlap(pci_dev->bus->address_space,
+PCIIORegion *r = &pci_dev->io_regions[region_num];
+
+memory_region_add_subregion_overlap(r->address_space,
 addr,
-pci_dev->io_regions[region_num].memory,
+r->memory,
 1);
 }
 
@@ -953,9 +955,13 @@ void pci_register_bar_region(PCIDevice *pci_dev, int 
region_num,
  uint8_t attr, MemoryRegion *memory)
 {
 pci_register_bar(pci_dev, region_num, memory_region_size(memory),
- PCI_BASE_ADDRESS_SPACE_MEMORY | attr,
+ attr,
  pci_simple_bar_mapfunc_region);
 pci_dev->io_regions[region_num].memory = memory;
+pci_dev->io_regions[region_num].address_space
+= attr & PCI_BASE_ADDRESS_SPACE_IO
+? pci_dev->bus->address_space_io
+: pci_dev->bus->address_space_mem;
 }
 
 pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num)
@@ -1090,7 +1096,9 @@ static void pci_update_mappings(PCIDevice *d)
 
 /* now do the real mapping */
 if (r->addr != PCI_BAR_UNMAPPED) {
-if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
+if (r->memory) {
+memory_region_del_subregion(r->address_space, r->memory);
+} else if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
 int class;
 /* NOTE: specific hack for IDE in PC case:
only one byte must be mapped. */
@@ -1101,16 +1109,11 @@ static void pci_update_mappings(PCIDevice *d)
 isa_unassign_ioport(r->addr, r->filtered_size);
 }
 } else {
-if (r->memory) {
-memory_region_del_subregion(d->bus->address_space,
-r->memory);
-} else {
-cpu_register_physical_memory(pci_to_cpu_addr(d->bus,
- r->addr),
- r->filtered_size,
- IO_MEM_UNASSIGNED);
-qemu_unregister_coalesced_mmio(r->addr, r->filtered_size);
-}
+cpu_register_physical_memory(pci_to_cpu_addr(d->bus,
+ r->addr),
+ r->filtered_size,
+ IO_MEM_UNASSIGNED);
+qemu_unregister_coalesced_mmio(r->addr, r->filtered_size);
 }
 }
 r->addr = new_addr;
diff --git a/hw/pci.h b/hw/pci.h
index 45b30fa..928e96c 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -95,6 +95,7 @@ typedef struct PCIIORegion {
 PCIMapIORegionFunc *map_func;
 ram_addr_t ram_addr;
 MemoryRegion *memory;
+MemoryRegion *address_space;
 } PCIIORegion;
 
 #define PCI_ROM_SLOT 6
diff --git a/hw/pci_internals.h b/hw/pci_internals.h
index c3a463

Re: [Qemu-devel] qemu-kvm aborts - vhost_dev_unassign_memory: Assertion `to >= 0' failed.

2011-08-03 Thread Michael S. Tsirkin
On Mon, Aug 01, 2011 at 11:44:23AM -0600, David Ahern wrote:
> qemu-kvm.git as of:
> 
> commit dacdc4b10bafbb21120e1c24a9665444768ef999
> Merge: 7b69d4f 0af4922
> Author: Avi Kivity 
> Date:   Sun Jul 31 11:42:26 2011 +0300
> 
> Merge branch 'upstream-merge' into next
> 
> is aborting with the error:
> 
> qemu-kvm: qemu-kvm.git/hw/vhost.c:123: vhost_dev_unassign_memory:
> Assertion `to >= 0' failed.
> Aborted
> 
> $ git bisect bad
> 00cb2a99f5e7f73c4fff54ae16c7b6acf463ab5c is the first bad commit
> commit 00cb2a99f5e7f73c4fff54ae16c7b6acf463ab5c
> Author: Avi Kivity 
> Date:   Tue Jul 26 14:26:17 2011 +0300
> 
> pc: convert pc_memory_init() to memory API
> 
> Reviewed-by: Anthony Liguori 
> Signed-off-by: Avi Kivity 
> Signed-off-by: Anthony Liguori 
> 
> :04 04 3d709c2cab75b934030fb9fbdfa99024c855b2a6
> 720d362f9702f15d16519093555182169d0b09bd Mhw
> 

Thanks for the report.
As Avi pointed out it's a vhost bug that got exposed
by a memory API change.
I have posted a patch which should fix that problem -
could you please try it and let me know?

Thanks!

-- 
MST



[Qemu-devel] [PATCH v2 34/38] pci: convert pci rom to memory API

2011-08-03 Thread Avi Kivity
Reviewed-by: Richard Henderson 
Signed-off-by: Avi Kivity 
---
 hw/pci.c |   20 +++-
 hw/pci.h |3 ++-
 2 files changed, 9 insertions(+), 14 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 6aca1af..481eb7e 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -1857,11 +1857,6 @@ static uint8_t pci_find_capability_list(PCIDevice *pdev, 
uint8_t cap_id,
 return next;
 }
 
-static void pci_map_option_rom(PCIDevice *pdev, int region_num, pcibus_t addr, 
pcibus_t size, int type)
-{
-cpu_register_physical_memory(addr, size, pdev->rom_offset);
-}
-
 /* Patch the PCI vendor and device ids in a PCI rom image if necessary.
This is needed for an option rom which is used for more than one device. */
 static void pci_patch_ids(PCIDevice *pdev, uint8_t *ptr, int size)
@@ -1965,9 +1960,9 @@ static int pci_add_option_rom(PCIDevice *pdev, bool 
is_default_rom)
 snprintf(name, sizeof(name), "%s.rom", pdev->qdev.info->vmsd->name);
 else
 snprintf(name, sizeof(name), "%s.rom", pdev->qdev.info->name);
-pdev->rom_offset = qemu_ram_alloc(&pdev->qdev, name, size);
-
-ptr = qemu_get_ram_ptr(pdev->rom_offset);
+pdev->has_rom = true;
+memory_region_init_ram(&pdev->rom, &pdev->qdev, name, size);
+ptr = memory_region_get_ram_ptr(&pdev->rom);
 load_image(path, ptr);
 qemu_free(path);
 
@@ -1978,19 +1973,18 @@ static int pci_add_option_rom(PCIDevice *pdev, bool 
is_default_rom)
 
 qemu_put_ram_ptr(ptr);
 
-pci_register_bar(pdev, PCI_ROM_SLOT, size,
- 0, pci_map_option_rom);
+pci_register_bar_region(pdev, PCI_ROM_SLOT, 0, &pdev->rom);
 
 return 0;
 }
 
 static void pci_del_option_rom(PCIDevice *pdev)
 {
-if (!pdev->rom_offset)
+if (!pdev->has_rom)
 return;
 
-qemu_ram_free(pdev->rom_offset);
-pdev->rom_offset = 0;
+memory_region_destroy(&pdev->rom);
+pdev->has_rom = false;
 }
 
 /*
diff --git a/hw/pci.h b/hw/pci.h
index 25e28b1..6e2bcea 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -191,7 +191,8 @@ struct PCIDevice {
 
 /* Location of option rom */
 char *romfile;
-ram_addr_t rom_offset;
+bool has_rom;
+MemoryRegion rom;
 uint32_t rom_bar;
 };
 
-- 
1.7.5.3




[Qemu-devel] [PATCH v2 08/45] ide: Reject ATA commands specific to drive kinds

2011-08-03 Thread Markus Armbruster
ACS-2 Table B.2 explicitly prohibits ATAPI devices from implementing
WIN_RECAL, WIN_READ_EXT, WIN_READDMA_EXT, WIN_READ_NATIVE_MAX,
WIN_MULTREAD_EXT, WIN_WRITE, WIN_WRITE_ONCE, WIN_WRITE_EXT,
WIN_WRITEDMA_EXT, WIN_MULTWRITE_EXT, WIN_WRITE_VERIFY, WIN_VERIFY,
WIN_VERIFY_ONCE, WIN_VERIFY_EXT, WIN_SPECIFY, WIN_MULTREAD,
WIN_MULTWRITE, WIN_SETMULT, WIN_READDMA, WIN_READDMA_ONCE,
WIN_WRITEDMA, WIN_WRITEDMA_ONCE, WIN_FLUSH_CACHE_EXT.  Restrict them
to IDE_HD and IDE_CFATA.

Same for CFA_WRITE_SECT_WO_ERASE, CFA_WRITE_MULTI_WO_ERASE.  Restrict
them to IDE_CFATA, like the other CFA_ commands.

Signed-off-by: Markus Armbruster 
---
 hw/ide/core.c |   50 +-
 1 files changed, 25 insertions(+), 25 deletions(-)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index a25c175..3c46176 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -888,27 +888,27 @@ uint8_t ide_cmd_table[0x100] = {
 [CFA_REQ_EXT_ERROR_CODE]= CFA_OK,
 [WIN_DSM]   = ALL_OK,
 [WIN_DEVICE_RESET]  = CD_OK,
-[WIN_RECAL] = ALL_OK,
+[WIN_RECAL] = HD_CFA_OK,
 [WIN_READ]  = ALL_OK,
 [WIN_READ_ONCE] = ALL_OK,
-[WIN_READ_EXT]  = ALL_OK,
-[WIN_READDMA_EXT]   = ALL_OK,
-[WIN_READ_NATIVE_MAX_EXT]   = ALL_OK,
-[WIN_MULTREAD_EXT]  = ALL_OK,
-[WIN_WRITE] = ALL_OK,
-[WIN_WRITE_ONCE]= ALL_OK,
-[WIN_WRITE_EXT] = ALL_OK,
-[WIN_WRITEDMA_EXT]  = ALL_OK,
-[CFA_WRITE_SECT_WO_ERASE]   = ALL_OK,
-[WIN_MULTWRITE_EXT] = ALL_OK,
-[WIN_WRITE_VERIFY]  = ALL_OK,
-[WIN_VERIFY]= ALL_OK,
-[WIN_VERIFY_ONCE]   = ALL_OK,
-[WIN_VERIFY_EXT]= ALL_OK,
+[WIN_READ_EXT]  = HD_CFA_OK,
+[WIN_READDMA_EXT]   = HD_CFA_OK,
+[WIN_READ_NATIVE_MAX_EXT]   = HD_CFA_OK,
+[WIN_MULTREAD_EXT]  = HD_CFA_OK,
+[WIN_WRITE] = HD_CFA_OK,
+[WIN_WRITE_ONCE]= HD_CFA_OK,
+[WIN_WRITE_EXT] = HD_CFA_OK,
+[WIN_WRITEDMA_EXT]  = HD_CFA_OK,
+[CFA_WRITE_SECT_WO_ERASE]   = CFA_OK,
+[WIN_MULTWRITE_EXT] = HD_CFA_OK,
+[WIN_WRITE_VERIFY]  = HD_CFA_OK,
+[WIN_VERIFY]= HD_CFA_OK,
+[WIN_VERIFY_ONCE]   = HD_CFA_OK,
+[WIN_VERIFY_EXT]= HD_CFA_OK,
 [WIN_SEEK]  = HD_CFA_OK,
 [CFA_TRANSLATE_SECTOR]  = CFA_OK,
 [WIN_DIAGNOSE]  = ALL_OK,
-[WIN_SPECIFY]   = ALL_OK,
+[WIN_SPECIFY]   = HD_CFA_OK,
 [WIN_STANDBYNOW2]   = ALL_OK,
 [WIN_IDLEIMMEDIATE2]= ALL_OK,
 [WIN_STANDBY2]  = ALL_OK,
@@ -920,14 +920,14 @@ uint8_t ide_cmd_table[0x100] = {
 [WIN_SMART] = HD_CFA_OK,
 [CFA_ACCESS_METADATA_STORAGE]   = CFA_OK,
 [CFA_ERASE_SECTORS] = CFA_OK,
-[WIN_MULTREAD]  = ALL_OK,
-[WIN_MULTWRITE] = ALL_OK,
-[WIN_SETMULT]   = ALL_OK,
-[WIN_READDMA]   = ALL_OK,
-[WIN_READDMA_ONCE]  = ALL_OK,
-[WIN_WRITEDMA]  = ALL_OK,
-[WIN_WRITEDMA_ONCE] = ALL_OK,
-[CFA_WRITE_MULTI_WO_ERASE]  = ALL_OK,
+[WIN_MULTREAD]  = HD_CFA_OK,
+[WIN_MULTWRITE] = HD_CFA_OK,
+[WIN_SETMULT]   = HD_CFA_OK,
+[WIN_READDMA]   = HD_CFA_OK,
+[WIN_READDMA_ONCE]  = HD_CFA_OK,
+[WIN_WRITEDMA]  = HD_CFA_OK,
+[WIN_WRITEDMA_ONCE] = HD_CFA_OK,
+[CFA_WRITE_MULTI_WO_ERASE]  = CFA_OK,
 [WIN_STANDBYNOW1]   = ALL_OK,
 [WIN_IDLEIMMEDIATE] = ALL_OK,
 [WIN_STANDBY]   = ALL_OK,
@@ -935,7 +935,7 @@ uint8_t ide_cmd_table[0x100] = {
 [WIN_CHECKPOWERMODE1]   = ALL_OK,
 [WIN_SLEEPNOW1] = ALL_OK,
 [WIN_FLUSH_CACHE]   = ALL_OK,
-[WIN_FLUSH_CACHE_EXT]   = ALL_OK,
+[WIN_FLUSH_CACHE_EXT]   = HD_CFA_OK,
 [WIN_IDENTIFY]  = ALL_OK,
 [WIN_SETFEATURES]   = ALL_OK,
 [IBM_SENSE_CONDITION]   = CFA_OK,
-- 
1.7.6




[Qemu-devel] [PATCH v2 16/45] scsi-disk: Track tray locked state

2011-08-03 Thread Markus Armbruster
We already track it in BlockDriverState.  Just like tray open/close
state, we should track it in the device models instead, because it's
device state.

Signed-off-by: Markus Armbruster 
---
 hw/scsi-disk.c |4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index db72b86..8ca69f2 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -73,6 +73,7 @@ struct SCSIDiskState
 char *serial;
 SCSISense sense;
 bool tray_open;
+bool tray_locked;
 };
 
 static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type);
@@ -678,7 +679,7 @@ static int mode_sense_page(SCSIRequest *req, int page, 
uint8_t *p,
 p[5] = 0xff; /* CD DA, DA accurate, RW supported,
 RW corrected, C2 errors, ISRC,
 UPC, Bar code */
-p[6] = 0x2d | (bdrv_is_locked(s->bs)? 2 : 0);
+p[6] = 0x2d | (s->tray_locked ? 2 : 0);
 /* Locking supported, jumper present, eject, tray */
 p[7] = 0; /* no volume & mute control, no
  changer */
@@ -896,6 +897,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r, 
uint8_t *outbuf)
 scsi_disk_emulate_start_stop(r);
 break;
 case ALLOW_MEDIUM_REMOVAL:
+s->tray_locked = req->cmd.buf[4] & 1;
 bdrv_set_locked(s->bs, req->cmd.buf[4] & 1);
 break;
 case READ_CAPACITY_10:
-- 
1.7.6




[Qemu-devel] [PATCH v2 03/45] block: Split change_cb() into change_media_cb(), resize_cb()

2011-08-03 Thread Markus Armbruster
Multiplexing callbacks complicates matters needlessly.

Signed-off-by: Markus Armbruster 
---
 block.c |   23 +++
 block.h |   12 +++-
 block_int.h |3 ---
 hw/ide/core.c   |8 ++--
 hw/sd.c |8 ++--
 hw/virtio-blk.c |8 +++-
 6 files changed, 33 insertions(+), 29 deletions(-)

diff --git a/block.c b/block.c
index 3aa1eb5..17933c8 100644
--- a/block.c
+++ b/block.c
@@ -44,7 +44,7 @@
 #include 
 #endif
 
-static void bdrv_dev_change_cb(BlockDriverState *bs, int reason);
+static void bdrv_dev_change_media_cb(BlockDriverState *bs);
 static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
 int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
 BlockDriverCompletionFunc *cb, void *opaque);
@@ -663,7 +663,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, 
int flags,
 
 if (!bdrv_key_required(bs)) {
 bs->media_changed = 1;
-bdrv_dev_change_cb(bs, CHANGE_MEDIA);
+bdrv_dev_change_media_cb(bs);
 }
 
 return 0;
@@ -700,7 +700,7 @@ void bdrv_close(BlockDriverState *bs)
 }
 
 bs->media_changed = 1;
-bdrv_dev_change_cb(bs, CHANGE_MEDIA);
+bdrv_dev_change_media_cb(bs);
 }
 }
 
@@ -779,10 +779,17 @@ void bdrv_set_dev_ops(BlockDriverState *bs, const 
BlockDevOps *ops,
 bs->dev_opaque = opaque;
 }
 
-static void bdrv_dev_change_cb(BlockDriverState *bs, int reason)
+static void bdrv_dev_change_media_cb(BlockDriverState *bs)
 {
-if (bs->dev_ops && bs->dev_ops->change_cb) {
-bs->dev_ops->change_cb(bs->dev_opaque, reason);
+if (bs->dev_ops && bs->dev_ops->change_media_cb) {
+bs->dev_ops->change_media_cb(bs->dev_opaque);
+}
+}
+
+static void bdrv_dev_resize_cb(BlockDriverState *bs)
+{
+if (bs->dev_ops && bs->dev_ops->resize_cb) {
+bs->dev_ops->resize_cb(bs->dev_opaque);
 }
 }
 
@@ -1243,7 +1250,7 @@ int bdrv_truncate(BlockDriverState *bs, int64_t offset)
 ret = drv->bdrv_truncate(bs, offset);
 if (ret == 0) {
 ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
-bdrv_dev_change_cb(bs, CHANGE_SIZE);
+bdrv_dev_resize_cb(bs);
 }
 return ret;
 }
@@ -1619,7 +1626,7 @@ int bdrv_set_key(BlockDriverState *bs, const char *key)
 bs->valid_key = 1;
 /* call the change callback now, we skipped it on open */
 bs->media_changed = 1;
-bdrv_dev_change_cb(bs, CHANGE_MEDIA);
+bdrv_dev_change_media_cb(bs);
 }
 return ret;
 }
diff --git a/block.h b/block.h
index 6c55d4c..3ff30c9 100644
--- a/block.h
+++ b/block.h
@@ -28,8 +28,18 @@ typedef struct QEMUSnapshotInfo {
 uint64_t vm_clock_nsec; /* VM clock relative to boot */
 } QEMUSnapshotInfo;
 
+/* Callbacks for block device models */
 typedef struct BlockDevOps {
-void (*change_cb)(void *opaque, int reason);
+/*
+ * Runs when virtual media changed (monitor commands eject, change)
+ * Beware: doesn't run when a host device's physical media
+ * changes.  Sure would be useful if it did.
+ */
+void (*change_media_cb)(void *opaque);
+/*
+ * Runs when the size changed (e.g. monitor command block_resize)
+ */
+void (*resize_cb)(void *opaque);
 } BlockDevOps;
 
 #define BDRV_O_RDWR0x0002
diff --git a/block_int.h b/block_int.h
index 48d6026..215f008 100644
--- a/block_int.h
+++ b/block_int.h
@@ -211,9 +211,6 @@ struct BlockDriverState {
 void *private;
 };
 
-#define CHANGE_MEDIA0x01
-#define CHANGE_SIZE 0x02
-
 struct BlockDriverAIOCB {
 AIOPool *pool;
 BlockDriverState *bs;
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 773b7cf..ec043a3 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -758,15 +758,11 @@ static void ide_cfata_metadata_write(IDEState *s)
 }
 
 /* called when the inserted state of the media has changed */
-static void cdrom_change_cb(void *opaque, int reason)
+static void ide_cd_change_cb(void *opaque)
 {
 IDEState *s = opaque;
 uint64_t nb_sectors;
 
-if (!(reason & CHANGE_MEDIA)) {
-return;
-}
-
 bdrv_get_geometry(s->bs, &nb_sectors);
 s->nb_sectors = nb_sectors;
 
@@ -1718,7 +1714,7 @@ void ide_bus_reset(IDEBus *bus)
 }
 
 static const BlockDevOps ide_cd_block_ops = {
-.change_cb = cdrom_change_cb,
+.change_media_cb = ide_cd_change_cb,
 };
 
 int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
diff --git a/hw/sd.c b/hw/sd.c
index d47b7a4..24f4af8 100644
--- a/hw/sd.c
+++ b/hw/sd.c
@@ -420,14 +420,10 @@ static void sd_reset(SDState *sd, BlockDriverState *bdrv)
 sd->pwd_len = 0;
 }
 
-static void sd_cardchange(void *opaque, int reason)
+static void sd_cardchange(void *opaque)
 {
 SDState *sd = opaque;
 
-if (!(reason & CHANGE_MEDIA)) {
-return;
-}
-
 qemu_set_irq(sd->inserted_cb, bdrv_is_inserted(sd->bdrv));
 if (bdrv_is_inserted(sd->bdrv)) {
 sd_reset(sd, sd->bdrv);
@@ -436,7 +432,7

[Qemu-devel] [PATCH v2 04/45] ide: Update command code definitions as per ACS-2 Table B.2

2011-08-03 Thread Markus Armbruster
Drop WIN_SRST, it has the same value as WIN_DEVICE_RESET.

Drop unused WIN_RESTORE, it has the same value as WIN_RECAL.

Drop codes that are not implemented and long obsolete: WIN_READ_LONG,
WIN_READ_LONG_ONCE, WIN_WRITE_LONG, WIN_WRITE_LONG_ONCE, WIN_FORMAT
(all obsolete since ATA4), WIN_ACKMEDIACHANGE, WIN_POSTBOOT,
WIN_PREBOOT (obsolete since ATA3), WIN_WRITE_SAME (obsolete since
ATA3, code reused for something else in ACS2), WIN_IDENTIFY_DMA
(obsolete since ATA4).

Drop codes that are not implemented and vendor-specific:
EXABYTE_ENABLE_NEST, DISABLE_SEAGATE.

Drop WIN_INIT, it isn't implemented, its value used to be reserved,
and is used for something else since ATA8.

CFA_IDLEIMMEDIATE isn't specific to CFATA.  ACS-2 shows it as a
defined command in ATA-1, -2 and -3.  Rename to WIN_IDLEIMMEDIATE2.

Mark vendor specific, retired, and obsolete codes.

Signed-off-by: Markus Armbruster 
---
 hw/ide/core.c |4 +-
 hw/ide/internal.h |  171 -
 2 files changed, 92 insertions(+), 83 deletions(-)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index ec043a3..88ee768 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -1104,7 +1104,7 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val)
 case WIN_STANDBYNOW1:
 case WIN_STANDBYNOW2:
 case WIN_IDLEIMMEDIATE:
-case CFA_IDLEIMMEDIATE:
+case WIN_IDLEIMMEDIATE2:
 case WIN_SETIDLE1:
 case WIN_SETIDLE2:
 case WIN_SLEEPNOW1:
@@ -1143,7 +1143,7 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val)
   */
 ide_set_irq(s->bus);
 break;
-case WIN_SRST:
+case WIN_DEVICE_RESET:
 if (s->drive_kind != IDE_CD)
 goto abort_cmd;
 ide_set_signature(s);
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index 02e805f..46e84fa 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -55,111 +55,120 @@ typedef struct IDEDMAOps IDEDMAOps;
 #define IDE_CMD_RESET   0x04
 #define IDE_CMD_DISABLE_IRQ 0x02
 
-/* ATA/ATAPI Commands pre T13 Spec */
+/* ACS-2 T13/2015-D Table B.2 Command codes */
 #define WIN_NOP0x00
-/*
- * 0x01->0x02 Reserved
- */
+/* reserved 0x01..0x02 */
 #define CFA_REQ_EXT_ERROR_CODE 0x03 /* CFA Request Extended Error Code 
*/
-/*
- *  0x04->0x05 Reserved
- */
+/* reserved 0x04..0x05 */
 #define WIN_DSM 0x06
-/*
- *  0x07 Reserved
- */
-#define WIN_SRST   0x08 /* ATAPI soft reset command */
+/* reserved 0x07 */
 #define WIN_DEVICE_RESET   0x08
-/*
- * 0x09->0x0F Reserved
- */
-#define WIN_RECAL  0x10
-#define WIN_RESTOREWIN_RECAL
-/*
- * 0x10->0x1F Reserved
- */
+/* reserved 0x09..0x0a */
+/* REQUEST SENSE DATA EXT   0x0B */
+/* reserved 0x0C..0x0F */
+#define WIN_RECAL   0x10 /* obsolete since ATA4 */
+/* obsolete since ATA3, retired in ATA4 0x11..0x1F */
 #define WIN_READ   0x20 /* 28-Bit */
-#define WIN_READ_ONCE  0x21 /* 28-Bit without retries */
-#define WIN_READ_LONG  0x22 /* 28-Bit */
-#define WIN_READ_LONG_ONCE 0x23 /* 28-Bit without retries */
+#define WIN_READ_ONCE   0x21 /* 28-Bit w/o retries, obsolete 
since ATA5 */
+/* obsolete since ATA4  0x22..0x23 */
 #define WIN_READ_EXT   0x24 /* 48-Bit */
 #define WIN_READDMA_EXT0x25 /* 48-Bit */
-#define WIN_READDMA_QUEUED_EXT 0x26 /* 48-Bit */
+#define WIN_READDMA_QUEUED_EXT  0x26 /* 48-Bit, obsolete since ACS2 */
 #define WIN_READ_NATIVE_MAX_EXT0x27 /* 48-Bit */
-/*
- * 0x28
- */
+/* reserved 0x28 */
 #define WIN_MULTREAD_EXT   0x29 /* 48-Bit */
-/*
- * 0x2A->0x2F Reserved
- */
+/* READ STREAM DMA EXT  0x2A */
+/* READ STREAM EXT  0x2B */
+/* reserved 0x2C..0x2E */
+/* READ LOG EXT 0x2F */
 #define WIN_WRITE  0x30 /* 28-Bit */
-#define WIN_WRITE_ONCE 0x31 /* 28-Bit without retries */
-#define WIN_WRITE_LONG 0x32 /* 28-Bit */
-#define WIN_WRITE_LONG_ONCE0x33 /* 28-Bit without retries */
+#define WIN_WRITE_ONCE  0x31 /* 28-Bit w/o retries, obsolete 
since ATA5 */
+/* obsolete since ATA4  0x32..0x33 */
 #define WIN_WRITE_EXT  0x34 /* 48-Bit */
 #define WIN_WRITEDMA_EXT   0x35 /* 48-Bit */
 #define WIN_WRITEDMA_QUEUED_EXT0x36 /* 48-Bit */
+#define WIN_SET_MAX_EXT 0x37 /* 48-Bit, obsolete since ACS2 */
 #define WIN_SET_MAX_EXT0x37 /* 48-Bit */
 #define CFA_WRITE_SECT

[Qemu-devel] [PATCH v2 28/38] sun4u: convert to memory API

2011-08-03 Thread Avi Kivity
fixes memory leak on repeated BAR map/unmap

Reviewed-by: Richard Henderson 
Signed-off-by: Avi Kivity 
---
 hw/sun4u.c |   55 +--
 1 files changed, 25 insertions(+), 30 deletions(-)

diff --git a/hw/sun4u.c b/hw/sun4u.c
index d7dcaf0..74a06a8 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -91,6 +91,12 @@ struct hwdef {
 uint64_t console_serial_base;
 };
 
+typedef struct EbusState {
+PCIDevice pci_dev;
+MemoryRegion bar0;
+MemoryRegion bar1;
+} EbusState;
+
 int DMA_get_channel_mode (int nchan)
 {
 return 0;
@@ -518,21 +524,6 @@ void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit)
 }
 }
 
-static void ebus_mmio_mapfunc(PCIDevice *pci_dev, int region_num,
-  pcibus_t addr, pcibus_t size, int type)
-{
-EBUS_DPRINTF("Mapping region %d registers at %" FMT_PCIBUS "\n",
- region_num, addr);
-switch (region_num) {
-case 0:
-isa_mmio_init(addr, 0x100);
-break;
-case 1:
-isa_mmio_init(addr, 0x80);
-break;
-}
-}
-
 static void dummy_isa_irq_handler(void *opaque, int n, int level)
 {
 }
@@ -549,27 +540,31 @@ pci_ebus_init(PCIBus *bus, int devfn)
 }
 
 static int
-pci_ebus_init1(PCIDevice *s)
+pci_ebus_init1(PCIDevice *pci_dev)
 {
-isa_bus_new(&s->qdev);
+EbusState *s = container_of(pci_dev, EbusState, pci_dev);
+
+isa_bus_new(&pci_dev->qdev);
 
-s->config[0x04] = 0x06; // command = bus master, pci mem
-s->config[0x05] = 0x00;
-s->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
-s->config[0x07] = 0x03; // status = medium devsel
-s->config[0x09] = 0x00; // programming i/f
-s->config[0x0D] = 0x0a; // latency_timer
+pci_dev->config[0x04] = 0x06; // command = bus master, pci mem
+pci_dev->config[0x05] = 0x00;
+pci_dev->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no 
error
+pci_dev->config[0x07] = 0x03; // status = medium devsel
+pci_dev->config[0x09] = 0x00; // programming i/f
+pci_dev->config[0x0D] = 0x0a; // latency_timer
 
-pci_register_bar(s, 0, 0x100, PCI_BASE_ADDRESS_SPACE_MEMORY,
-   ebus_mmio_mapfunc);
-pci_register_bar(s, 1, 0x80,  PCI_BASE_ADDRESS_SPACE_MEMORY,
-   ebus_mmio_mapfunc);
+isa_mmio_setup(&s->bar0, 0x100);
+pci_register_bar_region(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
+&s->bar0);
+isa_mmio_setup(&s->bar1, 0x80);
+pci_register_bar_region(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
+&s->bar1);
 return 0;
 }
 
 static PCIDeviceInfo ebus_info = {
 .qdev.name = "ebus",
-.qdev.size = sizeof(PCIDevice),
+.qdev.size = sizeof(EbusState),
 .init = pci_ebus_init1,
 .vendor_id = PCI_VENDOR_ID_SUN,
 .device_id = PCI_DEVICE_ID_SUN_EBUS,
-- 
1.7.5.3




[Qemu-devel] [PATCH v2 24/45] scsi-disk: Avoid physical/virtual tray state mismatch

2011-08-03 Thread Markus Armbruster
When scsi-cd is backed by a physical drive, we want the physical tray
match the virtual one.  To that end, we call bdrv_eject() on guest's
load/eject, and bdrv_lock_medium() on guest's prevent/allow removal.
But we don't set the initial state on device model init.  Fix that.

While there, also unlock on device model exit.

Signed-off-by: Markus Armbruster 
---
 hw/scsi-disk.c |7 +++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 19a1843..f223de6 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1205,6 +1205,9 @@ static void scsi_destroy(SCSIDevice *dev)
 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
 
 scsi_device_purge_requests(&s->qdev);
+if (s->qdev.type == TYPE_ROM) {
+bdrv_lock_medium(s->qdev.conf.bs, 0);
+}
 blockdev_mark_auto_del(s->qdev.conf.bs);
 }
 
@@ -1265,6 +1268,10 @@ static int scsi_initfn(SCSIDevice *dev, uint8_t 
scsi_type)
 s->qdev.type = scsi_type;
 qemu_add_vm_change_state_handler(scsi_dma_restart_cb, s);
 bdrv_set_removable(s->bs, scsi_type == TYPE_ROM);
+if (scsi_type == TYPE_ROM) {
+bdrv_lock_medium(s->bs, s->tray_locked);
+bdrv_eject(s->bs, s->tray_open);
+}
 add_boot_device_path(s->qdev.conf.bootindex, &dev->qdev, ",0");
 return 0;
 }
-- 
1.7.6




Re: [Qemu-devel] [PATCH] lm32: softusb: claim to support full speed

2011-08-03 Thread Gerd Hoffmann

On 07/21/11 20:52, Michael Walle wrote:

The QEMU keyboard and mouse reports themselves as full speed devices,
though they are actually low speed devices. Until this is fixed, claim that
we are supporting full speed devices.

Signed-off-by: Michael Walle


For both master+stable:

Acked-by: Gerd Hoffmann 

cheers,
  Gerd



[Qemu-devel] [PATCH v2 00/45] Block layer cleanup & fixes

2011-08-03 Thread Markus Armbruster
This patch series looks bigger than it is.  All the patches are small
and hopefully easy to review.

Objectives:

* Push BlockDriverState members locked, tray_open, media_changed into
  device models, where they belong.

* BlockDriverState member removable is a confusing mess, replace it.

* Improve eject -f.

Also clean up minor messes as they get in the way.

It is based on Kevin's block branch f08df41b.

Part I: Preliminaries
PATCH 01-03: Work on block layer interface for device models

Part II: Move tray state to device models
PATCH 04-10 IDE tray open/closed
PATCH 11-12 SCSI tray open/closed
PATCH 13-14 block layer kill tray_open
PATCH 15-16 IDE & SCSI tray lock
PATCH 17-19 block layer kill locked
PATCH 20-24 IDE & SCSI tray bug fixes
PATCH 25-27 IDE & SCSI migrate tray state
PATCH 28-30 block layer & fdc media_changed

Part III: Replace removable
PATCH 31-34 clean up inappopriate uses of removable
PATCH 35-36 replace remaining users

Part IV: Miscellaneous
PATCH 37cover tray open/closed in info block
PATCH 38-43 Reduce unclean use of block_int.h
PATCH 44-45 Improve eject -f

Naturally, I want all parts applied.  But I did my best to make
applying only a prefix workable, too.

Review invited from:

* Kevin, Christoph and Amit reviewed v1.

* Hannes commented on the SCSI stuff in v1.

* Luiz, the following patches affect QMP's query-block: PATCH 35
  `block: Clean up remaining users of "removable"' and PATCH 38
  `block: Show whether the guest ejected the medium in info block'.

* Juan, please review PATCH 26 `ide/atapi: Preserve tray state on
  migration', PATCH 27 `scsi-disk: Preserve tray state on migration',
  and PATCH 32 `savevm: Include writable devices with removable
  media'.

* Andrzej commented to v1 of PATCH 34 `spitz tosa: Simplify "drive is
  suitable for microdrive" test'.  It is unchanged.

* Stefano, you reviewed v1 of PATCH 35 (affects "-drive if=xen").
  Please have a look at new PATCH 33 `xen: Clean up
  pci_piix3_xen_ide_unplug()'s test for "not a CD"'.

Testing

* Both master and the block branch are broken for me by Avi's memory
  API work (Avi reproduced, and claims to have a fix), so for testing
  I had to rebase the block branch on an older master cde1a700 plus my
  dependencies: some Xen work e3745602..679f4f8b, and some nand work
  64de0e46..63efb1d9.

* Linux boots, both from HD and CD.

* For both IDE and SCSI:

  - info block reports tray state correctly

  - Guest locking the tray stops eject (without -f) and change

  - eject -f; change works even while tray is locked by guest

  - Physical tray state tracks the virtual one (file=/dev/sr0)

  - Reading /dev/sr0 with tray open behaves as before: IDE closes the
tray and reads (matches bare metal), SCSI reports no medium

  - Tray state is migrated correctly (tested with savevm/loadvm)

* Guest still notices CD media change (IDE only, SCSI doesn't work
  before or after my patches because GESN isn't implemented)

* Migrating ide-cd to older version works when tray is closed and
  unlocked, else fails (tested with savevm/loadvm)

* Migrating scsi-cd to older version fails

* Linux detects fdc media change (from monitor)

* savevm and loadvm snapshot read/write floppy

* spitz and tosa initialize their microdrive as before (PATCH 34;
  tested with -S -M {spitz,tosa}, didn't actually try to boot)

Not tested:

* BlockDriver "host_floppy"

  Lack the hardware.  Like pretty much everybody not running a
  computer museum.  

  Is keeping BlockDriver "host_floppy" around still worth our while?

  If the answer is no, I'm happy to respin with PATCH 28-30 replaced
  by a single patch to remove it, and simplify block.c and hw/fdc.c.


v2:

* Rebased to block branch; non-trivial conflicts:
  - Old PATCH 01-02,06-09 already there, drop
  - `block: Attach non-qdev devices as well':
- cover new pci_piix3_xen_ide_unplug()
- hw/nand has been qdefivied, drop hunk
- onenand_init() changed, rewrite hunk
  - pci_piix3_xen_ide_unplug() needs new PATCH 33.

* Drop old PATCH 18 `scsi-disk: Reject CD-specific SCSI commands to
  disks' because Hannes wants to do it differently, and it's not
  essential to this series.

* Christoph's advice:
  - Rework `ide: Update command code definitions as per ACS-2'
  - Add comment to `ide: Fix ATA command READ to set ATAPI signature
for CD-ROM'
  - Squash `ide/atapi: Track tray open/close state' and `ide/atapi:
Switch from BlockDriverState's tray_open to own'
  - Squash `ide/atapi: Track tray locked state' and `ide/atapi: Switch
from BlockDriverState's locked to own tray_locked'
  - Squash `scsi-disk: Track tray locked state' and `scsi-disk: Switch
from BlockDriverState's locked to own tray_locked'
  - Drop `block: Move BlockDriverAIOCB & friends from block_int.h to
block.h'

* Luiz's advice:
  - Change query-block to always include "ejected" for removable
devices.  Requires moving `block: Show whether the guest ejected
the medium in info block', which causes a b

Re: [Qemu-devel] [PATCH] do not call monitor_resume() from migrate_fd_put_buffer() error path

2011-08-03 Thread Jan Kiszka
On 2011-08-03 09:38, Michael Tokarev wrote:
> So, can we decide on this somehow?  I don't see a code
> path where we don't call monitor_resume at the end,
> so the "intermediate" monitor_resume can be dropped.
> This way we fix real bug.  If there will be other
> problem from that, it can be fixed later - this will
> mean that code path is found...

I do not see any reason for the spurious resume as well, so you may add my

Reviewed-by: Jan Kiszka 

> 
> Should I resend the initial patch again?

May help to finally trigger the merge. Direct it to Luiz Capitulino as
the subsystem maintainer.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux



[Qemu-devel] [PATCH v2 19/45] block: Rename bdrv_set_locked() to bdrv_lock_medium()

2011-08-03 Thread Markus Armbruster

Signed-off-by: Markus Armbruster 
---
 block.c   |8 
 block.h   |2 +-
 block/raw-posix.c |8 
 block/raw.c   |6 +++---
 block_int.h   |2 +-
 hw/ide/atapi.c|2 +-
 hw/scsi-disk.c|2 +-
 trace-events  |2 +-
 8 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/block.c b/block.c
index 3a8a4e6..10c1b1a 100644
--- a/block.c
+++ b/block.c
@@ -3037,14 +3037,14 @@ void bdrv_eject(BlockDriverState *bs, int eject_flag)
  * Lock or unlock the media (if it is locked, the user won't be able
  * to eject it manually).
  */
-void bdrv_set_locked(BlockDriverState *bs, int locked)
+void bdrv_lock_medium(BlockDriverState *bs, int locked)
 {
 BlockDriver *drv = bs->drv;
 
-trace_bdrv_set_locked(bs, locked);
+trace_bdrv_lock_medium(bs, locked);
 
-if (drv && drv->bdrv_set_locked) {
-drv->bdrv_set_locked(bs, locked);
+if (drv && drv->bdrv_lock_medium) {
+drv->bdrv_lock_medium(bs, locked);
 }
 }
 
diff --git a/block.h b/block.h
index 37d9048..4a6b957 100644
--- a/block.h
+++ b/block.h
@@ -212,7 +212,7 @@ int bdrv_is_sg(BlockDriverState *bs);
 int bdrv_enable_write_cache(BlockDriverState *bs);
 int bdrv_is_inserted(BlockDriverState *bs);
 int bdrv_media_changed(BlockDriverState *bs);
-void bdrv_set_locked(BlockDriverState *bs, int locked);
+void bdrv_lock_medium(BlockDriverState *bs, int locked);
 void bdrv_eject(BlockDriverState *bs, int eject_flag);
 void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size);
 BlockDriverState *bdrv_find(const char *name);
diff --git a/block/raw-posix.c b/block/raw-posix.c
index c5c9944..b429baf 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -1358,7 +1358,7 @@ static void cdrom_eject(BlockDriverState *bs, int 
eject_flag)
 }
 }
 
-static void cdrom_set_locked(BlockDriverState *bs, int locked)
+static void cdrom_lock_medium(BlockDriverState *bs, int locked)
 {
 BDRVRawState *s = bs->opaque;
 
@@ -1396,7 +1396,7 @@ static BlockDriver bdrv_host_cdrom = {
 /* removable device support */
 .bdrv_is_inserted   = cdrom_is_inserted,
 .bdrv_eject = cdrom_eject,
-.bdrv_set_locked= cdrom_set_locked,
+.bdrv_lock_medium   = cdrom_lock_medium,
 
 /* generic scsi device */
 .bdrv_ioctl = hdev_ioctl,
@@ -1477,7 +1477,7 @@ static void cdrom_eject(BlockDriverState *bs, int 
eject_flag)
 cdrom_reopen(bs);
 }
 
-static void cdrom_set_locked(BlockDriverState *bs, int locked)
+static void cdrom_lock_medium(BlockDriverState *bs, int locked)
 {
 BDRVRawState *s = bs->opaque;
 
@@ -1517,7 +1517,7 @@ static BlockDriver bdrv_host_cdrom = {
 /* removable device support */
 .bdrv_is_inserted   = cdrom_is_inserted,
 .bdrv_eject = cdrom_eject,
-.bdrv_set_locked= cdrom_set_locked,
+.bdrv_lock_medium   = cdrom_lock_medium,
 };
 #endif /* __FreeBSD__ */
 
diff --git a/block/raw.c b/block/raw.c
index cb6203e..fa74ef1 100644
--- a/block/raw.c
+++ b/block/raw.c
@@ -80,9 +80,9 @@ static void raw_eject(BlockDriverState *bs, int eject_flag)
 bdrv_eject(bs->file, eject_flag);
 }
 
-static void raw_set_locked(BlockDriverState *bs, int locked)
+static void raw_lock_medium(BlockDriverState *bs, int locked)
 {
-bdrv_set_locked(bs->file, locked);
+bdrv_lock_medium(bs->file, locked);
 }
 
 static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
@@ -138,7 +138,7 @@ static BlockDriver bdrv_raw = {
 
 .bdrv_is_inserted   = raw_is_inserted,
 .bdrv_eject = raw_eject,
-.bdrv_set_locked= raw_set_locked,
+.bdrv_lock_medium   = raw_lock_medium,
 .bdrv_ioctl = raw_ioctl,
 .bdrv_aio_ioctl = raw_aio_ioctl,
 
diff --git a/block_int.h b/block_int.h
index 9eff892..eb7f46d 100644
--- a/block_int.h
+++ b/block_int.h
@@ -119,7 +119,7 @@ struct BlockDriver {
 int (*bdrv_is_inserted)(BlockDriverState *bs);
 int (*bdrv_media_changed)(BlockDriverState *bs);
 void (*bdrv_eject)(BlockDriverState *bs, int eject_flag);
-void (*bdrv_set_locked)(BlockDriverState *bs, int locked);
+void (*bdrv_lock_medium)(BlockDriverState *bs, int locked);
 
 /* to control generic scsi devices */
 int (*bdrv_ioctl)(BlockDriverState *bs, unsigned long int req, void *buf);
diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index 6cb8f0e..1be6cbf 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -822,7 +822,7 @@ static void cmd_test_unit_ready(IDEState *s, uint8_t *buf)
 static void cmd_prevent_allow_medium_removal(IDEState *s, uint8_t* buf)
 {
 s->tray_locked = buf[4] & 1;
-bdrv_set_locked(s->bs, buf[4] & 1);
+bdrv_lock_medium(s->bs, buf[4] & 1);
 ide_atapi_cmd_ok(s);
 }
 
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 6f5ec0d..79d7737 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -901,7 +901,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r, 
uint8_t *outbuf)
 break;
 case ALLOW_MEDIUM_REMOVAL

[Qemu-devel] [PATCH v2 28/45] block/raw: Fix to forward method bdrv_media_changed()

2011-08-03 Thread Markus Armbruster
Block driver "raw" forwards most methods to the underlying block
driver.  However, it doesn't implement method bdrv_media_changed().
Makes bdrv_media_changed() always return -ENOTSUP.

I believe -fda /dev/fd0 gives you raw over host_floppy, and disk
change detection (fdc register 7 bit 7) is broken.  Testing my theory
requires a computer museum, though.

Signed-off-by: Markus Armbruster 
---
 block/raw.c |7 +++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/block/raw.c b/block/raw.c
index fa74ef1..934f439 100644
--- a/block/raw.c
+++ b/block/raw.c
@@ -75,6 +75,11 @@ static int raw_is_inserted(BlockDriverState *bs)
 return bdrv_is_inserted(bs->file);
 }
 
+static int raw_media_changed(BlockDriverState *bs)
+{
+return bdrv_media_changed(bs->file);
+}
+
 static void raw_eject(BlockDriverState *bs, int eject_flag)
 {
 bdrv_eject(bs->file, eject_flag);
@@ -137,8 +142,10 @@ static BlockDriver bdrv_raw = {
 .bdrv_discard   = raw_discard,
 
 .bdrv_is_inserted   = raw_is_inserted,
+.bdrv_media_changed = raw_media_changed,
 .bdrv_eject = raw_eject,
 .bdrv_lock_medium   = raw_lock_medium,
+
 .bdrv_ioctl = raw_ioctl,
 .bdrv_aio_ioctl = raw_aio_ioctl,
 
-- 
1.7.6




[Qemu-devel] [PATCH v2 43/45] nbd: Clean up use of block_int.h

2011-08-03 Thread Markus Armbruster

Signed-off-by: Markus Armbruster 
---
 block/nbd.c |1 +
 nbd.c   |1 +
 nbd.h   |2 --
 3 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/block/nbd.c b/block/nbd.c
index 7a52f62..2e365ac 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -28,6 +28,7 @@
 
 #include "qemu-common.h"
 #include "nbd.h"
+#include "block_int.h"
 #include "module.h"
 #include "qemu_socket.h"
 
diff --git a/nbd.c b/nbd.c
index e7a585d..6d81cfb 100644
--- a/nbd.c
+++ b/nbd.c
@@ -17,6 +17,7 @@
  */
 
 #include "nbd.h"
+#include "block.h"
 
 #include 
 #include 
diff --git a/nbd.h b/nbd.h
index b38d0d0..5f87a7d 100644
--- a/nbd.h
+++ b/nbd.h
@@ -23,8 +23,6 @@
 
 #include 
 
-#include "block_int.h"
-
 struct nbd_request {
 uint32_t magic;
 uint32_t type;
-- 
1.7.6




[Qemu-devel] [PATCH v2 18/45] block: Drop medium lock tracking, ask device models instead

2011-08-03 Thread Markus Armbruster
Requires new BlockDevOps member is_medium_locked().  Implement for IDE
and SCSI CD-ROMs.

Signed-off-by: Markus Armbruster 
---
 block.c|   16 +---
 block.h|8 +++-
 block_int.h|1 -
 blockdev.c |2 +-
 hw/ide/core.c  |6 ++
 hw/scsi-disk.c |   10 ++
 6 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/block.c b/block.c
index 73e0fd4..3a8a4e6 100644
--- a/block.c
+++ b/block.c
@@ -793,6 +793,14 @@ static void bdrv_dev_resize_cb(BlockDriverState *bs)
 }
 }
 
+bool bdrv_dev_is_medium_locked(BlockDriverState *bs)
+{
+if (bs->dev_ops && bs->dev_ops->is_medium_locked) {
+return bs->dev_ops->is_medium_locked(bs->dev_opaque);
+}
+return false;
+}
+
 /*
  * Run consistency checks on an image
  *
@@ -1854,7 +1862,7 @@ void bdrv_info(Monitor *mon, QObject **ret_data)
 bs_obj = qobject_from_jsonf("{ 'device': %s, 'type': 'unknown', "
 "'removable': %i, 'locked': %i }",
 bs->device_name, bs->removable,
-bs->locked);
+bdrv_dev_is_medium_locked(bs));
 
 if (bs->drv) {
 QObject *obj;
@@ -3025,11 +3033,6 @@ void bdrv_eject(BlockDriverState *bs, int eject_flag)
 }
 }
 
-int bdrv_is_locked(BlockDriverState *bs)
-{
-return bs->locked;
-}
-
 /**
  * Lock or unlock the media (if it is locked, the user won't be able
  * to eject it manually).
@@ -3040,7 +3043,6 @@ void bdrv_set_locked(BlockDriverState *bs, int locked)
 
 trace_bdrv_set_locked(bs, locked);
 
-bs->locked = locked;
 if (drv && drv->bdrv_set_locked) {
 drv->bdrv_set_locked(bs, locked);
 }
diff --git a/block.h b/block.h
index 3f33c8e..37d9048 100644
--- a/block.h
+++ b/block.h
@@ -37,6 +37,12 @@ typedef struct BlockDevOps {
  */
 void (*change_media_cb)(void *opaque);
 /*
+ * Is the virtual medium locked into the device?
+ * Device models should implement this only when device has such a
+ * lock.
+ */
+bool (*is_medium_locked)(void *opaque);
+/*
  * Runs when the size changed (e.g. monitor command block_resize)
  */
 void (*resize_cb)(void *opaque);
@@ -93,6 +99,7 @@ void bdrv_detach_dev(BlockDriverState *bs, void *dev);
 void *bdrv_get_attached_dev(BlockDriverState *bs);
 void bdrv_set_dev_ops(BlockDriverState *bs, const BlockDevOps *ops,
   void *opaque);
+bool bdrv_dev_is_medium_locked(BlockDriverState *bs);
 int bdrv_read(BlockDriverState *bs, int64_t sector_num,
   uint8_t *buf, int nb_sectors);
 int bdrv_write(BlockDriverState *bs, int64_t sector_num,
@@ -205,7 +212,6 @@ int bdrv_is_sg(BlockDriverState *bs);
 int bdrv_enable_write_cache(BlockDriverState *bs);
 int bdrv_is_inserted(BlockDriverState *bs);
 int bdrv_media_changed(BlockDriverState *bs);
-int bdrv_is_locked(BlockDriverState *bs);
 void bdrv_set_locked(BlockDriverState *bs, int locked);
 void bdrv_eject(BlockDriverState *bs, int eject_flag);
 void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size);
diff --git a/block_int.h b/block_int.h
index e0824ce..9eff892 100644
--- a/block_int.h
+++ b/block_int.h
@@ -155,7 +155,6 @@ struct BlockDriverState {
 int keep_read_only; /* if true, the media was requested to stay read only 
*/
 int open_flags; /* flags used to open the file, re-used for re-open */
 int removable; /* if true, the media can be removed */
-int locked;/* if true, the media cannot temporarily be ejected */
 int encrypted; /* if true, the media is encrypted */
 int valid_key; /* if true, a valid encryption key has been set */
 int sg;/* if true, the device is a /dev/sg* */
diff --git a/blockdev.c b/blockdev.c
index 40f061a..bb1f8c4 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -649,7 +649,7 @@ static int eject_device(Monitor *mon, BlockDriverState *bs, 
int force)
 qerror_report(QERR_DEVICE_NOT_REMOVABLE, bdrv_get_device_name(bs));
 return -1;
 }
-if (!force && bdrv_is_locked(bs)) {
+if (!force && bdrv_dev_is_medium_locked(bs)) {
 qerror_report(QERR_DEVICE_LOCKED, bdrv_get_device_name(bs));
 return -1;
 }
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 3c46176..5bcc857 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -1769,8 +1769,14 @@ void ide_bus_reset(IDEBus *bus)
 bus->dma->ops->reset(bus->dma);
 }
 
+static bool ide_cd_is_medium_locked(void *opaque)
+{
+return ((IDEState *)opaque)->tray_locked;
+}
+
 static const BlockDevOps ide_cd_block_ops = {
 .change_media_cb = ide_cd_change_cb,
+.is_medium_locked = ide_cd_is_medium_locked,
 };
 
 int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index d22a211..6f5ec0d 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1201,6 +1201,15 @@ static void scsi_destroy(SCSIDevice *dev)
 blo

[Qemu-devel] [PATCH v2 23/45] scsi-disk: Fix START_STOP to fail when it can't eject

2011-08-03 Thread Markus Armbruster
Don't fail when tray is already open.

Signed-off-by: Markus Armbruster 
---
 hw/scsi-bus.c  |   10 ++
 hw/scsi-disk.c |   15 +++
 hw/scsi.h  |4 
 3 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 0b0344c..1c5fe7f 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -441,6 +441,11 @@ const struct SCSISense sense_code_NO_MEDIUM = {
 .key = NOT_READY, .asc = 0x3a, .ascq = 0x00
 };
 
+/* LUN not ready, medium removal prevented */
+const struct SCSISense sense_code_MEDIUM_REMOVAL_PREVENTED_NR = {
+.key = NOT_READY, .asc = 0x53, .ascq = 0x00
+};
+
 /* Hardware error, internal target failure */
 const struct SCSISense sense_code_TARGET_FAILURE = {
 .key = HARDWARE_ERROR, .asc = 0x44, .ascq = 0x00
@@ -466,6 +471,11 @@ const struct SCSISense sense_code_LUN_NOT_SUPPORTED = {
 .key = ILLEGAL_REQUEST, .asc = 0x25, .ascq = 0x00
 };
 
+/* Illegal request, medium removal prevented */
+const struct SCSISense sense_code_MEDIUM_REMOVAL_PREVENTED_ILL = {
+.key = ILLEGAL_REQUEST, .asc = 0x53, .ascq = 0x00
+};
+
 /* Command aborted, I/O process terminated */
 const struct SCSISense sense_code_IO_ERROR = {
 .key = ABORTED_COMMAND, .asc = 0x00, .ascq = 0x06
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 79d7737..19a1843 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -828,7 +828,7 @@ static int scsi_disk_emulate_read_toc(SCSIRequest *req, 
uint8_t *outbuf)
 return toclen;
 }
 
-static void scsi_disk_emulate_start_stop(SCSIDiskReq *r)
+static int scsi_disk_emulate_start_stop(SCSIDiskReq *r)
 {
 SCSIRequest *req = &r->req;
 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
@@ -836,12 +836,17 @@ static void scsi_disk_emulate_start_stop(SCSIDiskReq *r)
 bool loej = req->cmd.buf[4] & 2;
 
 if (s->qdev.type == TYPE_ROM && loej) {
-if (!start && s->tray_locked) {
-return;
+if (!start && !s->tray_open && s->tray_locked) {
+scsi_command_complete(r, CHECK_CONDITION,
+  bdrv_is_inserted(s->bs)
+  ? SENSE_CODE(MEDIUM_REMOVAL_PREVENTED_ILL)
+  : SENSE_CODE(MEDIUM_REMOVAL_PREVENTED_NR));
+return -1;
 }
 bdrv_eject(s->bs, !start);
 s->tray_open = !start;
 }
+return 0;
 }
 
 static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf)
@@ -897,7 +902,9 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r, 
uint8_t *outbuf)
 goto illegal_request;
 break;
 case START_STOP:
-scsi_disk_emulate_start_stop(r);
+if (scsi_disk_emulate_start_stop(r) < 0) {
+return -1;
+}
 break;
 case ALLOW_MEDIUM_REMOVAL:
 s->tray_locked = req->cmd.buf[4] & 1;
diff --git a/hw/scsi.h b/hw/scsi.h
index 6b15bbc..63442c6 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -118,6 +118,8 @@ extern const struct SCSISense sense_code_NO_SENSE;
 extern const struct SCSISense sense_code_LUN_NOT_READY;
 /* LUN not ready, Medium not present */
 extern const struct SCSISense sense_code_NO_MEDIUM;
+/* LUN not readt, medium removal prevented */
+extern const struct SCSISense sense_code_MEDIUM_REMOVAL_PREVENTED_NR;
 /* Hardware error, internal target failure */
 extern const struct SCSISense sense_code_TARGET_FAILURE;
 /* Illegal request, invalid command operation code */
@@ -128,6 +130,8 @@ extern const struct SCSISense sense_code_LBA_OUT_OF_RANGE;
 extern const struct SCSISense sense_code_INVALID_FIELD;
 /* Illegal request, LUN not supported */
 extern const struct SCSISense sense_code_LUN_NOT_SUPPORTED;
+/* Illegal request, medium removal prevented */
+extern const struct SCSISense sense_code_MEDIUM_REMOVAL_PREVENTED_ILL;
 /* Command aborted, I/O process terminated */
 extern const struct SCSISense sense_code_IO_ERROR;
 /* Command aborted, I_T Nexus loss occurred */
-- 
1.7.6




  1   2   3   >