]> Zhao Yanbai Git Server - minix.git/commitdiff
eepromread: support for reading from /dev/eeprom 38/1138/1
authorThomas Cort <tcort@minix3.org>
Sun, 10 Nov 2013 17:06:27 +0000 (12:06 -0500)
committerThomas Cort <tcort@minix3.org>
Mon, 11 Nov 2013 15:14:03 +0000 (10:14 -0500)
eepromread could only read EEPROMs through the /dev/i2c interface.
Once the cat24c256 driver is started and claims/reserves the
device, it can no longer be read through the /dev/i2c interface.

This patch adds support for reading from EEPROMs through the
/dev/eeprom interface. For example, to read the on-board eeprom
on the BBB, one would do `eepromread -f /dev/eepromb1s50 -i`.

Change-Id: If08ce37231e593982eeb109bdd6d5458ad271108

commands/eepromread/board_info.c
commands/eepromread/eepromread.1
commands/eepromread/eepromread.c
commands/eepromread/eepromread.h

index 6521b4a641905d74818276601e967b631cbd7959..4f02c53ec0cf97d4a14c3e3c1d0858d117677295 100644 (file)
  * Attempt to read the board info from an eeprom on this board.
  */
 
-static int board_info_beaglebone(int fd, i2c_addr_t address, int flags);
-static int board_info_cape_a0(int fd, i2c_addr_t address, int flags);
-static int board_info_cape_a1(int fd, i2c_addr_t address, int flags);
+static int board_info_beaglebone(int fd, i2c_addr_t address, int flags,
+    enum device_types device_type);
+static int board_info_cape_a0(int fd, i2c_addr_t address, int flags,
+    enum device_types device_type);
+static int board_info_cape_a1(int fd, i2c_addr_t address, int flags,
+    enum device_types device_type);
 
 /* Memory Layout of the BeagleBone and BeagleBone Black EEPROM */
 typedef struct beaglebone_info
@@ -68,7 +71,8 @@ typedef struct cape_info_a1
 } cape_info_a1_t;
 
 static int
-board_info_beaglebone(int fd, i2c_addr_t address, int flags)
+board_info_beaglebone(int fd, i2c_addr_t address, int flags,
+    enum device_types device_type)
 {
        int r;
        int i, j;
@@ -76,7 +80,7 @@ board_info_beaglebone(int fd, i2c_addr_t address, int flags)
        beaglebone_info_t boneinfo;
 
        r = eeprom_read(fd, address, 0x0000, &boneinfo,
-           sizeof(beaglebone_info_t), flags);
+           sizeof(beaglebone_info_t), flags, device_type);
        if (r == -1) {
                fprintf(stderr, "Failed to read BeagleBone info r=%d\n", r);
                return -1;
@@ -102,7 +106,8 @@ board_info_beaglebone(int fd, i2c_addr_t address, int flags)
 }
 
 static int
-board_info_cape_a0(int fd, i2c_addr_t address, int flags)
+board_info_cape_a0(int fd, i2c_addr_t address, int flags,
+    enum device_types device_type)
 {
        int r;
        int i, j;
@@ -110,7 +115,7 @@ board_info_cape_a0(int fd, i2c_addr_t address, int flags)
        cape_info_a0_t capeinfo;
 
        r = eeprom_read(fd, address, 0x0000, &capeinfo,
-           sizeof(cape_info_a0_t), flags);
+           sizeof(cape_info_a0_t), flags, device_type);
        if (r == -1) {
                fprintf(stderr, "failed to read cape A0 info r=%d\n", r);
                return -1;
@@ -148,7 +153,8 @@ board_info_cape_a0(int fd, i2c_addr_t address, int flags)
 }
 
 static int
-board_info_cape_a1(int fd, i2c_addr_t address, int flags)
+board_info_cape_a1(int fd, i2c_addr_t address, int flags,
+    enum device_types device_type)
 {
        int r;
        int i, j;
@@ -156,7 +162,7 @@ board_info_cape_a1(int fd, i2c_addr_t address, int flags)
        cape_info_a1_t capeinfo;
 
        r = eeprom_read(fd, address, 0x0000, &capeinfo,
-           sizeof(cape_info_a1_t), flags);
+           sizeof(cape_info_a1_t), flags, device_type);
        if (r == -1) {
                fprintf(stderr, "failed to read cape A0 info r=%d\n", r);
                return -1;
@@ -194,12 +200,14 @@ board_info_cape_a1(int fd, i2c_addr_t address, int flags)
 }
 
 int
