From patchwork Thu Jul 2 18:43:48 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Warren Turkal X-Patchwork-Id: 33752 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n62Ihusg017162 for ; Thu, 2 Jul 2009 18:43:57 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750938AbZGBSnw (ORCPT ); Thu, 2 Jul 2009 14:43:52 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1750949AbZGBSnw (ORCPT ); Thu, 2 Jul 2009 14:43:52 -0400 Received: from smtp-out.google.com ([216.239.33.17]:18209 "EHLO smtp-out.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750938AbZGBSnu (ORCPT ); Thu, 2 Jul 2009 14:43:50 -0400 Received: from zps76.corp.google.com (zps76.corp.google.com [172.25.146.76]) by smtp-out.google.com with ESMTP id n62IhplQ011488 for ; Thu, 2 Jul 2009 19:43:52 +0100 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=google.com; s=beta; t=1246560232; bh=1UCCTolIl+n7/hFrcaTDNZHCTEQ=; h=DomainKey-Signature:From:To:Cc:Subject:Date:Message-Id:X-Mailer: In-Reply-To:References; b=RcDvrl/9KUhgrIWKfjDOMm2xh2Q2DEUW1VjZsGdT JGPhWhXbvaCaWSPcQMTOPcsPgneuYV4kT4HNnpUSsccLgw== DomainKey-Signature: a=rsa-sha1; s=beta; d=google.com; c=nofws; q=dns; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=a937aAmuahjGh15Z2HLJ3xaMlWEqjlehJswvUD0tND/mFIu6p9pPjGVCKYTYdoryx 2PhpbA2cT22wJZ0G9fd/Q== Received: from localhost (braindead.mtv.corp.google.com [172.22.65.110]) by zps76.corp.google.com with ESMTP id n62IhmQY013783; Thu, 2 Jul 2009 11:43:48 -0700 Received: by localhost (Postfix, from userid 60405) id 801BB1B817F; Thu, 2 Jul 2009 11:43:48 -0700 (PDT) From: Warren Turkal To: linux-pci@vger.kernel.org Cc: Warren Turkal Subject: [PATCH] Add qword read/write support. Date: Thu, 2 Jul 2009 11:43:48 -0700 Message-Id: <1246560228-7852-2-git-send-email-turkal@google.com> X-Mailer: git-send-email 1.5.4.3 In-Reply-To: <1246560228-7852-1-git-send-email-turkal@google.com> References: <> <1246560228-7852-1-git-send-email-turkal@google.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Signed-off-by: Warren Turkal --- lib/access.c | 15 +++++++++++++++ lib/pci.h | 2 ++ lib/sysdep.h | 18 ++++++++++++++++++ lib/types.h | 31 +++++++++++++++++-------------- setpci.c | 19 ++++++++++++++++--- 5 files changed, 68 insertions(+), 17 deletions(-) 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 #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 +#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 +#include typedef uint8_t u8; typedef uint16_t u16; typedef uint32_t u32; +typedef uint64_t u64; #else +#include typedef u_int8_t u8; typedef u_int16_t u16; typedef u_int32_t u32; -#endif - -#ifdef PCI_HAVE_64BIT_ADDRESS -#include -#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 #include #include +#include #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); }