diff options
author | khali <khali@7894878c-1315-0410-8ee3-d5d059ff63e0> | 2011-04-15 08:27:30 +0000 |
---|---|---|
committer | khali <khali@7894878c-1315-0410-8ee3-d5d059ff63e0> | 2011-04-15 08:27:30 +0000 |
commit | e0568889202115f390dc9e2d5048e7a3d93b711d (patch) | |
tree | fb99068a904edff635a1cd0568b5ccd65a59573f | |
parent | f1e7cde66d08c62e9473abffd5bc351f2e15be11 (diff) | |
download | lm-sensors-e0568889202115f390dc9e2d5048e7a3d93b711d.tar.gz |
isaset: Add support for word (16-bit) and long (32-bit) writes
Sometimes the hardware expects 16-bit or 32-bit writes rather than byte
writes. Add support to isaset so that the user can ask for such writes.
git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@5962 7894878c-1315-0410-8ee3-d5d059ff63e0
-rw-r--r-- | CHANGES | 1 | ||||
-rw-r--r-- | prog/dump/isaset.8 | 13 | ||||
-rw-r--r-- | prog/dump/isaset.c | 75 | ||||
-rw-r--r-- | prog/dump/util.c | 15 | ||||
-rw-r--r-- | prog/dump/util.h | 1 |
5 files changed, 69 insertions, 36 deletions
@@ -3,6 +3,7 @@ lm-sensors CHANGES file SVN HEAD isadump: Add support for word (16-bit) and long (32-bit) reads + isaset: Add support for word (16-bit) and long (32-bit) writes sensors-detect: Add AMD family 15h CPU detection Add detection of ADT7461A / NCT1008 Add detection of ITE IT8516E/F/G diff --git a/prog/dump/isaset.8 b/prog/dump/isaset.8 index 12071a22..e7bcd5db 100644 --- a/prog/dump/isaset.8 +++ b/prog/dump/isaset.8 @@ -1,10 +1,11 @@ -.TH ISASET 8 "May 2005" +.TH ISASET 8 "April 2011" .SH "NAME" isaset \- set ISA registers .SH SYNOPSIS .B isaset .RB [ -y ] +.RB [ -W | -L ] .I addrreg .I datareg .I address @@ -13,8 +14,10 @@ isaset \- set ISA registers #for I2C-like access .br .B isaset +.B -f .RB [ -y ] -.BI "-f " address +.RB [ -W | -L ] +.I address .I value .RI [ mask ] #for flat address space @@ -33,6 +36,12 @@ Disable interactive mode. By default, isaset will wait for a confirmation from the user before messing with the ISA bus. When this flag is used, it will perform the operation directly. This is mainly meant to be used in scripts. +.TP +.B -W +Perform a 16-bit write. +.TP +.B -L +Perform a 32-bit write. .SH OPTIONS (I2C-like access mode) Four options must be provided to isaset. \fIaddrreg\fR contains the diff --git a/prog/dump/isaset.c b/prog/dump/isaset.c index ceacbb59..1d1bdadc 100644 --- a/prog/dump/isaset.c +++ b/prog/dump/isaset.c @@ -2,7 +2,7 @@ isaset.c - isaset, a user-space program to write ISA registers Copyright (C) 2000 Frodo Looijaard <frodol@dds.nl>, and Mark D. Studebaker <mdsxyz123@yahoo.com> - Copyright (C) 2004,2007 Jean Delvare <khali@linux-fr.org> + Copyright (C) 2004-2011 Jean Delvare <khali@linux-fr.org> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -48,17 +48,22 @@ static void help(void) { fprintf(stderr, "Syntax for I2C-like access:\n" - " isaset [-y] ADDRREG DATAREG ADDRESS VALUE [MASK]\n" + " isaset [OPTIONS] ADDRREG DATAREG ADDRESS VALUE [MASK]\n" "Syntax for flat address space:\n" - " isaset [-y] -f ADDRESS VALUE [MASK]\n"); + " isaset -f [OPTIONS] ADDRESS VALUE [MASK]\n" + "Options:\n" + " -f Enable flat address space mode\n" + " -y Assume affirmative answer to all questions\n" + " -W Write a word (16-bit) value\n" + " -L Write a long (32-bit) value\n"); } int main(int argc, char *argv[]) { - int addrreg, datareg = 0, value, addr = 0, vmask = 0; - unsigned char res; + int addrreg, datareg = 0, addr = 0; + unsigned long value, vmask = 0, maxval = 0xff, res; int flags = 0; - int flat = 0, yes = 0; + int flat = 0, yes = 0, width = 1; char *end; /* handle (optional) flags first */ @@ -66,6 +71,8 @@ int main(int argc, char *argv[]) switch (argv[1+flags][1]) { case 'f': flat = 1; break; case 'y': yes = 1; break; + case 'W': width = 2; maxval = 0xffff; break; + case 'L': width = 4; maxval = 0xffffffff; break; default: fprintf(stderr, "Warning: Unsupported flag " "\"-%c\"!\n", argv[1+flags][1]); @@ -128,29 +135,30 @@ int main(int argc, char *argv[]) if (!flat) flags += 2; - value = strtol(argv[flags+2], &end, 0); + value = strtoul(argv[flags+2], &end, 0); if (*end) { fprintf(stderr, "Error: Invalid value!\n"); help(); exit(1); } - if (value < 0 || value > 0xff) { + if (value > maxval) { fprintf(stderr, "Error: Value out of range " - "(0x00-0xff)!\n"); + "(0x%0*u-%0*lu)!\n", width * 2, 0, width * 2, maxval); help(); exit(1); } if (flags+3 < argc) { - vmask = strtol(argv[flags+3], &end, 0); + vmask = strtoul(argv[flags+3], &end, 0); if (*end) { fprintf(stderr, "Error: Invalid mask!\n"); help(); exit(1); } - if (vmask < 0 || vmask > 0xff) { + if (vmask > maxval) { fprintf(stderr, "Error: Mask out of range " - "(0x00-0xff)!\n"); + "(0x%0*u-%0*lu)!\n", width * 2, 0, + width * 2, maxval); help(); exit(1); } @@ -167,13 +175,15 @@ int main(int argc, char *argv[]) "system crashes, data loss and worse!\n"); if (flat) - fprintf(stderr, "I will write value 0x%02x%s to address " - "0x%x.\n", value, vmask ? " (masked)" : "", - addrreg); + fprintf(stderr, + "I will write value 0x%0*lx%s to address " + "0x%x.\n", width * 2, value, + vmask ? " (masked)" : "", addrreg); else - fprintf(stderr, "I will write value 0x%02x%s to address " + fprintf(stderr, + "I will write value 0x%0*lx%s to address " "0x%02x of chip with address register 0x%x\n" - "and data register 0x%x.\n", + "and data register 0x%x.\n", width * 2, value, vmask ? " (masked)" : "", addr, addrreg, datareg); @@ -206,26 +216,22 @@ int main(int argc, char *argv[]) #endif if (vmask) { - int oldvalue; + unsigned long oldvalue; if (flat) { - oldvalue = inb(addrreg); + oldvalue = inx(addrreg, width); } else { outb(addr, addrreg); - oldvalue = inb(datareg); - } - - if (oldvalue < 0) { - fprintf(stderr, "Error: Failed to read old value\n"); - exit(1); + oldvalue = inx(datareg, width); } value = (value & vmask) | (oldvalue & ~vmask); if (!yes) { - fprintf(stderr, "Old value 0x%02x, write mask " - "0x%02x: Will write 0x%02x to %s " - "0x%02x\n", oldvalue, vmask, value, + fprintf(stderr, "Old value 0x%0*lx, write mask " + "0x%0*lx: Will write 0x%0*lx to %s " + "0x%02x\n", width * 2, oldvalue, + width * 2, vmask, width * 2, value, flat ? "address" : "register", flat ? addrreg : addr); @@ -241,20 +247,21 @@ int main(int argc, char *argv[]) /* do the real thing */ if (flat) { /* write */ - outb(value, addrreg); + outx(value, addrreg, width); /* readback */ - res = inb(addrreg); + res = inx(addrreg, width); } else { /* write */ outb(addr, addrreg); - outb(value, datareg); + outx(value, datareg, width); /* readback */ - res = inb(datareg); + res = inx(datareg, width); } if (res != value) { - fprintf(stderr, "Data mismatch, wrote 0x%02x, " - "read 0x%02x back.\n", value, res); + fprintf(stderr, "Data mismatch, wrote 0x%0*lx, " + "read 0x%0*lx back.\n", width * 2, value, + width * 2, res); } exit(0); diff --git a/prog/dump/util.c b/prog/dump/util.c index 31c7936b..676c3397 100644 --- a/prog/dump/util.c +++ b/prog/dump/util.c @@ -67,3 +67,18 @@ unsigned long inx(int addr, int width) return inb(addr); } } + +/* I/O write of specified size */ +void outx(unsigned long value, int addr, int width) +{ + switch (width) { + case 2: + outw(value, addr); + break; + case 4: + outl(value, addr); + break; + default: + outb(value, addr); + } +} diff --git a/prog/dump/util.h b/prog/dump/util.h index 9c1055bd..9a644ec2 100644 --- a/prog/dump/util.h +++ b/prog/dump/util.h @@ -13,5 +13,6 @@ extern int user_ack(int def); extern unsigned long inx(int addr, int width); +extern void outx(unsigned long value, int addr, int width); #endif /* _UTIL_H */ |