diff mbox

Add qword read/write support.

Message ID 1246482765-27205-2-git-send-email-turkal@google.com (mailing list archive)
State Superseded, archived
Headers show

Commit Message

Warren Turkal July 1, 2009, 9:12 p.m. UTC
Signed-off-by: Warren Turkal <turkal@google.com>
---
 lib/access.c |   15 +++++++++++++++
 lib/pci.h    |    2 ++
 lib/sysdep.h |   18 ++++++++++++++++++
 lib/types.h  |    5 +++--
 setpci.c     |   18 +++++++++++++++---
 5 files changed, 53 insertions(+), 5 deletions(-)

Comments

Martin Mareš July 1, 2009, 9:25 p.m. UTC | #1
Hello!

>  #elif defined(PCI_HAVE_STDINT_H) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
>  #include <stdint.h>
>  typedef uint8_t u8;
>  typedef uint16_t u16;
>  typedef uint32_t u32;
> +typedef uint64_t u64;
>  #else
>  typedef u_int8_t u8;
>  typedef u_int16_t u16;
>  typedef u_int32_t u32;
> +typedef u_int64_t u64;
>  #endif
>  
>  #ifdef PCI_HAVE_64BIT_ADDRESS
>  #include <limits.h>
>  #if ULONG_MAX > 0xffffffff
> -typedef unsigned long u64;
>  #define PCI_U64_FMT "l"
>  #else
> -typedef unsigned long long u64;
>  #define PCI_U64_FMT "ll"
>  #endif
>  #endif

This is unfortunately wrong -- you cannot use the "ll" modifier on uint64_t.

> +  const char * const formats[] = { NULL, " %02x", " %04x", NULL, " %08x", NULL, NULL, NULL, " %016llx"};
> +  const char * const mask_formats[] = { NULL, " %02x->(%02x:%02x)->%02x", " %04x->(%04x:%04x)->%04x", NULL, " %08x->(%08x:%08x)->%08x", NULL, NULL, NULL, " %016llx->(%016llx:%016llx)->%016llx"};

The same here.

				Have a nice fortnight
Warren Turkal July 1, 2009, 10:12 p.m. UTC | #2
On Wed, Jul 1, 2009 at 14:25, Martin Mares<mj@ucw.cz> wrote:
> Hello!
>
>>  #elif defined(PCI_HAVE_STDINT_H) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
>>  #include <stdint.h>
>>  typedef uint8_t u8;
>>  typedef uint16_t u16;
>>  typedef uint32_t u32;
>> +typedef uint64_t u64;
>>  #else
>>  typedef u_int8_t u8;
>>  typedef u_int16_t u16;
>>  typedef u_int32_t u32;
>> +typedef u_int64_t u64;
>>  #endif
>>
>>  #ifdef PCI_HAVE_64BIT_ADDRESS
>>  #include <limits.h>
>>  #if ULONG_MAX > 0xffffffff
>> -typedef unsigned long u64;
>>  #define PCI_U64_FMT "l"
>>  #else
>> -typedef unsigned long long u64;
>>  #define PCI_U64_FMT "ll"
>>  #endif
>>  #endif
>
> This is unfortunately wrong -- you cannot use the "ll" modifier on uint64_t.

Is that due to the fact that "long long" could be something other than
64-bit width?

Do you have a suggestion for fixing it? I usually am not working on
the C level. :)

>> +  const char * const formats[] = { NULL, " %02x", " %04x", NULL, " %08x", NULL, NULL, NULL, " %016llx"};
>> +  const char * const mask_formats[] = { NULL, " %02x->(%02x:%02x)->%02x", " %04x->(%04x:%04x)->%04x", NULL, " %08x->(%08x:%08x)->%08x", NULL, NULL, NULL, " %016llx->(%016llx:%016llx)->%016llx"};
>
> The same here.

Thanks for pointing these out,
wt
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Warren Turkal July 1, 2009, 11:47 p.m. UTC | #3
Someone just pointed out things PRIu64 to me. Would it be resonable to
use that instead of "ll"?

wt