-board_info(int fd, i2c_addr_t address, int flags)
+board_info(int fd, i2c_addr_t address, int flags,
+    enum device_types device_type)
 {
        int r;
        uint8_t magic_number[6];
 
-       r = eeprom_read(fd, address, 0x0000, &magic_number, 6, flags);
+       r = eeprom_read(fd, address, 0x0000, &magic_number, 6, flags,
+           device_type);
        if (r == -1) {
                printf("%-16s: %s\n", "BOARD_NAME", "UNKNOWN");
                return 0;
@@ -211,11 +219,11 @@ board_info(int fd, i2c_addr_t address, int flags)
 
                /* Check if Cape Rev A0, Cape Rev A1, or on-board EEPROM */
                if (magic_number[4] == 'A' && magic_number[5] == '0') {
-                       board_info_cape_a0(fd, address, flags);
+                       board_info_cape_a0(fd, address, flags, device_type);
                } else if (magic_number[4] == 'A' && magic_number[5] == '1') {
-                       board_info_cape_a1(fd, address, flags);
+                       board_info_cape_a1(fd, address, flags, device_type);
                } else {
-                       board_info_beaglebone(fd, address, flags);
+                       board_info_beaglebone(fd, address, flags, device_type);
                }
        } else {
                printf("%-16s: %s\n", "BOARD_NAME", "UNKNOWN");
index 53115ac999b666fee87732e7abd5a56599d9b80b..7462aa431602350a8b3fa76858322b9c642ac304 100644 (file)
@@ -43,6 +43,10 @@ number is sent with the memory address. Use this when reading EDID.
 .TP 20
 .B eepromread -f /dev/i2c-3 -n
 # read the EDID info from the display on I2C bus 3 on the BeagleBoard-xM.
+.TP 20
+.B eepromread -f /dev/eepromb1s50 -i
+# access the EEPROM through the /dev/eeprom interface once the
+cat24c256 driver has been started.
 .SH DESCRIPTION
 .PP
 \fIeepromread\fR is a simple tool for viewing the contents of an EEPROM.
@@ -51,5 +55,5 @@ detect, \fIeepromread\fR can properly format each of the fields and display
 the information via the \fI-i\fR command line option.
 .SH NOTES
 If the \fIcat24c256\fR driver has claimed the EEPROM device that this
-program is attempting to read from, then this program will fail. Once
-a driver claims an I2C device, the driver has exclusive access.
+program is attempting to read from, then you must access it through
+the /dev/eeprom interface rather than the /dev/i2c interface.
index 4ecee6bdcb22a4d010fd53690a2e2d45308d2d4c..3c1f807da400b43cd2a9ebfcaa69005314011412 100644 (file)
@@ -15,8 +15,9 @@
 #include "eepromread.h"
 
 static int __eeprom_read128(int fd, i2c_addr_t addr, uint16_t memaddr,
-    void *buf, size_t buflen, int flags);
-static int eeprom_dump(int fd, i2c_addr_t addr, int flags);
+    void *buf, size_t buflen, int flags, enum device_types device_type);
+static int eeprom_dump(int fd, i2c_addr_t addr, int flags,
+    enum device_types device_type);
 
 #define DEFAULT_I2C_DEVICE "/dev/i2c-1"
 #define DEFAULT_I2C_ADDRESS 0x50
@@ -26,16 +27,11 @@ static int eeprom_dump(int fd, i2c_addr_t addr, int flags);
  * larger, so to read the whole EEPROM, the task is broken down into 128 byte
  * chunks in eeprom_read(). __eeprom_read128() does the actual ioctl() to do
  * the read.
- *
- * A future enhancement might be to add support for the /dev/eeprom interface
- * and if one way fails, fall back to the other. /dev/eeprom can fail if the
- * eeprom driver isn't running and /dev/i2c can fail if the eeprom driver
- * claimed the eeprom device.
  */
 
 static int
 __eeprom_read128(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
-    size_t buflen, int flags)
+    size_t buflen, int flags, enum device_types device_type)
 {
        int r;
        minix_i2c_ioctl_exec_t ioctl_exec;
@@ -46,6 +42,20 @@ __eeprom_read128(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
                return -1;
        }
 
+       /* if /dev/eeprom, then use read() */
+       if (device_type == EEPROM_DEVICE) {
+
+               off_t offset;
+
+               offset = lseek(fd, memaddr, SEEK_SET);
+               if (offset != memaddr) {
+                       return -1;
+               }
+
+               return read(fd, buf, buflen);
+
+       }
+       /* else /dev/i2c, use i2c_ioctl_exec_t interface */
        memset(&ioctl_exec, '\0', sizeof(minix_i2c_ioctl_exec_t));
 
        ioctl_exec.iie_op = I2C_OP_READ_WITH_STOP;
@@ -77,7 +87,7 @@ __eeprom_read128(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
 
 int
 eeprom_read(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
-    size_t buflen, int flags)
+    size_t buflen, int flags, enum device_types device_type)
 {
        int r;
        uint16_t i;
@@ -87,11 +97,11 @@ eeprom_read(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
                return -1;
        }
 
-
        for (i = 0; i < buflen; i += 128) {
 
                r = __eeprom_read128(fd, addr, memaddr + i, buf + i,
-                   ((buflen - i) < 128) ? (buflen - i) : 128, flags);
+                   ((buflen - i) < 128) ? (buflen - i) : 128, flags,
+                   device_type);
                if (r == -1) {
                        return -1;
                }
@@ -104,14 +114,14 @@ eeprom_read(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
  * Read 256 bytes and print it to the screen in HEX and ASCII.
  */
 static int
-eeprom_dump(int fd, i2c_addr_t addr, int flags)
+eeprom_dump(int fd, i2c_addr_t addr, int flags, enum device_types device_type)
 {
        int i, j, r;
        uint8_t buf[256];
 
        memset(buf, '\0', 256);
 
-       r = eeprom_read(fd, addr, 0x0000, buf, 256, flags);
+       r = eeprom_read(fd, addr, 0x0000, buf, 256, flags, device_type);
        if (r == -1) {
                return r;
        }
@@ -163,6 +173,7 @@ main(int argc, char *argv[])
        int ch, iflag = 0, read_flags = 0;
        char *device = DEFAULT_I2C_DEVICE;
        i2c_addr_t address = DEFAULT_I2C_ADDRESS;
+       enum device_types device_type = DEFAULT_DEVICE;
 
        setprogname(*argv);
 
@@ -185,6 +196,10 @@ main(int argc, char *argv[])
                }
        }
 
+       /* determine whether to use /dev/i2c or /dev/eeprom interface */
+       device_type =
+           strstr(device, "i2c") == NULL ? EEPROM_DEVICE : I2C_DEVICE;
+
        fd = open(device, O_RDWR);
        if (fd == -1) {
                fprintf(stderr, "open(): %s\n", strerror(errno));
@@ -192,15 +207,16 @@ main(int argc, char *argv[])
        }
 
        if (iflag == 1) {
-               r = board_info(fd, address, read_flags);
+               r = board_info(fd, address, read_flags, device_type);
                if (r == -1) {
                        fprintf(stderr, "board_info(): %s\n", strerror(errno));
                        return 1;
                }
        } else {
-               r = eeprom_dump(fd, address, read_flags);
+               r = eeprom_dump(fd, address, read_flags, device_type);
                if (r == -1) {
-                       fprintf(stderr, "eeprom_dump(): %s\n", strerror(errno));
+                       fprintf(stderr, "eeprom_dump(): %s\n",
+                           strerror(errno));
                        return 1;
                }
        }
@@ -213,4 +229,3 @@ main(int argc, char *argv[])
 
        return 0;
 }
-
index 733ba2cf3af1d252305a5430b42096895e3ccfba..60dadc3fe3135c6f9f9be45e73dac283d2ef8940 100644 (file)
@@ -1,8 +1,13 @@
 #ifndef __EEPROMREAD_H
 #define __EEPROMREAD_H
 
+enum device_types { I2C_DEVICE, EEPROM_DEVICE };
+#define DEFAULT_DEVICE I2C_DEVICE
+
 int eeprom_read(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
-                                               size_t buflen, int flags);
-int board_info(int fd, i2c_addr_t address, int flags);
+               size_t buflen, int flags, enum device_types device_type);
+
+int board_info(int fd, i2c_addr_t address, int flags,
+                                               enum device_types device_type);
 
 #endif /* __EEPROMREAD_H */