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..e41eae7 100644
--- a/lib/types.h
+++ b/lib/types.h
@@ -15,34 +15,37 @@
 typedef BYTE u8;
 typedef WORD u16;
 typedef DWORD u32;
+typedef QWORD u64;
+
+#ifdef PCI_HAVE_64BIT_ADDRESS
+#include <limits.h>
+#if ULONG_MAX > 0xffffffff
+#define PRIu64 "l"
+#else
+#define PRIu64 "ll"
+#endif
+#endif
+
 #elif defined(PCI_HAVE_STDINT_H) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
-#include <stdint.h>
+#include <inttypes.h>
 typedef uint8_t u8;
 typedef uint16_t u16;
 typedef uint32_t u32;
+typedef uint64_t u64;
 #else
+#include <inttypes.h>
 typedef u_int8_t u8;
 typedef u_int16_t u16;
 typedef u_int32_t u32;
-#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
+typedef u_int64_t u64;
 #endif
 
 #endif	/* PCI_HAVE_Uxx_TYPES */
 
 #ifdef PCI_HAVE_64BIT_ADDRESS
 typedef u64 pciaddr_t;
-#define PCIADDR_T_FMT "%08" PCI_U64_FMT "x"
-#define PCIADDR_PORT_FMT "%04" PCI_U64_FMT "x"
+#define PCIADDR_T_FMT "%08" PRIu64 "x"
+#define PCIADDR_PORT_FMT "%04" PRIu64 "x"
 #else
 typedef u32 pciaddr_t;
 #define PCIADDR_T_FMT "%08x"
diff --git a/setpci.c b/setpci.c
index 97740e8..30195b0 100644
--- a/setpci.c
+++ b/setpci.c
@@ -12,6 +12,7 @@
 #include <stdarg.h>
 #include <unistd.h>
 #include <errno.h>
+#include <inttypes.h>
 
 #define PCIUTILS_SETPCI
 #include "pciutils.h"
@@ -73,9 +74,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, " %016" PRIu64 "x"};
+  const char * const mask_formats[] = { NULL, " %02x->(%02x:%02x)->%02x", " %04x->(%04x:%04x)->%04x", NULL, " %08x->(%08x:%08x)->%08x", NULL, NULL, NULL, " %016" PRIu64 "x->(%016" PRIu64 "x:%016" PRIu64 "x)->%016" PRIu64 "x"};
+  unsigned int i;
+  u64 x, y;
   int addr = 0;
   int width = op->width;
   char slot[16];
@@ -120,6 +122,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 +142,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 +165,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 +611,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);
 	}