On Wed, Jul 1, 2009 at 15:12, Warren Turkal<turkal@google.com> wrote:
> On Wed, Jul 1, 2009 at 14:25, Martin Mares<mj@ucw.cz> wrote:
>> Hello!
>>
>>>  #elif defined(PCI_HAVE_STDINT_H) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
>>>  #include <stdint.h>
>>>  typedef uint8_t u8;
>>>  typedef uint16_t u16;
>>>  typedef uint32_t u32;
>>> +typedef uint64_t u64;
>>>  #else
>>>  typedef u_int8_t u8;
>>>  typedef u_int16_t u16;
>>>  typedef u_int32_t u32;
>>> +typedef u_int64_t u64;
>>>  #endif
>>>
>>>  #ifdef PCI_HAVE_64BIT_ADDRESS
>>>  #include <limits.h>
>>>  #if ULONG_MAX > 0xffffffff
>>> -typedef unsigned long u64;
>>>  #define PCI_U64_FMT "l"
>>>  #else
>>> -typedef unsigned long long u64;
>>>  #define PCI_U64_FMT "ll"
>>>  #endif
>>>  #endif
>>
>> This is unfortunately wrong -- you cannot use the "ll" modifier on uint64_t.
>
> Is that due to the fact that "long long" could be something other than
> 64-bit width?
>
> Do you have a suggestion for fixing it? I usually am not working on
> the C level. :)
>
>>> +  const char * const formats[] = { NULL, " %02x", " %04x", NULL, " %08x", NULL, NULL, NULL, " %016llx"};
>>> +  const char * const mask_formats[] = { NULL, " %02x->(%02x:%02x)->%02x", " %04x->(%04x:%04x)->%04x", NULL, " %08x->(%08x:%08x)->%08x", NULL, NULL, NULL, " %016llx->(%016llx:%016llx)->%016llx"};
>>
>> The same here.
>
> Thanks for pointing these out,
> wt
>
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Rolf Eike Beer July 2, 2009, 5:42 a.m. UTC | #4
Warren Turkal wrote:
> Someone just pointed out things PRIu64 to me. Would it be resonable to
> use that instead of "ll"?

Then you need <inttypes.h> around which you don't have with fscking MSVC.

Eike
Warren Turkal July 2, 2009, 8:17 p.m. UTC | #5
PTAL at the "Take 4" patch. I think it addresses this concern in a
fairly decent way.

wt

On Wed, Jul 1, 2009 at 22:42, Rolf Eike Beer<eike-kernel@sf-tec.de> wrote:
> Warren Turkal wrote:
>> Someone just pointed out things PRIu64 to me. Would it be resonable to
>> use that instead of "ll"?
>
> Then you need <inttypes.h> around which you don't have with fscking MSVC.
>
> Eike
>
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/lib/access.c b/lib/access.c
index 691df39..b8addea 100644
--- a/lib/access.c
+++ b/lib/access.c
@@ -98,6 +98,14 @@  pci_read_long(struct pci_dev *d, int pos)
   return le32_to_cpu(buf);
 }
 
+u64
+pci_read_quad(struct pci_dev *d, int pos)
+{
+  u64 buf;
+  pci_read_data(d, &buf, pos, 8);
+  return le64_to_cpu(buf);
+}
+
 int
 pci_read_block(struct pci_dev *d, int pos, byte *buf, int len)
 {
@@ -141,6 +149,13 @@  pci_write_long(struct pci_dev *d, int pos, u32 data)
 }
 
 int
