diff --git a/you-ass-bee-see/eeprog-0.7.6-tear12/24cXX.c b/you-ass-bee-see/eeprog-0.7.6-tear12/24cXX.c new file mode 100644 index 0000000..a8a352c --- /dev/null +++ b/you-ass-bee-see/eeprog-0.7.6-tear12/24cXX.c @@ -0,0 +1,203 @@ +/*************************************************************************** + copyright : (C) by 2003-2004 Stefano Barbato + email : stefano@codesink.org + + Copyright (C) 2011 by Kris Rusocki + - support for user-defined write cycle time + + $Id: 24cXX.c,v 1.5 2004/02/29 11:05:28 tat Exp $ + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "24cXX.h" + +static int i2c_write_1b(struct eeprom *e, __u8 buf) +{ + int r; + // we must simulate a plain I2C byte write with SMBus functions + r = i2c_smbus_write_byte(e->fd, buf); + if(r < 0) + fprintf(stderr, "Error i2c_write_1b: %s\n", strerror(errno)); + usleep(10); + return r; +} + +static int i2c_write_2b(struct eeprom *e, __u8 buf[2]) +{ + int r; + // we must simulate a plain I2C byte write with SMBus functions + r = i2c_smbus_write_byte_data(e->fd, buf[0], buf[1]); + if(r < 0) + fprintf(stderr, "Error i2c_write_2b: %s\n", strerror(errno)); + usleep(10); + return r; +} + +static int i2c_write_3b(struct eeprom *e, __u8 buf[3]) +{ + int r; + // we must simulate a plain I2C byte write with SMBus functions + // the __u16 data field will be byte swapped by the SMBus protocol + r = i2c_smbus_write_word_data(e->fd, buf[0], buf[2] << 8 | buf[1]); + if(r < 0) + fprintf(stderr, "Error i2c_write_3b: %s\n", strerror(errno)); + usleep(10); + return r; +} + + +#define CHECK_I2C_FUNC( var, label ) \ + do { if(0 == (var & label)) { \ + fprintf(stderr, "\nError: " \ + #label " function is required. Program halted.\n\n"); \ + exit(1); } \ + } while(0); + +int eeprom_open(char *dev_fqn, int addr, int type, int write_cycle_time, struct eeprom* e) +{ + int funcs, fd, r; + e->fd = e->addr = 0; + e->dev = 0; + + fd = open(dev_fqn, O_RDWR); + if(fd <= 0) + { + fprintf(stderr, "Error eeprom_open: %s\n", strerror(errno)); + return -1; + } + + // get funcs list + if((r = ioctl(fd, I2C_FUNCS, &funcs) < 0)) + { + fprintf(stderr, "Error eeprom_open: %s\n", strerror(errno)); + return -1; + } + + + // check for req funcs + CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_READ_BYTE ); + CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_WRITE_BYTE ); + CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_READ_BYTE_DATA ); + CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_WRITE_BYTE_DATA ); + CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_READ_WORD_DATA ); + CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_WRITE_WORD_DATA ); + + // set working device + if( ( r = ioctl(fd, I2C_SLAVE, addr)) < 0) + { + fprintf(stderr, "Error eeprom_open: %s\n", strerror(errno)); + return -1; + } + e->fd = fd; + e->addr = addr; + e->dev = dev_fqn; + e->type = type; + e->write_cycle_time = write_cycle_time; + return 0; +} + +int eeprom_close(struct eeprom *e) +{ + close(e->fd); + e->fd = -1; + e->dev = 0; + e->type = EEPROM_TYPE_UNKNOWN; + return 0; +} + +#if 0 +int eeprom_24c32_write_byte(struct eeprom *e, __u16 mem_addr, __u8 data) +{ + __u8 buf[3] = { (mem_addr >> 8) & 0x00ff, mem_addr & 0x00ff, data }; + return i2c_write_3b(e, buf); +} + + +int eeprom_24c32_read_current_byte(struct eeprom* e) +{ + ioctl(e->fd, BLKFLSBUF); // clear kernel read buffer + return i2c_smbus_read_byte(e->fd); +} + +int eeprom_24c32_read_byte(struct eeprom* e, __u16 mem_addr) +{ + int r; + ioctl(e->fd, BLKFLSBUF); // clear kernel read buffer + __u8 buf[2] = { (mem_addr >> 8) & 0x0ff, mem_addr & 0x0ff }; + r = i2c_write_2b(e, buf); + if (r < 0) + return r; + r = i2c_smbus_read_byte(e->fd); + return r; +} +#endif + + +int eeprom_read_current_byte(struct eeprom* e) +{ + ioctl(e->fd, BLKFLSBUF); // clear kernel read buffer + return i2c_smbus_read_byte(e->fd); +} + +int eeprom_read_byte(struct eeprom* e, __u16 mem_addr) +{ + int r; + ioctl(e->fd, BLKFLSBUF); // clear kernel read buffer + if(e->type == EEPROM_TYPE_8BIT_ADDR) + { + __u8 buf = mem_addr & 0x0ff; + r = i2c_write_1b(e, buf); + } else if(e->type == EEPROM_TYPE_16BIT_ADDR) { + __u8 buf[2] = { (mem_addr >> 8) & 0x0ff, mem_addr & 0x0ff }; + r = i2c_write_2b(e, buf); + } else { + fprintf(stderr, "ERR: unknown eeprom type\n"); + return -1; + } + if (r < 0) + return r; + r = i2c_smbus_read_byte(e->fd); + return r; +} + +int eeprom_write_byte(struct eeprom *e, __u16 mem_addr, __u8 data) +{ + int ret; + + if(e->type == EEPROM_TYPE_8BIT_ADDR) { + __u8 buf[2] = { mem_addr & 0x00ff, data }; + ret = i2c_write_2b(e, buf); + if (ret == 0 && e->write_cycle_time != 0) { + usleep(1000 * e->write_cycle_time); + } + return ret; + } else if(e->type == EEPROM_TYPE_16BIT_ADDR) { + __u8 buf[3] = + { (mem_addr >> 8) & 0x00ff, mem_addr & 0x00ff, data }; + ret = i2c_write_3b(e, buf); + if (ret == 0 && e->write_cycle_time != 0) { + usleep(1000 * e->write_cycle_time); + } + return ret; + } + fprintf(stderr, "ERR: unknown eeprom type\n"); + return -1; +} + diff --git a/you-ass-bee-see/eeprog-0.7.6-tear12/24cXX.h b/you-ass-bee-see/eeprog-0.7.6-tear12/24cXX.h new file mode 100644 index 0000000..93a1c63 --- /dev/null +++ b/you-ass-bee-see/eeprog-0.7.6-tear12/24cXX.h @@ -0,0 +1,62 @@ +/*************************************************************************** + copyright : (C) by 2003-2004 Stefano Barbato + email : stefano@codesink.org + + Copyright (C) 2011 by Kris Rusocki + - support for user-defined write cycle time + + $Id: 24cXX.h,v 1.6 2004/02/29 11:05:28 tat Exp $ + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef _24CXX_H_ +#define _24CXX_H_ +#include "i2c-dev.h" + +#define EEPROM_TYPE_UNKNOWN 0 +#define EEPROM_TYPE_8BIT_ADDR 1 +#define EEPROM_TYPE_16BIT_ADDR 2 + +struct eeprom +{ + char *dev; // device file i.e. /dev/i2c-N + int addr; // i2c address + int fd; // file descriptor + int type; // eeprom type + int write_cycle_time; +}; + +/* + * opens the eeprom device at [dev_fqn] (i.e. /dev/i2c-N) whose address is + * [addr] and set the eeprom_24c32 [e] + */ +int eeprom_open(char *dev_fqn, int addr, int type, int delay, struct eeprom*); +/* + * closees the eeprom device [e] + */ +int eeprom_close(struct eeprom *e); +/* + * read and returns the eeprom byte at memory address [mem_addr] + * Note: eeprom must have been selected by ioctl(fd,I2C_SLAVE,address) + */ +int eeprom_read_byte(struct eeprom* e, __u16 mem_addr); +/* + * read the current byte + * Note: eeprom must have been selected by ioctl(fd,I2C_SLAVE,address) + */ +int eeprom_read_current_byte(struct eeprom *e); +/* + * writes [data] at memory address [mem_addr] + * Note: eeprom must have been selected by ioctl(fd,I2C_SLAVE,address) + */ +int eeprom_write_byte(struct eeprom *e, __u16 mem_addr, __u8 data); + +#endif + diff --git a/you-ass-bee-see/eeprog-0.7.6-tear12/ChangeLog b/you-ass-bee-see/eeprog-0.7.6-tear12/ChangeLog new file mode 100644 index 0000000..deeb5fb --- /dev/null +++ b/you-ass-bee-see/eeprog-0.7.6-tear12/ChangeLog @@ -0,0 +1,21 @@ +29.02.2004, 0.7.6 + - better error handling + - read_from_eeprom bug fixed, thanks to Marek Michalkiewicz +02.12.2003, 0.7.5 + - help switch (-h) added + - 8bit addressing is now the default (safest) + - 16bit mode switch added (-16) + - quiet mode has been added (-q) +28.11.2003, 0.7.4 + - force switch added (-f) + - big warning will be displayed before reading/writing, user must + confirm + - i2c-dev.h has been (re)included into the distribution package because + user space functions have been removed from the original i2c-dev.h + by the dev team. +21.11.2003, 0.7.3 + - ChangeLog added + - WARNING file added + - support for 8bit addressing EEPROMs (-8 command line switch) + - better code documentation + - i2c-dev.h is no more included into the dist package. diff --git a/you-ass-bee-see/eeprog-0.7.6-tear12/Makefile b/you-ass-bee-see/eeprog-0.7.6-tear12/Makefile new file mode 100644 index 0000000..7583466 --- /dev/null +++ b/you-ass-bee-see/eeprog-0.7.6-tear12/Makefile @@ -0,0 +1,32 @@ +CFLAGS=-g -Wall -O2 +PREFIX=/usr/bin + +all: eeprog + +eeprog: eeprog.o 24cXX.o + +eeprog-static: eeprog.o 24cXX.o + $(CC) -static -o $@ $? + +clean: + $(RM) eeprog eeprog.o 24cXX.o + +distclean: clean + $(RM) *~ + $(RM) dist/*~ + +install: eeprog + install -ps eeprog $(PREFIX)/eeprog-tear + install -p dist/eeprog-spd-dump $(PREFIX) + install -p dist/eeprog-spd-flash $(PREFIX) + install -p dist/eeprog-spd-dump-g34 $(PREFIX) + install -p dist/eeprog-spd-flash-g34 $(PREFIX) + +uninstall: + $(RM) $(PREFIX)/eeprog-tear + $(RM) $(PREFIX)/eeprog-spd-dump + $(RM) $(PREFIX)/eeprog-spd-flash + $(RM) $(PREFIX)/eeprog-spd-dump-g34 + $(RM) $(PREFIX)/eeprog-spd-flash-g34 + +.PHONY: all clean distclean install uninstall diff --git a/you-ass-bee-see/eeprog-0.7.6-tear12/README b/you-ass-bee-see/eeprog-0.7.6-tear12/README new file mode 100644 index 0000000..d0be4ee --- /dev/null +++ b/you-ass-bee-see/eeprog-0.7.6-tear12/README @@ -0,0 +1,12 @@ +Important! See the WARNING file. + +eeprog reads and writes 24Cxx EEPROMs connected to I2C serial bus. + +It uses the SMBus protocol used by most of the recent chipsets. Don't forget to load +your i2c chipset and the i2c-dev drivers. + +Use -16 switch for EEPROMs larger than 24C16 (16bit addressing mode). + +Again, it's really important that you read the WARNING file. + +Type "make" to compile. diff --git a/you-ass-bee-see/eeprog-0.7.6-tear12/WARNING b/you-ass-bee-see/eeprog-0.7.6-tear12/WARNING new file mode 100644 index 0000000..1ad85bf --- /dev/null +++ b/you-ass-bee-see/eeprog-0.7.6-tear12/WARNING @@ -0,0 +1,20 @@ +Writing to unknown EEPROMs can break your computer. + +DIMMs contain an EEPROM and if you overwrite it, your computer +may not boot anymore. + +Reading 8bit EEPROM using 16bit addressing may actually WRITE +to the EEPROM. Be careful. + +The following chips use 8bit mode: + 24C01 + 24C02 + 24C04 + 24C08 + 24C16 + +Bigger ones use 16bit addressing so you must use -16. + +When in doubt, check data sheets. + +If you are not sure what you're doing, DO NOT use this tool. diff --git a/you-ass-bee-see/eeprog-0.7.6-tear12/dist/eeprog-spd-dump b/you-ass-bee-see/eeprog-0.7.6-tear12/dist/eeprog-spd-dump new file mode 120000 index 0000000..adf8068 --- /dev/null +++ b/you-ass-bee-see/eeprog-0.7.6-tear12/dist/eeprog-spd-dump @@ -0,0 +1 @@ +eeprog-spd-dump-0.11 \ No newline at end of file diff --git a/you-ass-bee-see/eeprog-0.7.6-tear12/dist/eeprog-spd-dump-0.11 b/you-ass-bee-see/eeprog-0.7.6-tear12/dist/eeprog-spd-dump-0.11 new file mode 100755 index 0000000..8f6f6e7 --- /dev/null +++ b/you-ass-bee-see/eeprog-0.7.6-tear12/dist/eeprog-spd-dump-0.11 @@ -0,0 +1,115 @@ +#!/bin/bash +# +# eeprog-spd-dump 0.11, SPD dump utility +# +# Copyright (c) 2010-2014 by Kris Rusocki +# Licensed under GPLv2 +# +# Boards supported: generic utility, YMMV +# + +check_for() +{ + [ -z $1 ] && return 1 + which $1 > /dev/null 2>&1 || return 1 + return 0 +} + +missing_tool() +{ + echo + echo ERROR: \'$1\' is not available on your system. Please install package providing \'$1\'. +} + +usage() +{ + echo Usage: + echo -e \\t"$0" \ + echo -e \\t\\tdumps SPD at I2C address 0x50 + \ + echo + echo -e \\t"$0" all + echo -e \\t\\tdumps all SPDs \(I2C addresses 0x50 through 0x57\) + exit 1 +} + +[ -z "$1" ] && usage + +INDEX=$1 + +if [ "$INDEX" = "all" ]; then + START=0 + END=7 +else + [ "$INDEX" != "$(echo $INDEX | tr -cd 0-9)" ] && INDEX=x + if [ "$INDEX" != $(($INDEX)) -o $(($INDEX)) -lt 0 -o $(($INDEX)) -gt 7 ]; then + echo \ must be a number \(0-7\) or \"all\" + exit 1 + fi + INDEX=$(($INDEX)) + START=$INDEX + END=$INDEX +fi + +DMIDECODE=dmidecode +MODPROBE=modprobe +EEPROG=eeprog-tear + +PREREQUISITES="id head $DMIDECODE $MODPROBE $EEPROG" + +ERRORS=0 +MISSING=1 +for i in $PREREQUISITES ; do + [ $MISSING -ne 0 ] && echo -n Checking for + echo -n \ $i + MISSING=0 + if ! check_for $i ; then + MISSING=1 + missing_tool $i + ERRORS=1 + fi +done +echo \ ...done. +if [ $ERRORS -ne 0 ]; then + exit 1 +fi + +if [ "$(id -ru)" != "0" ]; then + echo ERROR: need root privileges. + exit 1 +fi + +BOARD=$($DMIDECODE -s baseboard-product-name | head -1) + +if [ "$BOARD" = "H8QG6" -o "$BOARD" = "H8QGL" ]; then + $MODPROBE ipmi_si + if ls -d /sys/devices/platform/ipmi_bmc* > /dev/null 2>&1 ; then + echo ERROR: BMC\(s\) found. Please disable IPMI and try again. + exit 1 + fi +fi + +$MODPROBE -r eeprom 2> /dev/null +$MODPROBE i2c_dev + +[ -z "$EEPROG_DEV" ] && EEPROG_DEV=/dev/i2c-0 + +echo Processing ... +for i in $(seq $((0x50+$START)) $((0x50+$END))) ; do + IHEX=0x$(printf '%x' $i) + OUT=spd-$BOARD-$IHEX.bin + echo -n Reading DIMM at address $IHEX ... + $EEPROG -8 -f -r 0:256 $EEPROG_DEV $i > "$OUT" 2> /dev/null + RET=$? + if [ $RET -eq 2 ]; then + echo + echo ERROR: cannot access $EEPROG_DEV + exit 1 + fi + if [ $RET -ne 0 ]; then + echo + echo DIMM at address $IHEX not populated \(or encountered I2C error\) + rm "$OUT" + else + echo done. + fi +done diff --git a/you-ass-bee-see/eeprog-0.7.6-tear12/dist/eeprog-spd-dump-g34 b/you-ass-bee-see/eeprog-0.7.6-tear12/dist/eeprog-spd-dump-g34 new file mode 120000 index 0000000..e5d7559 --- /dev/null +++ b/you-ass-bee-see/eeprog-0.7.6-tear12/dist/eeprog-spd-dump-g34 @@ -0,0 +1 @@ +eeprog-spd-dump-g34-0.11 \ No newline at end of file diff --git a/you-ass-bee-see/eeprog-0.7.6-tear12/dist/eeprog-spd-dump-g34-0.11 b/you-ass-bee-see/eeprog-0.7.6-tear12/dist/eeprog-spd-dump-g34-0.11 new file mode 100755 index 0000000..32a9129 --- /dev/null +++ b/you-ass-bee-see/eeprog-0.7.6-tear12/dist/eeprog-spd-dump-g34-0.11 @@ -0,0 +1,200 @@ +#!/bin/bash +# +# eeprog-spd-dump-g34 0.11, SPD dump utility for G34 boards +# +# Copyright (c) 2010-2014 by Kris Rusocki +# Licensed under GPLv2 +# +# Boards supported: Tyan S8812, Supermicro H8QGi/H8QG6/H8QGL series +# + +SMBUS=/proc/bus/pci/00/14.0 + +read_smbus() +{ + local out + [ -z $1 ] && return 1 + [ -z $SMBUS ] && return 1 + [ $(($1 % 4)) -ne 0 ] && return 1 + out=0x$(dd bs=4 if=$SMBUS skip=$(($1/4)) count=1 status=noxfer 2> /dev/null | od -tx1 -An | tr -d ' ') + [ $? -ne 0 ] && return 1 + echo $out + return 0 +} + +write_smbus() +{ + [ -z $1 ] && return 1 + [ -z $2 ] && return 1 + [ -z $SMBUS ] && return 1 + [ $(($1 % 4)) -ne 0 ] && return 1 + echo -en $(printf '%08x' $2 | sed -e s/../\\\\x\&/g) | dd bs=4 of=$SMBUS conv=notrunc seek=$(($1/4)) status=noxfer 2> /dev/null + return $? +} + +dimm_bank() +{ + [ -z $1 ] && return 1 + [ -z "$BOARD" ] && return 1 + [ -z "$I2CSET" ] && return 1 + if [ "$BOARD" = "S8812" ]; then + $I2CSET -y 0 0x71 $(($1+4)) + return $? + fi + if [ "$BOARD" = "H8QG6" -o "$BOARD" = "H8QGL" ]; then + local GPIO + GPIO=$(read_smbus 0x50) + [ $? -ne 0 ] && return 1 + GPIO=$((($GPIO & 0xFFFFFCFF) | ($1 << 8))) + write_smbus 0x50 $GPIO + [ $? -ne 0 ] && return 1 + return 0 + fi + return 1 +} + +check_for() +{ + [ -z $1 ] && return 1 + which $1 > /dev/null 2>&1 || return 1 + return 0 +} + +missing_tool() +{ + echo + echo ERROR: \'$1\' is not available on your system. Please install package providing \'$1\'. +} + +usage() +{ + echo Usage: + echo -e \\t"$0" \ + echo -e \\t\\tdumps SPDs of all DIMM modules of given CPU + echo + echo -e \\t"$0" all + echo -e \\t\\tdumps SPDs of all DIMM modules + exit 1 +} + +[ -z "$1" ] && usage + +CPU=$1 + +CPUMASK=0 +if [ "$CPU" = "all" ]; then + CPUMASK=15 +else + [ "$CPU" != "$(echo $CPU | tr -cd 0-9)" ] && CPU=x + if [ "$CPU" != $(($CPU)) -o $(($CPU)) -lt 0 -o $(($CPU)) -gt 3 ]; then + echo \ must be a number \(0-3\) or \"all\" + exit 1 + fi + CPU=$(($CPU)) + CPUMASK=$((1 << $CPU)) +fi + +DMIDECODE=dmidecode +MODPROBE=modprobe +I2CSET=i2cset +EEPROG=eeprog-tear + +PREREQUISITES="id head sed od tr seq dd find awk lspci $DMIDECODE $MODPROBE $I2CSET $EEPROG" + +ERRORS=0 +MISSING=1 +for i in $PREREQUISITES ; do + [ $MISSING -ne 0 ] && echo -n Checking for + echo -n \ $i + MISSING=0 + if ! check_for $i ; then + MISSING=1 + missing_tool $i + ERRORS=1 + fi +done +echo \ ...done. +if [ $ERRORS -ne 0 ]; then + exit 1 +fi + +if [ "$(id -ru)" != "0" ]; then + echo ERROR: need root privileges. + exit 1 +fi + +BOARD=$($DMIDECODE -s baseboard-product-name | head -1) + +if [ "$BOARD" != "S8812" -a "$BOARD" != "H8QG6" -a "$BOARD" != "H8QGL" ]; then + echo ERROR: unsupported board: \""$BOARD"\" +fi + +if [ "$BOARD" = "H8QG6" -o "$BOARD" = "H8QGL" ]; then + $MODPROBE ipmi_si + if ls -d /sys/devices/platform/ipmi_bmc* > /dev/null 2>&1 ; then + echo ERROR: BMC\(s\) found. Please disable IPMI and try again. + exit 1 + fi +fi + +INCREMENT=1 +if [ "$BOARD" = "H8QGL" ]; then + INCREMENT=2 +fi + +$MODPROBE -r eeprom 2> /dev/null +$MODPROBE i2c_dev + +if [ -z "$EEPROG_DEV" ]; then + echo Discovering i2c bus ... + # EEPROG_DEV=$(ls /sys/bus/pci/devices/0000:00:14.0/i2c-*/i2c-dev 2> /dev/null) + # EEPROG_DEV=$(ls /sys/bus/pci/devices/0000:$(lspci -nm | awk '/ "1002" "4385" / { print $1 }')/i2c-*/i2c-dev 2> /dev/null) + EEPROG_DEV=$(find /sys/bus/pci/devices/0000:$(lspci -nm | awk '/ "1002" "4385" / { print $1 }')/i2c-*/i2c-dev -mindepth 1 -maxdepth 1 -printf '%f ' | (read -a A ; if [ ${#A[*]} -gt 1 ]; then echo WARNING: multiple matching I2C interfaces found: ${A[*]}. Using ${A[0]}. Override with EEPROG_DEV if necessary. >&2 ; fi ; echo ${A[0]})) +fi +if [ -z "$EEPROG_DEV" ]; then + echo WARNING: PCI device 1002:4385 not found or has no I2C busses! Using i2c-0. >&2 + EEPROG_DEV=i2c-0 +fi + +EEPROG_DEV=/dev/$EEPROG_DEV + +echo Using i2c bus at $EEPROG_DEV + +if [ "$BOARD" = "S8812" ]; then + # pre-set the Tyan + $I2CSET -y 0 0x72 0 +fi + +bit=1 +cpu=0 +while [ $cpu -lt 4 ]; do + if [ $(($bit & $CPUMASK)) -ne 0 ]; then + echo Processing CPU $cpu ... + dimm_bank $cpu + if [ $? -ne 0 ]; then + echo ERROR: dimm_bank $cpu failed + exit 1 + fi + for i in $(seq $((0x50)) $INCREMENT $((0x57))) ; do + IHEX=0x$(printf '%x' $i) + OUT=spd-$BOARD-CPU-$cpu-$IHEX.bin + echo -n Reading DIMM at address $IHEX ... + $EEPROG -8 -f -r 0:256 $EEPROG_DEV $i > "$OUT" 2> /dev/null + RET=$? + if [ $RET -eq 2 ]; then + echo + echo ERROR: cannot access $EEPROG_DEV + exit 1 + fi + if [ $RET -ne 0 ]; then + echo + echo DIMM at address $IHEX not populated \(or encountered I2C error\) + rm "$OUT" + else + echo done. + fi + done + fi + cpu=$(($cpu+1)) + bit=$(($bit << 1)) +done diff --git a/you-ass-bee-see/eeprog-0.7.6-tear12/dist/eeprog-spd-flash b/you-ass-bee-see/eeprog-0.7.6-tear12/dist/eeprog-spd-flash new file mode 120000 index 0000000..237e1cf --- /dev/null +++ b/you-ass-bee-see/eeprog-0.7.6-tear12/dist/eeprog-spd-flash @@ -0,0 +1 @@ +eeprog-spd-flash-0.11 \ No newline at end of file diff --git a/you-ass-bee-see/eeprog-0.7.6-tear12/dist/eeprog-spd-flash-0.11 b/you-ass-bee-see/eeprog-0.7.6-tear12/dist/eeprog-spd-flash-0.11 new file mode 100755 index 0000000..4f9f12c --- /dev/null +++ b/you-ass-bee-see/eeprog-0.7.6-tear12/dist/eeprog-spd-flash-0.11 @@ -0,0 +1,143 @@ +#!/bin/bash +# +# eeprog-spd-flash 0.11, SPD flash utility +# +# Copyright (c) 2010-2014 by Kris Rusocki +# Licensed under GPLv2 +# +# Boards supported: generic utility, YMMV +# + +check_for() +{ + [ -z $1 ] && return 1 + which $1 > /dev/null 2>&1 || return 1 + return 0 +} + +missing_tool() +{ + echo + echo ERROR: \'$1\' is not available on your system. Please install package providing \'$1\'. +} + +usage() +{ + echo Usage: + echo -e \\t"$0" all \ + echo -e \\t\\tflashes all SPDs \(I2C addresses 0x50 through 0x57\) with given file + echo + echo -e \\t"$0" \ \ + echo -e \\t\\tflashes SPD at address 0x50 + \ with given file + echo + echo -e \\t"$0" all + echo -e \\t\\tflashes SPDs with files, names of which follow the scheme: + echo -e \\t\\t\ \ spd-\-0x\.bin + echo -e \\t\\tin other words, it does reverse of eeprog-spd-dump + echo + exit 1 +} + +[ -z "$1" ] && usage + +INDEX=$1 +FILE=$2 + +if [ "$INDEX" = "all" ]; then + START=0 + END=7 +else + [ -z "$FILE" ] && usage + [ "$INDEX" != "$(echo $INDEX | tr -cd 0-9)" ] && INDEX=x + if [ "$INDEX" != $(($INDEX)) -o $(($INDEX)) -lt 0 -o $(($INDEX)) -gt 7 ]; then + echo \ must be a number \(0-7\) or \"all\" + exit 1 + fi + INDEX=$(($INDEX)) + START=$INDEX + END=$INDEX +fi + +DMIDECODE=dmidecode +MODPROBE=modprobe +EEPROG=eeprog-tear + +PREREQUISITES="id head $DMIDECODE $MODPROBE $EEPROG" + +ERRORS=0 +MISSING=1 +for i in $PREREQUISITES ; do + [ $MISSING -ne 0 ] && echo -n Checking for + echo -n \ $i + MISSING=0 + if ! check_for $i ; then + MISSING=1 + missing_tool $i + ERRORS=1 + fi +done +echo \ ...done. +if [ $ERRORS -ne 0 ]; then + exit 1 +fi + +if [ "$(id -ru)" != "0" ]; then + echo ERROR: need root privileges. + exit 1 +fi + +BOARD=$($DMIDECODE -s baseboard-product-name | head -1) + +if [ "$BOARD" = "H8QG6" -o "$BOARD" = "H8QGL" ]; then + $MODPROBE ipmi_si + if ls -d /sys/devices/platform/ipmi_bmc* > /dev/null 2>&1 ; then + echo ERROR: BMC\(s\) found. Please disable IPMI and try again. + exit 1 + fi +fi + +echo +echo Requested flashing of +echo -en \\t +[ "$INDEX" = "all" ] && echo -n all DIMMs || echo -n DIMM at index $INDEX +echo +echo with +echo -en \\t +[ -z "$FILE" ] && echo -n spd-$BOARD-\.bin files || echo -n "$FILE" +echo +echo +echo OK to proceed? Press ENTER to continue or Ctrl+C to exit. +read CONFIRM + +$MODPROBE -r eeprom 2> /dev/null +$MODPROBE i2c_dev + +[ -z "$EEPROG_DEV" ] && EEPROG_DEV=/dev/i2c-0 + +flashed=0 +echo Processing ... +for i in $(seq $((0x50+$START)) $((0x50+$END))) ; do + IHEX=0x$(printf '%x' $i) + [ -z "$FILE" ] && IN=spd-$BOARD-$IHEX.bin || IN=$FILE + if [ ! -r "$IN" ]; then + echo "$IN" does not exist or is not readable. Skipping DIMM at address $IHEX. + continue + fi + echo -n Writing "$IN" to DIMM at address $IHEX ... + $EEPROG -8 -f -w 0 -t 15 $EEPROG_DEV $i < "$IN" 2> /dev/null + RET=$? + if [ $RET -eq 2 ]; then + echo + echo ERROR: cannot access $EEPROG_DEV + exit 1 + fi + if [ $RET -ne 0 ]; then + echo + echo DIMM at address $IHEX not populated \(or encountered I2C error\) + else + flashed=$(($flashed+1)) + echo done. + fi +done +echo +echo Flashed $flashed DIMM\(s\). diff --git a/you-ass-bee-see/eeprog-0.7.6-tear12/dist/eeprog-spd-flash-g34 b/you-ass-bee-see/eeprog-0.7.6-tear12/dist/eeprog-spd-flash-g34 new file mode 120000 index 0000000..2eeb354 --- /dev/null +++ b/you-ass-bee-see/eeprog-0.7.6-tear12/dist/eeprog-spd-flash-g34 @@ -0,0 +1 @@ +eeprog-spd-flash-g34-0.11 \ No newline at end of file diff --git a/you-ass-bee-see/eeprog-0.7.6-tear12/dist/eeprog-spd-flash-g34-0.11 b/you-ass-bee-see/eeprog-0.7.6-tear12/dist/eeprog-spd-flash-g34-0.11 new file mode 100755 index 0000000..5bf2df4 --- /dev/null +++ b/you-ass-bee-see/eeprog-0.7.6-tear12/dist/eeprog-spd-flash-g34-0.11 @@ -0,0 +1,230 @@ +#!/bin/bash +# +# eeprog-spd-flash-g34 0.11, SPD flash utility for 4p G34 boards +# +# Copyright (c) 2010-2014 by Kris Rusocki +# Licensed under GPLv2 +# +# Boards supported: Tyan S8812, Supermicro H8QGi/H8QG6/H8QGL series +# + +SMBUS=/proc/bus/pci/00/14.0 + +read_smbus() +{ + local out + [ -z $1 ] && return 1 + [ -z $SMBUS ] && return 1 + [ $(($1 % 4)) -ne 0 ] && return 1 + out=0x$(dd bs=4 if=$SMBUS skip=$(($1/4)) count=1 status=noxfer 2> /dev/null | od -tx1 -An | tr -d ' ') + [ $? -ne 0 ] && return 1 + echo $out + return 0 +} + +write_smbus() +{ + [ -z $1 ] && return 1 + [ -z $2 ] && return 1 + [ -z $SMBUS ] && return 1 + [ $(($1 % 4)) -ne 0 ] && return 1 + echo -en $(printf '%08x' $2 | sed -e s/../\\\\x\&/g) | dd bs=4 of=$SMBUS conv=notrunc seek=$(($1/4)) status=noxfer 2> /dev/null + return $? +} + +dimm_bank() +{ + [ -z $1 ] && return 1 + [ -z "$BOARD" ] && return 1 + [ -z "$I2CSET" ] && return 1 + if [ "$BOARD" = "S8812" ]; then + $I2CSET -y 0 0x71 $(($1+4)) + return $? + fi + if [ "$BOARD" = "H8QG6" -o "$BOARD" = "H8QGL" ]; then + local GPIO + GPIO=$(read_smbus 0x50) + [ $? -ne 0 ] && return 1 + GPIO=$((($GPIO & 0xFFFFFCFF) | ($1 << 8))) + write_smbus 0x50 $GPIO + [ $? -ne 0 ] && return 1 + return 0 + fi + return 1 +} + +check_for() +{ + [ -z $1 ] && return 1 + which $1 > /dev/null 2>&1 || return 1 + return 0 +} + +missing_tool() +{ + echo + echo ERROR: \'$1\' is not available on your system. Please install package providing \'$1\'. +} + +usage() +{ + echo Usage: + echo -e \\t"$0" all \ + echo -e \\t\\tflashes SPDs of all DIMM modules with given file + echo + echo -e \\t"$0" \ \ + echo -e \\t\\tflashes SPDs of all DIMM modules of given CPU with given file + echo + echo -e \\t"$0" all + echo -e \\t\\tflashes SPDs with files, names of which follow the scheme: + echo -e \\t\\t\ \ spd-\-CPU-\-0x\.bin + echo -e \\t\\tin other words, it does reverse of eeprog-spd-dump-g34 + echo + echo -e \\t"$0" \ + echo -e \\t\\tsame as above but only flashes SPDs of DIMM modules of given CPU + echo + exit 1 +} + +[ -z "$1" ] && usage + +CPU=$1 +FILE=$2 + +CPUMASK=0 +if [ "$CPU" = "all" ]; then + CPUMASK=15 +else + [ "$CPU" != "$(echo $CPU | tr -cd 0-9)" ] && CPU=x + if [ "$CPU" != $(($CPU)) -o $(($CPU)) -lt 0 -o $(($CPU)) -gt 3 ]; then + echo \ must be a number \(0-3\) or \"all\" + exit 1 + fi + CPU=$(($CPU)) + CPUMASK=$((1 << $CPU)) +fi + +DMIDECODE=dmidecode +MODPROBE=modprobe +I2CSET=i2cset +EEPROG=eeprog-tear + +PREREQUISITES="id head sed od tr seq dd find awk lspci $DMIDECODE $MODPROBE $I2CSET $EEPROG" + +ERRORS=0 +MISSING=1 +for i in $PREREQUISITES ; do + [ $MISSING -ne 0 ] && echo -n Checking for + echo -n \ $i + MISSING=0 + if ! check_for $i ; then + MISSING=1 + missing_tool $i + ERRORS=1 + fi +done +echo \ ...done. +if [ $ERRORS -ne 0 ]; then + exit 1 +fi + +if [ "$(id -ru)" != "0" ]; then + echo ERROR: need root privileges. + exit 1 +fi + +BOARD=$($DMIDECODE -s baseboard-product-name | head -1) + +if [ "$BOARD" != "S8812" -a "$BOARD" != "H8QG6" -a "$BOARD" != "H8QGL" ]; then + echo ERROR: unsupported board: \""$BOARD"\" +fi + +if [ "$BOARD" = "H8QG6" -o "$BOARD" = "H8QGL" ]; then + $MODPROBE ipmi_si + if ls -d /sys/devices/platform/ipmi_bmc* > /dev/null 2>&1 ; then + echo ERROR: BMC\(s\) found. Please disable IPMI and try again. + exit 1 + fi +fi + +echo +echo Requested flashing of +echo -en \\t +[ "$CPU" = "all" ] && echo -n all DIMMs || echo -n CPU$CPU\'s DIMMs +echo +echo with +echo -en \\t +[ -z "$FILE" ] && echo -n spd-$BOARD-CPU-\-\.bin files || echo -n "$FILE" +echo +echo +echo OK to proceed? Press ENTER to continue or Ctrl+C to exit. +read CONFIRM + +INCREMENT=1 +if [ "$BOARD" = "H8QGL" ]; then + INCREMENT=2 +fi + +$MODPROBE -r eeprom 2> /dev/null +$MODPROBE i2c_dev + +if [ -z "$EEPROG_DEV" ]; then + echo Discovering i2c bus ... + # EEPROG_DEV=$(ls /sys/bus/pci/devices/0000:00:14.0/i2c-*/i2c-dev 2> /dev/null) + # EEPROG_DEV=$(ls /sys/bus/pci/devices/0000:$(lspci -nm | awk '/ "1002" "4385" / { print $1 }')/i2c-*/i2c-dev 2> /dev/null) + EEPROG_DEV=$(find /sys/bus/pci/devices/0000:$(lspci -nm | awk '/ "1002" "4385" / { print $1 }')/i2c-*/i2c-dev -mindepth 1 -maxdepth 1 -printf '%f ' | (read -a A ; if [ ${#A[*]} -gt 1 ]; then echo WARNING: multiple matching I2C interfaces found: ${A[*]}. Using ${A[0]}. Override with EEPROG_DEV if necessary. >&2 ; fi ; echo ${A[0]})) +fi +if [ -z "$EEPROG_DEV" ]; then + echo WARNING: PCI device 1002:4385 not found or has no I2C busses! Using i2c-0. >&2 + EEPROG_DEV=i2c-0 +fi + +EEPROG_DEV=/dev/$EEPROG_DEV + +echo Using i2c bus at $EEPROG_DEV + +if [ "$BOARD" = "S8812" ]; then + # pre-set the Tyan + $I2CSET -y 0 0x72 0 +fi + +bit=1 +cpu=0 +flashed=0 +while [ $cpu -lt 4 ]; do + if [ $(($bit & $CPUMASK)) -ne 0 ]; then + echo Processing CPU $cpu ... + dimm_bank $cpu + if [ $? -ne 0 ]; then + echo ERROR: dimm_bank $cpu failed + exit 1 + fi + for i in $(seq $((0x50)) $INCREMENT $((0x57))) ; do + IHEX=0x$(printf '%x' $i) + [ -z "$FILE" ] && IN=spd-$BOARD-CPU-$cpu-$IHEX.bin || IN=$FILE + if [ ! -r "$IN" ]; then + echo "$IN" does not exist or is not readable. Skipping DIMM at address $IHEX. + continue + fi + echo -n Writing "$IN" to DIMM at address $IHEX ... + $EEPROG -8 -f -w 0 -t 15 $EEPROG_DEV $i < "$IN" 2> /dev/null + RET=$? + if [ $RET -eq 2 ]; then + echo + echo ERROR: cannot access $EEPROG_DEV + exit 1 + fi + if [ $RET -ne 0 ]; then + echo + echo DIMM at address $IHEX not populated \(or encountered I2C error\) + else + flashed=$(($flashed+1)) + echo done. + fi + done + fi + cpu=$(($cpu+1)) + bit=$(($bit << 1)) +done +echo +echo Flashed $flashed DIMM\(s\). diff --git a/you-ass-bee-see/eeprog-0.7.6-tear12/eeprog.c b/you-ass-bee-see/eeprog-0.7.6-tear12/eeprog.c new file mode 100644 index 0000000..5a7692f --- /dev/null +++ b/you-ass-bee-see/eeprog-0.7.6-tear12/eeprog.c @@ -0,0 +1,386 @@ +/*************************************************************************** + copyright : (C) by 2003-2004 Stefano Barbato + email : stefano@codesink.org + + Copyright (C) 2011 by Kris Rusocki + - usage/strings cleanup + - misc cleanup: use "static" keyword where appropriate + - misc cleanup: have confirm_action() return void + - support custom input and output files + - support user-defined write cycle time + - ensure that stdin is a terminal when operating w/o -f + - do not allow reading data from a terminal w/o -f + - perform complete input validation before taking action + - use dedicated exit code when opening I2C device fails + + $Id: eeprog.c,v 1.28 2004/02/29 11:06:41 tat Exp $ + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "24cXX.h" + +#define VERSION "0.7.6-tear12" + +#define ENV_DEV "EEPROG_DEV" +#define ENV_I2C_ADDR "EEPROG_I2C_ADDR" + +static int g_quiet; + +#define usage_if(a) do { do_usage_if( a , __LINE__); } while(0); +static void do_usage_if(int b, int line) +{ +const static char *eeprog_usage = +"eeprog " VERSION ", a 24Cxx EEPROM reader/writer\n" +"Copyright (c) 2003-2004 by Stefano Barbato - All rights reserved.\n" +"Copyright (c) 2011 by Kris Rusocki - All rights reserved.\n" +"Usage:\n" +"\teeprog [-fqxd] [-16|-8] -r addr[:count] [-o file] /dev/i2c-N i2c-address\n" +"\teeprog [-fqd] [-16|-8] -w addr [-i file] [-t tWC] /dev/i2c-N i2c-address\n" +"\teeprog -h\n" +"\n" +" Address modes: \n" +" -8 Use 8bit address mode for 24c0x...24C16 [default]\n" +" -16 Use 16bit address mode for 24c32...24C256\n" +" Actions: \n" +" -r addr[:count] Read [count] (1 if omitted) bytes from [addr]\n" +" and print them to the standard output (or file\n" +" specified by -o)\n" +" -w addr Write stdin (or file specified by -i) starting\n" +" at address [addr] of the EEPROM\n" +" -h Print this help\n" +" Options: \n" +" -i file Read input from [file] (for use with -w)\n" +" -o file Write output to [file] (for use with -r)\n" +" -x Set hex output mode\n" +" -d Dummy mode, display what *would* have been done\n" +" -f Disable warnings and don't ask confirmation\n" +" -q Quiet mode\n" +" -t tWC Define chip's write cycle time to [tWC] miliseconds\n" +"\n" +"The following environment variables could be set instead of the command\n" +"line arguments:\n" +" EEPROG_DEV device name(/dev/i2c-N)\n" +" EEPROG_I2C_ADDR i2c-address\n" +"\n" +" Examples\n" +" 1- read 64 bytes from the EEPROM at address 0x54 on bus 0 starting\n" +" at address 123 (decimal)\n" +" eeprog /dev/i2c-0 0x54 -r 123:64\n" +" 2- prints the hex codes of the first 32 bytes read from bus 1 \n" +" at address 0x22\n" +" eeprog /dev/i2c-1 0x51 -x -r 0x22:0x20\n" +" 3- write the current timestamp at address 0x200 of the EEPROM on \n" +" bus 0 at address 0x33 \n" +" date | eeprog /dev/i2c-0 0x33 -w 0x200 -f\n"; + + if(!b) + return; + fprintf(stderr, "%s\n[line %d]\n", eeprog_usage, line); + exit(1); +} + + +#define die_if3(a, msg, code) do { do_die_if( a , msg, __LINE__, code); } while(0) +#define die_if(a, msg) die_if3(a, msg, 1) +static void do_die_if(int b, char* msg, int line, int exitcode) +{ + if(!b) + return; + fprintf(stderr, "Error at line %d: %s\n", line, msg); + //fprintf(stderr, " sysmsg: %s\n", strerror(errno)); + exit(exitcode); +} + +#define print_info(args...) do { if(!g_quiet) fprintf(stderr, args); } while(0) + +static int parse_arg(char *arg, int* paddr, int *psize) +{ + char *end; + unsigned int out_paddr, out_psize; + + if(arg[0] == '\0') + return -1; + + out_paddr = strtol(arg, &end, 0); + if(*end == '\0') + { + if(paddr) + *paddr = out_paddr; + return 1; + } + + if(*end != ':') + return -1; + + if(end[1] == '\0') + return -1; + + out_psize = strtol(end + 1, &end, 0); + if(*end == '\0') + { + if (paddr) + *paddr = out_paddr; + if (psize) + *psize = out_psize; + return 2; + } + + return -1; +} + +static void confirm_action() +{ + fprintf(stderr, + "\n" + "____________________________WARNING____________________________\n" + "Erroneously writing to a system EEPROM (like DIMM SPD modules)\n" + "may break your system. In such event, it will NOT boot anymore\n" + "and you may not be able to fix it.\n" + "\n" + "Reading from 8bit EEPROMs (like that in your DIMM) while using\n" + "-16 option can also UNEXPECTEDLY write to them so be sure to\n" + "use -16 option ONLY when required.\n" + "\n" + "Use -f to disable this warning message\n" + "\n" + "Press ENTER to continue or hit CTRL-C to exit\n" + "\n" + ); + + getchar(); +} + +static int read_from_eeprom(struct eeprom *e, FILE *fp, int addr, int size, int hex) +{ + int ch, i; + for(i = 0; i < size; ++i, ++addr) + { + die_if((ch = eeprom_read_byte(e, addr)) < 0, "read error"); + if(hex) + { + if( (i % 16) == 0 ) + fprintf(fp, "\n %.4x| ", addr); + else if( (i % 8) == 0 ) + fprintf(fp, " "); + fprintf(fp, "%.2x ", ch); + } else + putc(ch, fp); + } + if(hex) + fprintf(fp, "\n\n"); + fflush(fp); + return 0; +} + +static int write_to_eeprom(struct eeprom *e, FILE *fp, int addr) +{ + int c; + while((c = fgetc(fp)) != EOF) + { + print_info("."); + fflush(stdout); + die_if(eeprom_write_byte(e, addr++, c), "write error"); + } + print_info("\n\n"); + return 0; +} + +int main(int argc, char** argv) +{ + struct eeprom e; + int ret, op, i2c_addr, memaddr, size, want_hex, dummy, force, sixteen, write_cycle_time; + + char *input_file, *output_file; + FILE *input_fp, *output_fp; + + char *device, *arg = 0, *i2c_addr_s; + struct stat st; + int eeprom_type = 0; + + op = want_hex = dummy = force = sixteen = write_cycle_time = 0; + size = 1; // default + g_quiet = 0; + + input_file = output_file = NULL; + input_fp = stdin; + output_fp = stdout; + + while((ret = getopt(argc, argv, "1:8fr:qhw:xdt:i:o:")) != -1) + { + switch(ret) + { + case '1': + usage_if(*optarg != '6' || strlen(optarg) != 1); + die_if(eeprom_type, "EEPROM type switch (-8 or -16) used twice"); + eeprom_type = EEPROM_TYPE_16BIT_ADDR; + break; + case 'x': + want_hex++; + break; + case 'd': + dummy++; + break; + case '8': + die_if(eeprom_type, "EEPROM type switch (-8 or -16) used twice"); + eeprom_type = EEPROM_TYPE_8BIT_ADDR; + break; + case 'f': + force++; + break; + case 'q': + g_quiet++; + break; + case 'h': + usage_if(1); + break; + case 't': + die_if(parse_arg(optarg, &write_cycle_time, NULL) != 1 || write_cycle_time < 0, "-t -- invalid argument"); + break; + case 'i': + input_file = optarg; + break; + case 'o': + output_file = optarg; + break; + default: + die_if(op != 0, "Both read and write requested"); + arg = optarg; + op = ret; + } + } + if(!eeprom_type) + eeprom_type = EEPROM_TYPE_8BIT_ADDR; // default + + usage_if(op == 0); // no switches + // set device and i2c_addr reading from cmdline or env + device = i2c_addr_s = 0; + switch(argc - optind) + { + case 0: + device = getenv(ENV_DEV); + i2c_addr_s = getenv(ENV_I2C_ADDR); + break; + case 1: + if(stat(argv[optind], &st) != -1) + { + device = argv[optind]; + i2c_addr_s = getenv(ENV_I2C_ADDR); + } else { + device = getenv(ENV_DEV); + i2c_addr_s = argv[optind]; + } + break; + case 2: + device = argv[optind++]; + i2c_addr_s = argv[optind]; + break; + default: + usage_if(1); + } + usage_if(!device || !i2c_addr_s); + die_if(parse_arg(i2c_addr_s, &i2c_addr, NULL) != 1 || i2c_addr < 0, "I2C address -- invalid argument"); + ret = parse_arg(arg, &memaddr, &size); + die_if(op == 'r' && (ret == -1 || memaddr < 0 || size < 0), "-r -- invalid argument"); + die_if(op == 'w' && (ret != 1 || memaddr < 0), "-w -- invalid argument"); + + print_info("eeprog %s, a 24Cxx EEPROM reader/writer\n", VERSION); + print_info("Copyright (c) 2003-2004 by Stefano Barbato - All rights reserved.\n"); + print_info("Copyright (c) 2011 by Kris Rusocki - All rights reserved.\n"); + print_info(" Bus: %s, Address: 0x%02x, Mode: %dbit\n", + device, i2c_addr, + (eeprom_type == EEPROM_TYPE_8BIT_ADDR ? 8 : 16) ); + if(op == 'r') + { + print_info(" Operation: read %d bytes from offset %d, Output file: %s\n", + size, memaddr, output_file ? output_file : ""); + } else { + print_info(" Operation: write at offset %d, Input file: %s\n", + memaddr, input_file ? input_file : ""); + if(write_cycle_time != 0) + print_info(" Write cycle time: %d milliseconds\n", write_cycle_time); + } + + if(dummy) + { + fprintf(stderr, "Dummy mode selected, nothing done.\n"); + return 0; + } + + if (input_file) { + die_if((input_fp = fopen(input_file, "rb")) == NULL, + "unable to open input file " + "(check that the file exists and that it's readable)"); + } else { + input_file = ""; + } + + if (output_file) { + die_if((output_fp = fopen(output_file, "wb")) == NULL, + "unable to create output file " + "(check that you have permissions to write the file)"); + } else { + output_file = ""; + } + + die_if3(eeprom_open(device, i2c_addr, eeprom_type, write_cycle_time, &e) < 0, + "unable to open eeprom device file " + "(check that the file exists and that it's readable)", + 2); + switch(op) + { + case 'r': + if(force == 0) { + /* Confirmation must come from a terminal */ + die_if(isatty(0) == 0, + "stdin is not a terminal" + ); + confirm_action(); + } + print_info(" Reading %d bytes from 0x%x\n", size, memaddr); + read_from_eeprom(&e, output_fp, memaddr, size, want_hex); + break; + case 'w': + if(force == 0) { + /* Don't read data from a terminal */ + die_if(isatty(fileno(input_fp)) == 1, + "refusing to read data from a terminal\n" + "\n" + "Use -i to provide input file or -f to force." + ); + + /* Confirmation must come from a terminal */ + die_if(isatty(0) == 0, + "stdin is not a terminal" + "\n" + "Use -f to force." + ); + confirm_action(); + } + print_info(" Writing %s starting at address 0x%x\n", + input_file, memaddr); + write_to_eeprom(&e, input_fp, memaddr); + break; + default: + usage_if(1); + exit(1); + } + eeprom_close(&e); + + return 0; +} diff --git a/you-ass-bee-see/eeprog-0.7.6-tear12/i2c-dev.h b/you-ass-bee-see/eeprog-0.7.6-tear12/i2c-dev.h new file mode 100644 index 0000000..415ab45 --- /dev/null +++ b/you-ass-bee-see/eeprog-0.7.6-tear12/i2c-dev.h @@ -0,0 +1,361 @@ +/* + i2c-dev.h - i2c-bus driver, char device interface + + Copyright (C) 1995-97 Simon G. Vogl + Copyright (C) 1998-99 Frodo Looijaard + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* $Id: i2c-dev.h,v 1.4 2003/11/27 23:08:06 tat Exp $ */ + +#ifndef LIB_I2CDEV_H +#define LIB_I2CDEV_H + +#include +#include + + +/* -- i2c.h -- */ + + +/* + * I2C Message - used for pure i2c transaction, also from /dev interface + */ +struct i2c_msg { + __u16 addr; /* slave address */ + unsigned short flags; +#define I2C_M_TEN 0x10 /* we have a ten bit chip address */ +#define I2C_M_RD 0x01 +#define I2C_M_NOSTART 0x4000 +#define I2C_M_REV_DIR_ADDR 0x2000 +#define I2C_M_IGNORE_NAK 0x1000 +#define I2C_M_NO_RD_ACK 0x0800 + short len; /* msg length */ + char *buf; /* pointer to msg data */ + int err; + short done; +}; + +/* To determine what functionality is present */ + +#define I2C_FUNC_I2C 0x00000001 +#define I2C_FUNC_10BIT_ADDR 0x00000002 +#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */ +#define I2C_FUNC_SMBUS_HWPEC_CALC 0x00000008 /* SMBus 2.0 */ +#define I2C_FUNC_SMBUS_READ_WORD_DATA_PEC 0x00000800 /* SMBus 2.0 */ +#define I2C_FUNC_SMBUS_WRITE_WORD_DATA_PEC 0x00001000 /* SMBus 2.0 */ +#define I2C_FUNC_SMBUS_PROC_CALL_PEC 0x00002000 /* SMBus 2.0 */ +#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL_PEC 0x00004000 /* SMBus 2.0 */ +#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */ +#define I2C_FUNC_SMBUS_QUICK 0x00010000 +#define I2C_FUNC_SMBUS_READ_BYTE 0x00020000 +#define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000 +#define I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000 +#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000 +#define I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000 +#define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000 +#define I2C_FUNC_SMBUS_PROC_CALL 0x00800000 +#define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000 +#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000 +#define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */ +#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */ +#define I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 0x10000000 /* I2C-like block xfer */ +#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2 0x20000000 /* w/ 2-byte reg. addr. */ +#define I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC 0x40000000 /* SMBus 2.0 */ +#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC 0x80000000 /* SMBus 2.0 */ + +#define I2C_FUNC_SMBUS_BYTE I2C_FUNC_SMBUS_READ_BYTE | \ + I2C_FUNC_SMBUS_WRITE_BYTE +#define I2C_FUNC_SMBUS_BYTE_DATA I2C_FUNC_SMBUS_READ_BYTE_DATA | \ + I2C_FUNC_SMBUS_WRITE_BYTE_DATA +#define I2C_FUNC_SMBUS_WORD_DATA I2C_FUNC_SMBUS_READ_WORD_DATA | \ + I2C_FUNC_SMBUS_WRITE_WORD_DATA +#define I2C_FUNC_SMBUS_BLOCK_DATA I2C_FUNC_SMBUS_READ_BLOCK_DATA | \ + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA +#define I2C_FUNC_SMBUS_I2C_BLOCK I2C_FUNC_SMBUS_READ_I2C_BLOCK | \ + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK +#define I2C_FUNC_SMBUS_I2C_BLOCK_2 I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 | \ + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2 +#define I2C_FUNC_SMBUS_BLOCK_DATA_PEC I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC | \ + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC +#define I2C_FUNC_SMBUS_WORD_DATA_PEC I2C_FUNC_SMBUS_READ_WORD_DATA_PEC | \ + I2C_FUNC_SMBUS_WRITE_WORD_DATA_PEC + +#define I2C_FUNC_SMBUS_READ_BYTE_PEC I2C_FUNC_SMBUS_READ_BYTE_DATA +#define I2C_FUNC_SMBUS_WRITE_BYTE_PEC I2C_FUNC_SMBUS_WRITE_BYTE_DATA +#define I2C_FUNC_SMBUS_READ_BYTE_DATA_PEC I2C_FUNC_SMBUS_READ_WORD_DATA +#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA_PEC I2C_FUNC_SMBUS_WRITE_WORD_DATA +#define I2C_FUNC_SMBUS_BYTE_PEC I2C_FUNC_SMBUS_BYTE_DATA +#define I2C_FUNC_SMBUS_BYTE_DATA_PEC I2C_FUNC_SMBUS_WORD_DATA + +#define I2C_FUNC_SMBUS_EMUL I2C_FUNC_SMBUS_QUICK | \ + I2C_FUNC_SMBUS_BYTE | \ + I2C_FUNC_SMBUS_BYTE_DATA | \ + I2C_FUNC_SMBUS_WORD_DATA | \ + I2C_FUNC_SMBUS_PROC_CALL | \ + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \ + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC | \ + I2C_FUNC_SMBUS_I2C_BLOCK + +/* + * Data for SMBus Messages + */ +#define I2C_SMBUS_BLOCK_MAX 32 /* As specified in SMBus standard */ +#define I2C_SMBUS_I2C_BLOCK_MAX 32 /* Not specified but we use same structure */ +union i2c_smbus_data { + __u8 byte; + __u16 word; + __u8 block[I2C_SMBUS_BLOCK_MAX + 3]; /* block[0] is used for length */ + /* one more for read length in block process call */ + /* and one more for PEC */ +}; + +/* smbus_access read or write markers */ +#define I2C_SMBUS_READ 1 +#define I2C_SMBUS_WRITE 0 + +/* SMBus transaction types (size parameter in the above functions) + Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */ +#define I2C_SMBUS_QUICK 0 +#define I2C_SMBUS_BYTE 1 +#define I2C_SMBUS_BYTE_DATA 2 +#define I2C_SMBUS_WORD_DATA 3 +#define I2C_SMBUS_PROC_CALL 4 +#define I2C_SMBUS_BLOCK_DATA 5 +#define I2C_SMBUS_I2C_BLOCK_DATA 6 +#define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */ +#define I2C_SMBUS_BLOCK_DATA_PEC 8 /* SMBus 2.0 */ +#define I2C_SMBUS_PROC_CALL_PEC 9 /* SMBus 2.0 */ +#define I2C_SMBUS_BLOCK_PROC_CALL_PEC 10 /* SMBus 2.0 */ +#define I2C_SMBUS_WORD_DATA_PEC 11 /* SMBus 2.0 */ + + +/* ----- commands for the ioctl like i2c_command call: + * note that additional calls are defined in the algorithm and hw + * dependent layers - these can be listed here, or see the + * corresponding header files. + */ + /* -> bit-adapter specific ioctls */ +#define I2C_RETRIES 0x0701 /* number of times a device address */ + /* should be polled when not */ + /* acknowledging */ +#define I2C_TIMEOUT 0x0702 /* set timeout - call with int */ + + +/* this is for i2c-dev.c */ +#define I2C_SLAVE 0x0703 /* Change slave address */ + /* Attn.: Slave address is 7 or 10 bits */ +#define I2C_SLAVE_FORCE 0x0706 /* Change slave address */ + /* Attn.: Slave address is 7 or 10 bits */ + /* This changes the address, even if it */ + /* is already taken! */ +#define I2C_TENBIT 0x0704 /* 0 for 7 bit addrs, != 0 for 10 bit */ + +#define I2C_FUNCS 0x0705 /* Get the adapter functionality */ +#define I2C_RDWR 0x0707 /* Combined R/W transfer (one stop only)*/ +#define I2C_PEC 0x0708 /* != 0 for SMBus PEC */ +#if 0 +#define I2C_ACK_TEST 0x0710 /* See if a slave is at a specific address */ +#endif + +#define I2C_SMBUS 0x0720 /* SMBus-level access */ + +/* -- i2c.h -- */ + + +/* Note: 10-bit addresses are NOT supported! */ + +/* This is the structure as used in the I2C_SMBUS ioctl call */ +struct i2c_smbus_ioctl_data { + char read_write; + __u8 command; + int size; + union i2c_smbus_data *data; +}; + +/* This is the structure as used in the I2C_RDWR ioctl call */ +struct i2c_rdwr_ioctl_data { + struct i2c_msg *msgs; /* pointers to i2c_msgs */ + int nmsgs; /* number of i2c_msgs */ +}; + + +static inline __s32 i2c_smbus_access(int file, char read_write, __u8 command, + int size, union i2c_smbus_data *data) +{ + struct i2c_smbus_ioctl_data args; + + args.read_write = read_write; + args.command = command; + args.size = size; + args.data = data; + return ioctl(file,I2C_SMBUS,&args); +} + + +static inline __s32 i2c_smbus_write_quick(int file, __u8 value) +{ + return i2c_smbus_access(file,value,0,I2C_SMBUS_QUICK,NULL); +} + +static inline __s32 i2c_smbus_read_byte(int file) +{ + union i2c_smbus_data data; + if (i2c_smbus_access(file,I2C_SMBUS_READ,0,I2C_SMBUS_BYTE,&data)) + return -1; + else + return 0x0FF & data.byte; +} + +static inline __s32 i2c_smbus_write_byte(int file, __u8 value) +{ + return i2c_smbus_access(file,I2C_SMBUS_WRITE,value, + I2C_SMBUS_BYTE,NULL); +} + +static inline __s32 i2c_smbus_read_byte_data(int file, __u8 command) +{ + union i2c_smbus_data data; + if (i2c_smbus_access(file,I2C_SMBUS_READ,command, + I2C_SMBUS_BYTE_DATA,&data)) + return -1; + else + return 0x0FF & data.byte; +} + +static inline __s32 i2c_smbus_write_byte_data(int file, __u8 command, + __u8 value) +{ + union i2c_smbus_data data; + data.byte = value; + return i2c_smbus_access(file,I2C_SMBUS_WRITE,command, + I2C_SMBUS_BYTE_DATA, &data); +} + +static inline __s32 i2c_smbus_read_word_data(int file, __u8 command) +{ + union i2c_smbus_data data; + if (i2c_smbus_access(file,I2C_SMBUS_READ,command, + I2C_SMBUS_WORD_DATA,&data)) + return -1; + else + return 0x0FFFF & data.word; +} + +static inline __s32 i2c_smbus_write_word_data(int file, __u8 command, + __u16 value) +{ + union i2c_smbus_data data; + data.word = value; + return i2c_smbus_access(file,I2C_SMBUS_WRITE,command, + I2C_SMBUS_WORD_DATA, &data); +} + +static inline __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value) +{ + union i2c_smbus_data data; + data.word = value; + if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command, + I2C_SMBUS_PROC_CALL,&data)) + return -1; + else + return 0x0FFFF & data.word; +} + + +/* Returns the number of read bytes */ +static inline __s32 i2c_smbus_read_block_data(int file, __u8 command, + __u8 *values) +{ + union i2c_smbus_data data; + int i; + if (i2c_smbus_access(file,I2C_SMBUS_READ,command, + I2C_SMBUS_BLOCK_DATA,&data)) + return -1; + else { + for (i = 1; i <= data.block[0]; i++) + values[i-1] = data.block[i]; + return data.block[0]; + } +} + +static inline __s32 i2c_smbus_write_block_data(int file, __u8 command, + __u8 length, __u8 *values) +{ + union i2c_smbus_data data; + int i; + if (length > 32) + length = 32; + for (i = 1; i <= length; i++) + data.block[i] = values[i-1]; + data.block[0] = length; + return i2c_smbus_access(file,I2C_SMBUS_WRITE,command, + I2C_SMBUS_BLOCK_DATA, &data); +} + +/* Returns the number of read bytes */ +static inline __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command, + __u8 *values) +{ + union i2c_smbus_data data; + int i; + if (i2c_smbus_access(file,I2C_SMBUS_READ,command, + I2C_SMBUS_I2C_BLOCK_DATA,&data)) + return -1; + else { + for (i = 1; i <= data.block[0]; i++) + values[i-1] = data.block[i]; + return data.block[0]; + } +} + +static inline __s32 i2c_smbus_write_i2c_block_data(int file, __u8 command, + __u8 length, __u8 *values) +{ + union i2c_smbus_data data; + int i; + if (length > 32) + length = 32; + for (i = 1; i <= length; i++) + data.block[i] = values[i-1]; + data.block[0] = length; + return i2c_smbus_access(file,I2C_SMBUS_WRITE,command, + I2C_SMBUS_I2C_BLOCK_DATA, &data); +} + +/* Returns the number of read bytes */ +static inline __s32 i2c_smbus_block_process_call(int file, __u8 command, + __u8 length, __u8 *values) +{ + union i2c_smbus_data data; + int i; + if (length > 32) + length = 32; + for (i = 1; i <= length; i++) + data.block[i] = values[i-1]; + data.block[0] = length; + if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command, + I2C_SMBUS_BLOCK_PROC_CALL,&data)) + return -1; + else { + for (i = 1; i <= data.block[0]; i++) + values[i-1] = data.block[i]; + return data.block[0]; + } +} + + +#endif /* LIB_I2CDEV_H */ diff --git a/you-ass-bee-see/eeprom.c b/you-ass-bee-see/eeprom.c deleted file mode 100644 index 37685a7..0000000 --- a/you-ass-bee-see/eeprom.c +++ /dev/null @@ -1,315 +0,0 @@ -/* -This program is hereby placed into the public domain. -Of course the program is provided without warranty of any kind. - -Downloaded from http://www.lm-sensors.org/browser/i2c-tools/trunk/eepromer/eeprom.c - -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - this program can read 24C16 (and probably smaller ones, too) - I wrote it as a quick and dirty hack because my satellite receiver - hung again... so I had to reprogram the eeprom where is stores it's - settings. - */ - -#define DEFAULT_I2C_BUS "/dev/i2c-0" -#define DEFAULT_EEPROM_ADDR 0x50 /* the 24C16 sits on i2c address 0x50 */ -#define DEFAULT_NUM_PAGES 8 /* we default to a 24C16 eeprom which has 8 pages */ -#define BYTES_PER_PAGE 256 /* one eeprom page is 256 byte */ -#define MAX_BYTES 16 /* max number of bytes to write in one chunk */ - /* ... note: 24C02 and 24C01 only allow 8 bytes to be written in one chunk. * - * if you are going to write 24C04,8,16 you can change this to 16 */ - -/* write len bytes (stored in buf) to eeprom at address addr, page-offset offset */ -/* if len=0 (buf may be NULL in this case) you can reposition the eeprom's read-pointer */ -/* return 0 on success, -1 on failure */ -int eeprom_write(int fd, - unsigned int addr, - unsigned int offset, - unsigned char *buf, - unsigned char len -){ - struct i2c_rdwr_ioctl_data msg_rdwr; - struct i2c_msg i2cmsg; - int i; - char _buf[MAX_BYTES + 1]; - - if(len>MAX_BYTES){ - fprintf(stderr,"I can only write MAX_BYTES bytes at a time!\n"); - return -1; - } - - if(len+offset >256){ - fprintf(stderr,"Sorry, len(%d)+offset(%d) > 256 (page boundary)\n", - len,offset); - return -1; - } - - _buf[0]=offset; /* _buf[0] is the offset into the eeprom page! */ - for(i=0;i _buf[1..n+1] */ - _buf[1+i]=buf[i]; - - msg_rdwr.msgs = &i2cmsg; - msg_rdwr.nmsgs = 1; - - i2cmsg.addr = addr; - i2cmsg.flags = 0; - i2cmsg.len = 1+len; - i2cmsg.buf = _buf; - - if((i=ioctl(fd,I2C_RDWR,&msg_rdwr))<0){ - if ( len > 0 ) { - perror("ioctl()"); - fprintf(stderr,"ioctl returned %d\n",i); - } - return -1; - } - - if(len>0) - fprintf(stderr,"Wrote %d bytes to eeprom at 0x%02x, offset %08x\n", - len,addr,offset); - return 0; -} - -/* read len bytes stored in eeprom at address addr, offset offset in array buf */ -/* return -1 on error, 0 on success */ -int eeprom_read(int fd, - unsigned int addr, - unsigned int offset, - unsigned char *buf, - unsigned char len -){ - struct i2c_rdwr_ioctl_data msg_rdwr; - struct i2c_msg i2cmsg; - int i; - - if(len>MAX_BYTES){ - fprintf(stderr,"I can only write MAX_BYTES bytes at a time!\n"); - return -1; - } - - if(eeprom_write(fd,addr,offset,NULL,0)<0) - return -1; - - msg_rdwr.msgs = &i2cmsg; - msg_rdwr.nmsgs = 1; - - i2cmsg.addr = addr; - i2cmsg.flags = I2C_M_RD; - i2cmsg.len = len; - i2cmsg.buf = buf; - - if((i=ioctl(fd,I2C_RDWR,&msg_rdwr))<0){ - perror("ioctl()"); - fprintf(stderr,"ioctl returned %d\n",i); - return -1; - } - - fprintf(stderr,"Read %d bytes from eeprom at 0x%02x, offset %08x\n", - len,addr,offset); - - return 0; -} - - - -int main(int argc, char **argv){ - int i,j; - - /* filedescriptor and name of device */ - int d; - char *dn=DEFAULT_I2C_BUS; - - /* filedescriptor and name of data file */ - int f=-1; - char *fn=NULL; - - unsigned int addr=DEFAULT_EEPROM_ADDR; - int rwmode=0; - int pages=DEFAULT_NUM_PAGES; - - int force=0; /* suppress warning on write! */ - int wait = 0; - int acked = 0; - - while((i=getopt(argc,argv,"d:a:p:wyf:h"))>=0){ - switch(i){ - case 'h': - fprintf(stderr,"%s [-d dev] [-a adr] [-p pgs] [-w] [-y] [-f file]\n",argv[0]); - fprintf(stderr,"\tdev: device, e.g. /dev/i2c-0 (def)\n"); - fprintf(stderr,"\tadr: base address of eeprom, eg 0xA0 (def)\n"); - fprintf(stderr,"\tpgs: number of pages to read, eg 8 (def)\n"); - fprintf(stderr,"\t-w : write to eeprom (default is reading!)\n"); - fprintf(stderr,"\t-y : suppress warning when writing (default is to warn!)\n"); - fprintf(stderr,"\t-f file: copy eeprom contents to/from file\n"); - fprintf(stderr,"\t (default for read is test only; for write is all zeros)\n"); - fprintf(stderr,"Note on pages/addresses:\n"); - fprintf(stderr,"\teeproms with more than 256 byte appear as if they\n"); - fprintf(stderr,"\twere several eeproms with consecutive addresses on the bus\n"); - fprintf(stderr,"\tso we might as well address several separate eeproms with\n"); - fprintf(stderr,"\tincreasing addresses....\n\n"); - exit(1); - break; - case 'd': - dn=optarg; - break; - case 'a': - if(sscanf(optarg,"0x%x",&addr)!=1){ - fprintf(stderr,"Cannot parse '%s' as addrs., example: 0xa0\n", - optarg); - exit(1); - } - break; - case 'p': - if(sscanf(optarg,"%d",&pages)!=1){ - fprintf(stderr,"Cannot parse '%s' as number of pages, example: 8\n", - optarg); - exit(1); - } - break; - case 'w': - rwmode++; - break; - case 'f': - fn=optarg; - break; - case 'y': - force++; - break; - } - - } - - fprintf(stderr,"base-address of eeproms : 0x%02x\n",addr); - fprintf(stderr,"number of pages to read : %d (0x%02x .. 0x%02x)\n", - pages,addr,addr+pages-1); - - if(fn){ - if(!rwmode) /* if we are reading, *WRITE* to file */ - f=open(fn,O_WRONLY|O_CREAT,0666); - else /* if we are writing to eeprom, *READ* from file */ - f=open(fn,O_RDONLY); - if(f<0){ - fprintf(stderr,"Could not open data-file %s for reading or writing\n",fn); - perror(fn); - exit(1); - } - fprintf(stderr,"file opened for %7s : %s\n",rwmode?"reading":"writing",fn); - fprintf(stderr," on filedescriptor : %d\n",f); - } - - if((d=open(dn,O_RDWR))<0){ - fprintf(stderr,"Could not open i2c at %s\n",dn); - perror(dn); - exit(1); - } - - fprintf(stderr,"i2c-devicenode is : %s\n",dn); - fprintf(stderr," on filedescriptor : %d\n\n",d); - - /*** - *** I'm not the one to blame of you screw your computer! - ***/ - if(rwmode && ! force){ - unsigned char warnbuf[4]; - fprintf(stderr,"**WARNING**\n"); - fprintf(stderr," - \tYou have chosen to WRITE to this eeprom.\n"); - fprintf(stderr,"\tMake sure that this tiny chip is *NOT* vital to the\n"); - fprintf(stderr,"\toperation of your computer as you can easily corrupt\n"); - fprintf(stderr,"\tthe configuration memory of your SDRAM-memory-module,\n"); - fprintf(stderr,"\tyour IBM ThinkPad or whatnot...! Fixing these errors can be\n"); - fprintf(stderr,"\ta time-consuming and very costly process!\n\n"); - fprintf(stderr,"Things to consider:\n"); - fprintf(stderr," - \tYou can have more than one i2c-bus, check in /proc/bus/i2c\n"); - fprintf(stderr,"\tand specify the correct one with -d\n"); - fprintf(stderr,"\tright now you have chosen to use '%s'\n",dn); - fprintf(stderr," - \tA eeprom can occupy several i2c-addresses (one per page)\n"); - fprintf(stderr,"\tso please make sure that there is no vital eeprom in your computer\n"); - fprintf(stderr,"\tsitting at addresses between 0x%02x and 0x%02x\n",addr,addr+pages-1); - - fprintf(stderr,"Enter 'yes' to continue:"); - fflush(stderr); - if(!fgets(warnbuf,sizeof(warnbuf),stdin)){ - fprintf(stderr,"\nCould not read confirmation from stdin!\n"); - exit(1); - } - if(strncmp(warnbuf,"yes",3)){ - fprintf(stderr,"\n** ABORTING WRITE! **, you did not answer 'yes'\n"); - exit(1); - } - } - - for(i=0;i=0){ - j=read(f,buf,sizeof(buf)); - if(j<0){ - fprintf(stderr,"Cannot read from file '%s'\n",fn); - perror(fn); - exit(1); - } - if(j!=sizeof(buf)){ - fprintf(stderr,"File '%s' is too small, padding eeprom with zeroes\n",fn); - while(j=0){ - j=write(f,buf,sizeof(buf)); - if(j!=sizeof(buf)){ - fprintf(stderr,"Cannot write to file '%s'\n",fn); - perror(fn); - exit(1); - } - } - - } - - if(f>=0) - close(f); - - close(d); - - exit(0); - -}