Patchwork [16/23] ioport: register ranges by byte aligned addresses always

login
register
mail settings
Submitter Avi Kivity
Date July 25, 2011, 2:02 p.m.
Message ID <1311602584-23409-17-git-send-email-avi@redhat.com>
Download mbox | patch
Permalink /patch/106695/
State New
Headers show

Comments

Avi Kivity - July 25, 2011, 2:02 p.m.
The I/O port space is byte addressable, even for word and long accesses.

An example is the VMware svga card, which has long ports on offsets 0,
1, and 2.

Signed-off-by: Avi Kivity <avi@redhat.com>
---
 ioport.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
Anthony Liguori - July 25, 2011, 7:20 p.m.
On 07/25/2011 09:02 AM, Avi Kivity wrote:
> The I/O port space is byte addressable, even for word and long accesses.
>
> An example is the VMware svga card, which has long ports on offsets 0,
> 1, and 2.
>
> Signed-off-by: Avi Kivity<avi@redhat.com>

I've always thought this was odd but didn't know of a specific 
circumstance where it broke a device.

This was a big problem with the old API.  Devices don't register their 
interest in specific sizes.  They may ignore certain size accesses but 
that's a device specific behavior.

Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>

Regards,

Anthony Liguori

> ---
>   ioport.c |    4 ++--
>   1 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/ioport.c b/ioport.c
> index 0d2611d..a32483b 100644
> --- a/ioport.c
> +++ b/ioport.c
> @@ -146,7 +146,7 @@ int register_ioport_read(pio_addr_t start, int length, int size,
>           hw_error("register_ioport_read: invalid size");
>           return -1;
>       }
> -    for(i = start; i<  start + length; i += size) {
> +    for(i = start; i<  start + length; ++i) {
>           ioport_read_table[bsize][i] = func;
>           if (ioport_opaque[i] != NULL&&  ioport_opaque[i] != opaque)
>               hw_error("register_ioport_read: invalid opaque for address 0x%x",
> @@ -166,7 +166,7 @@ int register_ioport_write(pio_addr_t start, int length, int size,
>           hw_error("register_ioport_write: invalid size");
>           return -1;
>       }
> -    for(i = start; i<  start + length; i += size) {
> +    for(i = start; i<  start + length; ++i) {
>           ioport_write_table[bsize][i] = func;
>           if (ioport_opaque[i] != NULL&&  ioport_opaque[i] != opaque)
>               hw_error("register_ioport_write: invalid opaque for address 0x%x",
Avi Kivity - July 26, 2011, 10:59 a.m.
On 07/25/2011 10:20 PM, Anthony Liguori wrote:
> On 07/25/2011 09:02 AM, Avi Kivity wrote:
>> The I/O port space is byte addressable, even for word and long accesses.
>>
>> An example is the VMware svga card, which has long ports on offsets 0,
>> 1, and 2.
>>
>> Signed-off-by: Avi Kivity<avi@redhat.com>
>
> I've always thought this was odd but didn't know of a specific 
> circumstance where it broke a device.
>
> This was a big problem with the old API.  Devices don't register their 
> interest in specific sizes.  They may ignore certain size accesses but 
> that's a device specific behavior.

In fact there's on counterexample - 440FX consumes dword accesses on 
port cf8 but forwards byte and word accesses to the PCI bus.  This 
cannot be implemented with the current API (it requires the opaque to be 
equal for all word sizes).  The new API doesn't support it either; if we 
need to, we can re-issue the access but using the PCI address space 
instead of the root I/O address space.

(of course this is purely theoretical)

Patch

diff --git a/ioport.c b/ioport.c
index 0d2611d..a32483b 100644
--- a/ioport.c
+++ b/ioport.c
@@ -146,7 +146,7 @@  int register_ioport_read(pio_addr_t start, int length, int size,
         hw_error("register_ioport_read: invalid size");
         return -1;
     }
-    for(i = start; i < start + length; i += size) {
+    for(i = start; i < start + length; ++i) {
         ioport_read_table[bsize][i] = func;
         if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
             hw_error("register_ioport_read: invalid opaque for address 0x%x",
@@ -166,7 +166,7 @@  int register_ioport_write(pio_addr_t start, int length, int size,
         hw_error("register_ioport_write: invalid size");
         return -1;
     }
-    for(i = start; i < start + length; i += size) {
+    for(i = start; i < start + length; ++i) {
         ioport_write_table[bsize][i] = func;
         if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
             hw_error("register_ioport_write: invalid opaque for address 0x%x",