+pci_write_quad(struct pci_dev *d, int pos, u64 data)
+{
+  u64 buf = cpu_to_le64(data);
+  return pci_write_data(d, &buf, pos, 8);
+}
+
+int
 pci_write_block(struct pci_dev *d, int pos, byte *buf, int len)
 {
   if (pos < d->cache_len)
diff --git a/lib/pci.h b/lib/pci.h
index 7a5a6b8..71d673f 100644
--- a/lib/pci.h
+++ b/lib/pci.h
@@ -147,11 +147,13 @@  struct pci_dev {
 u8 pci_read_byte(struct pci_dev *, int pos) PCI_ABI; /* Access to configuration space */
 u16 pci_read_word(struct pci_dev *, int pos) PCI_ABI;
 u32 pci_read_long(struct pci_dev *, int pos) PCI_ABI;
+u64 pci_read_quad(struct pci_dev *, int pos) PCI_ABI;
 int pci_read_block(struct pci_dev *, int pos, u8 *buf, int len) PCI_ABI;
 int pci_read_vpd(struct pci_dev *d, int pos, u8 *buf, int len) PCI_ABI;
 int pci_write_byte(struct pci_dev *, int pos, u8 data) PCI_ABI;
 int pci_write_word(struct pci_dev *, int pos, u16 data) PCI_ABI;
 int pci_write_long(struct pci_dev *, int pos, u32 data) PCI_ABI;
+int pci_write_quad(struct pci_dev *, int pos, u64 data) PCI_ABI;
 int pci_write_block(struct pci_dev *, int pos, u8 *buf, int len) PCI_ABI;
 
 int pci_fill_info(struct pci_dev *, int flags) PCI_ABI; /* Fill in device information */
diff --git a/lib/sysdep.h b/lib/sysdep.h
index 2a25c93..4701884 100644
--- a/lib/sysdep.h
+++ b/lib/sysdep.h
@@ -27,8 +27,10 @@  typedef u16 word;
 #include <asm/byteorder.h>
 #define cpu_to_le16 __cpu_to_le16
 #define cpu_to_le32 __cpu_to_le32
+#define cpu_to_le64 __cpu_to_le64
 #define le16_to_cpu __le16_to_cpu
 #define le32_to_cpu __le32_to_cpu
+#define le64_to_cpu __le64_to_cpu
 
 #else
 
@@ -63,8 +65,10 @@  typedef u16 word;
 #if BYTE_ORDER == BIG_ENDIAN
 #define cpu_to_le16 swab16
 #define cpu_to_le32 swab32
+#define cpu_to_le64 swab64
 #define le16_to_cpu swab16
 #define le32_to_cpu swab32
+#define le64_to_cpu swab64
 
 static inline word swab16(word w)
 {
@@ -78,11 +82,25 @@  static inline u32 swab32(u32 w)
          ((w & 0x0000ff00) << 8)  |
          ((w & 0x000000ff) << 24);
 }
+
+static inline u64 swab64(u64 w)
+{
+  return ((w & 0xff00000000000000) >> 56) |
+         ((w & 0x00ff000000000000) >> 40) |
+         ((w & 0x0000ff0000000000) >> 24) |
+         ((w & 0x000000ff00000000) >> 8) |
+         ((w & 0x00000000ff000000) << 8) |
+         ((w & 0x0000000000ff0000) << 24) |
+         ((w & 0x000000000000ff00) << 40) |
+         ((w & 0x00000000000000ff) << 56);
+}
 #else
 #define cpu_to_le16(x) (x)
 #define cpu_to_le32(x) (x)
+#define cpu_to_le64(x) (x)
 #define le16_to_cpu(x) (x)
 #define le32_to_cpu(x) (x)
+#define le64_to_cpu(x) (x)
 #endif
 
 #endif
diff --git a/lib/types.h b/lib/types.h
index 3e0e5c3..39d5397 100644
--- a/lib/types.h
+++ b/lib/types.h
@@ -15,24 +15,25 @@ 
 typedef BYTE u8;
 typedef WORD u16;
 typedef DWORD u32;
+typedef QWORD u64;
 #elif defined(PCI_HAVE_STDINT_H) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
 #include <stdint.h>
 typedef uint8_t u8;
 typedef uint16_t u16;
 typedef uint32_t u32;
+typedef uint64_t u64;
 #else
 typedef u_int8_t u8;
 typedef u_int16_t u16;
 typedef u_int32_t u32;
+typedef u_int64_t u64;
 #endif
 
 #ifdef PCI_HAVE_64BIT_ADDRESS
 #include <limits.h>
 #if ULONG_MAX > 0xffffffff
-typedef unsigned long u64;
 #define PCI_U64_FMT "l"
 #else
-typedef unsigned long long u64;
 #define PCI_U64_FMT "ll"
 #endif
 #endif
diff --git a/setpci.c b/setpci.c
index 97740e8..8382b33 100644
--- a/setpci.c
+++ b/setpci.c
@@ -73,9 +73,10 @@  trace(const char *fmt, ...)
 static void
 exec_op(struct op *op, struct pci_dev *dev)
 {
-  const char * const formats[] = { NULL, " %02x", " %04x", NULL, " %08x" };
-  const char * const mask_formats[] = { NULL, " %02x->(%02x:%02x)->%02x", " %04x->(%04x:%04x)->%04x", NULL, " %08x->(%08x:%08x)->%08x" };
-  unsigned int i, x, y;
+  const char * const formats[] = { NULL, " %02x", " %04x", NULL, " %08x", NULL, NULL, NULL, " %016llx"};
+  const char * const mask_formats[] = { NULL, " %02x->(%02x:%02x)->%02x", " %04x->(%04x:%04x)->%04x", NULL, " %08x->(%08x:%08x)->%08x", NULL, NULL, NULL, " %016llx->(%016llx:%016llx)->%016llx"};
+  unsigned int i;
+  u64 x, y;
   int addr = 0;
   int width = op->width;
   char slot[16];
@@ -120,6 +121,9 @@  exec_op(struct op *op, struct pci_dev *dev)
 		case 2:
 		  y = pci_read_word(dev, addr);
 		  break;
+		case 8:
+		  y = pci_read_quad(dev, addr);
+		  break;
 		default:
 		  y = pci_read_long(dev, addr);
 		  break;
@@ -137,6 +141,9 @@  exec_op(struct op *op, struct pci_dev *dev)
 		case 2:
 		  pci_write_word(dev, addr, x);
 		  break;
+		case 8:
+		  pci_write_quad(dev, addr, x);
+		  break;
 		default:
 		  pci_write_long(dev, addr, x);
 		  break;
@@ -157,6 +164,9 @@  exec_op(struct op *op, struct pci_dev *dev)
 	case 2:
 	  x = pci_read_word(dev, addr);
 	  break;
+	case 8:
+	  x = pci_read_quad(dev, addr);
+	  break;
 	default:
 	  x = pci_read_long(dev, addr);
 	  break;
@@ -600,6 +610,8 @@  static void parse_op(char *c, struct pci_dev **selected_devices)
 	  op->width = 2; break;
 	case 'L':
 	  op->width = 4; break;
+	case 'Q':
+	  op->width = 8; break;
 	default:
 	  parse_err("Invalid width \"%c\"", *width);
 	}