eepromread: support for reading from /dev/eeprom
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
This commit is contained in:
		
							parent
							
								
									9a00643262
								
							
						
					
					
						commit
						13054fd168
					
				@ -16,9 +16,12 @@
 | 
			
		||||
 * 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");
 | 
			
		||||
 | 
			
		||||
@ -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.
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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 */
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user