diff options
Diffstat (limited to 'meta-facebook/meta-wedge/recipes-wedge/fbutils/files')
18 files changed, 1057 insertions, 85 deletions
diff --git a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/at93cx6.py b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/at93cx6.py new file mode 100644 index 0000000..514a06b --- /dev/null +++ b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/at93cx6.py @@ -0,0 +1,318 @@ +# Copyright 2004-present Facebook. All rights reserved. +# +# This program file 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; version 2 of the License. +# +# 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 in a file named COPYING; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301 USA +# + +import subprocess +import struct +import sys + + +AT93C46 = 'at93c46' +AT93C56 = 'at93c56' +AT93C66 = 'at93c66' +AT93C86 = 'at93c86' + + +class VerboseLogger: + def __init__(self, verbose=False): + self.verbose = verbose + + def _verbose_print(self, caption, bytestream=None): + ''' + Print a bytestream to stdout if verbose is enabled. + ''' + if self.verbose: + if bytestream is not None: + sys.stderr.write( + "{}: {}\n" .format( + caption, " ".join(['{:02X}'.format(ord(x)) + for x in bytestream]))) + else: + sys.stderr.write("{}\n".format(caption)) + + +class AT93CX6SPI(VerboseLogger): + '''The class to access AT93CX6 through SPI intf''' + SPI_CMD = 'spi-bb' + + def __init__(self, bus_width, gpio_cs, gpio_ck, gpio_do, gpio_di, + model, verbose=False): + addr_bits_map = { + AT93C46 : 6, + AT93C56 : 8, + AT93C66 : 8, + AT93C86 : 10, + } + if bus_width != 8 and bus_width != 16: + raise Exception("Invalid bus width for AT93CX6!") + if model not in addr_bits_map: + raise Exception("Invalid model '%s'" % model) + + self.bus_width = bus_width + self.gpio_cs = gpio_cs + self.gpio_ck = gpio_ck + self.gpio_do = gpio_do + self.gpio_di = gpio_di + self.verbose = verbose + + self.addr_bits = addr_bits_map[model] \ + + (0 if self.bus_width == 16 else 1) + self.addr_mask = (1 << self.addr_bits) - 1 + + def __shift(self, bytestream, value): + ''' + Shift an entire byte stream by value bits. + ''' + binary = "".join(['{:08b}'.format(ord(x)) for x in bytestream]) + if value > 0: + binary = binary[value:] + '0' * value + else: + binary = '0' * (-value) + binary[:value] + return "".join([chr(int(binary[x:x+8],2)) + for x in range(0, len(binary), 8)]) + + def __io(self, op, addr, data=None): + ''' + Perform an IO operation against the EEPROM + ''' + write_bits = self.addr_bits + 3 + if data is not None: + # If giving data, we are doing a write command so + # no need to read any data. + write_bits = write_bits + self.bus_width + read_bits = 0 + else: + # If not giving data, we are doing either a read + # command or a set command, so read the result. + # We pad with an extra bit due to a dummy bit introduced + # by a delay for address decoding on chip. + read_bits = self.addr_bits + 4 + self.bus_width + + # Format the command itself + instruction = addr & self.addr_mask + instruction = instruction | ((0x4 | (op & 0x3)) << self.addr_bits) + if data is not None: + if self.bus_width == 16: + write_data = struct.pack(">HH", instruction, data & 0xFFFF) + else: + write_data = struct.pack(">HB", instruction, data & 0xFF) + else: + write_data = struct.pack(">H", instruction) + write_data = self.__shift(write_data, 16 - (self.addr_bits + 3)) + + self._verbose_print("Write data", write_data) + + # Run the command with the bitbang driver + if read_bits > 0: + data_portion = "-r {} -w {}".format(read_bits, write_bits) + else: + data_portion = "-w {}".format(write_bits) + + cmd = "{} -s {} -c {} -o {} -i {} -b {}".format( + self.SPI_CMD, self.gpio_cs, self.gpio_ck, self.gpio_do, + self.gpio_di, data_portion + ) + + self._verbose_print("Command: {}".format(cmd)) + + out = subprocess.Popen(cmd.split(), + stdout=subprocess.PIPE, + stdin = subprocess.PIPE)\ + .communicate(input=write_data) + + # Format the response + read_data = self.__shift(out[0], self.addr_bits + 4) + if self.bus_width == 16: + read_data = read_data[:2] + self._verbose_print("Read data", read_data) + return struct.unpack(">H", read_data)[0] + else: + read_data = read_data[:1] + self._verbose_print("Read data", read_data) + return struct.unpack(">B", read_data)[0] + + def read(self, addr): + return self.__io(0x2, addr) + + def ewen(self): + self.__io(0x0, 0x3 << (self.addr_bits - 2)) + + def erase(self, addr): + self.__io(0x3, addr) + + def write(self, addr, data): + self.__io(0x1, addr, data) + + def eral(self): + self.__io(0x0, 0x2 << (self.addr_bits - 2)) + + def wral(self, data): + self.__io(0x0, 0x1 << (self.addr_bits - 2), data) + + def ewds(self): + self.__io(0x0, 0x0) + + +class AT93CX6(VerboseLogger): + ''' + The class which handles accessing memory on the AT93CX6 chip. + ''' + + def __init__(self, bus_width, gpio_cs, gpio_ck, gpio_do, gpio_di, + byte_swap, model=AT93C46, verbose=False): + mem_size_map = { + # in bytes + AT93C46 : 128, + AT93C56 : 256, + AT93C66 : 512, + AT93C86 : 2048, + } + self.bus_width = bus_width + self.verbose = verbose + self.byte_swap = byte_swap + self.model = model + self.memory_size = mem_size_map[model] + + self.spi = AT93CX6SPI(bus_width=bus_width, gpio_cs=gpio_cs, + gpio_ck=gpio_ck, gpio_do=gpio_do, + gpio_di=gpio_di, model=model, + verbose=verbose) + + def __swap(self, value): + ''' + Swap bytes for a 16-bit integer if instructed to do so. + ''' + if self.bus_width == 16: + if self.byte_swap: + return ((value >> 8) & 0xFF) | ((value << 8) & 0xFF00) + else: + return value + else: + return value + + def get_memory_size(self): + return self.memory_size + + def erase(self, offset=None, limit=None): + ''' + Erase the chip. + ''' + if offset is None: + offset = 0 + if limit is None: + limit = self.memory_size + + if offset < 0 or offset + limit > self.memory_size: + raise Exception("Erase would be out of bounds!") + if self.bus_width == 16 and \ + ((offset & 1) != 0 or ((offset + limit) & 1) != 0): + raise Exception("Erase can't start or end on odd boundary in " + "16-bit mode!") + + if offset == 0 and limit == self.memory_size: + # Special case when we are erasing the entire chip + self.spi.ewen() + self.spi.eral() + self.spi.ewds() + + self._verbose_print("Erased entire chip") + else: + # Regular case + if self.bus_width == 16: + real_offset = offset / 2 + real_limit = limit / 2 + else: + real_offset = offset + real_limit = limit + + self.spi.ewen() + for addr in range(real_offset, real_offset + real_limit): + self.spi.erase(addr) + self.spi.ewds() + + self._verbose_print("Erased {} bytes from offset {}" + .format(limit, offset)) + + def read(self, offset=None, limit=None): + ''' + Read the chip into a memory buffer. + ''' + if offset is None: + offset = 0 + if limit is None: + limit = self.memory_size + + if offset < 0 or offset + limit > self.memory_size: + raise Exception("Read would be out of bounds!") + if self.bus_width == 16 and \ + ((offset & 1) != 0 or ((offset + limit) & 1) != 0): + raise Exception("Read can't start or end on odd boundary in 16-bit " + "mode!") + + output = "" + if self.bus_width == 16: + real_offset = offset / 2 + real_limit = limit / 2 + pack_instruction = "=H" + else: + real_offset = offset + real_offset + pack_instruction = "=B" + + for addr in range(real_offset, real_offset + real_limit): + output = output + struct.pack(pack_instruction, + self.__swap(self.spi.read(addr))) + + self._verbose_print("Read {} bytes from offset {}".format(limit, offset) + , output) + + return output + + def write(self, data, offset=None): + ''' + Write a memory buffer to the chip. + ''' + if offset is None: + offset = 0 + + if offset < 0 or offset + len(data) > self.memory_size: + raise Exception("Write would be out of bounds!") + if self.bus_width == 16 and \ + ((offset & 1) != 0 or ((offset + len(data)) & 1) != 0): + raise Exception("Write can't start or end on odd boundary in " + "16-bit mode!") + + if self.bus_width == 16: + offset_divisor = 2 + pack_instruction = "=H" + else: + offset_divisor = 1 + pack_instruction = "=B" + + self.spi.ewen() + for addr in range(offset, offset + len(data), offset_divisor): + actual_addr = addr / offset_divisor + value = self.__swap(struct.unpack( + pack_instruction, data[(addr - offset):(addr - offset) + + offset_divisor])[0]) + + self.spi.erase(actual_addr) + self.spi.write(actual_addr, value) + self.spi.ewds() + + self._verbose_print("Wrote {} bytes from offset {}" + .format(len(data), offset), data) diff --git a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/at93cx6_util.py b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/at93cx6_util.py new file mode 100755 index 0000000..8ae7664 --- /dev/null +++ b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/at93cx6_util.py @@ -0,0 +1,223 @@ +#!/usr/bin/python -S +# Copyright 2004-present Facebook. All rights reserved. +# +# This program file 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; version 2 of the License. +# +# 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 in a file named COPYING; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301 USA +# + + +from argparse import ArgumentParser +import at93cx6 +import sys + + +def get_raw(args): + return at93cx6.AT93CX6SPI( + args.bus_width, args.cs, args.clk, args.mosi, args.miso, + args.model, args.verbose) + +def get_chip(args): + return at93cx6.AT93CX6( + args.bus_width, args.cs, args.clk, args.mosi, args.miso, + args.byte_swap if hasattr(args, 'byte_swap') else None, + args.model, args.verbose) + +def model_parser(ap): + # Default, based on currenct HW configuration + MODEL_DEFAULT = at93cx6.AT93C46 + + ap.add_argument('--model', default=at93cx6.AT93C46, + choices=[at93cx6.AT93C46, at93cx6.AT93C56, + at93cx6.AT93C66, at93cx6.AT93C86], + help='The chip model (default: %(default)s)') + +def access_parser(ap): + # Default, based on currenct HW configuration + SPI_CS_DEFAULT = 68 + SPI_CLK_DEFAULT = 69 + SPI_MOSI_DEFAULT = 70 + SPI_MISO_DEFAULT = 71 + + spi_group = ap.add_argument_group('SPI Access') + spi_group.add_argument('--cs', type=int, default=SPI_CS_DEFAULT, + help='The GPIO number for SPI CS pin ' + '(default: %(default)s)') + spi_group.add_argument('--clk', type=int, default=SPI_CLK_DEFAULT, + help='The GPIO number for SPI CLK pin ' + '(default: %(default)s)') + spi_group.add_argument('--mosi', type=int, default=SPI_MOSI_DEFAULT, + help='The GPIO number for SPI MOSI pin ' + '(default: %(default)s)') + spi_group.add_argument('--miso', type=int, default=SPI_MISO_DEFAULT, + help='The GPIO number for SPI MISO pin ' + '(default: %(default)s)') + +def bus_width_parser(ap): + # Default, based on currenct HW configuration + AT83C46_BUS_WIDTH = 16 + + bus_group = ap.add_argument_group('Bus Width') + bus_group.add_argument('--bus-width', type=int, default=AT83C46_BUS_WIDTH, + help='The configured bus width ' + '(default: %(default)s)') + +def read_raw(args): + raw = get_raw(args) + val = raw.read(args.address) + + if args.int: + print "{}".format(val) + else: + if args.bus_width == 16: + print "0x{:04X}".format(val) + else: + print "0x{:02X}".format(val) + +def write_raw(args): + if args.value[:2] == "0x": + value = int(args.value, 16) + else: + value = int(args.value) + + raw = get_raw(args) + raw.ewen() + raw.erase(args.address) + raw.write(args.address, value) + raw.ewds() + +def erase_raw(args): + raw = get_raw(args) + raw.ewen() + raw.erase(args.address) + raw.ewds() + +def raw_subparser(subparsers): + raw_parser = subparsers.add_parser( + 'raw', help='Raw memory access') + raw_sub = raw_parser.add_subparsers() + + read_parser = raw_sub.add_parser( + 'read', help='Read a single memory address') + read_parser.add_argument( + 'address', type=int, help='The memory address') + read_parser.add_argument('--int', action='store_true', + help='Display output as an integer') + read_parser.set_defaults(func=read_raw) + + write_parser = raw_sub.add_parser( + 'write', help='Write a single memory address') + write_parser.add_argument( + 'address', type=int, help='The memory address') + write_parser.add_argument( + 'value', type=str, help='The value to write, either integer or hex') + write_parser.set_defaults(func=write_raw) + + erase_parser = raw_sub.add_parser( + 'erase', help='Erase a single memory address') + erase_parser.add_argument('address', type=int, help='The memory address') + erase_parser.set_defaults(func=erase_raw) + +def read_chip(args): + chip = get_chip(args) + data = chip.read(args.start, args.length) + + if args.file is None: + sys.stdout.write(data) + else: + with open(args.file, "wb") as fp: + fp.write(data) + +def write_chip(args): + chip = get_chip(args) + + # Either way, limit reads to the size of the chip + if args.file is None: + data = sys.stdin.read(chip.get_memory_size()) + else: + with open(args.file, "rb") as fp: + data = fp.read(chip.get_memory_size()) + + if args.length is not None: + # Make sure length is correct + if len(data) < args.length: + data = data + '\x00' * (args.length - len(data)) + if len(data) > args.length: + data = data[:args.length] + + chip.write(data, args.start) + +def erase_chip(args): + chip = get_chip(args) + chip.erase(args.start, args.length) + +def chip_subparser(subparsers): + chip_parser = subparsers.add_parser('chip', help='Chip-level access') + chip_sub = chip_parser.add_subparsers() + + read_parser = chip_sub.add_parser('read', help='Read from the chip') + read_parser.add_argument('--start', type=int, + help='The memory address to start at (default: 0)') + read_parser.add_argument('--length', type=int, + help='The number of bytes to read ' + '(default: whole chip)') + read_parser.add_argument('--file', type=str, + help='File to operate on (default: stdout)') + read_parser.add_argument('--byte-swap', default=False, action='store_true', + help='Byte swap values for 16-bit reads/writes ' + '(default: %(default)s)') + read_parser.set_defaults(func=read_chip) + + write_parser = chip_sub.add_parser('write', help='Write to the chip') + write_parser.add_argument('--start', type=int, + help='The memory address to start at ' + '(default: 0)') + write_parser.add_argument('--length', type=int, + help='The number of bytes to write ' + '(default: file length)') + write_parser.add_argument('--file', type=str, + help='File to operate on (default: stdin)') + write_parser.add_argument('--byte-swap', default=False, action='store_true', + help='Byte swap values for 16-bit reads/writes ' + '(default: %(default)s)') + write_parser.set_defaults(func=write_chip) + + erase_parser = chip_sub.add_parser('erase', help='Erase the chip') + erase_parser.add_argument('--start', type=int, + help='The memory address to start at ' + '(default: 0)') + erase_parser.add_argument('--length', type=int, + help='The number of bytes to erase ' + '(default: whole chip)') + erase_parser.set_defaults(func=erase_chip) + +if __name__ == "__main__": + # General arguments + ap = ArgumentParser() + ap.add_argument('--verbose', action='store_true', + help='Print verbose debugging information') + + # Model, SPI, and bus width arguments + model_parser(ap) + access_parser(ap) + bus_width_parser(ap) + + # Functionality + subparsers = ap.add_subparsers() + raw_subparser(subparsers) + chip_subparser(subparsers) + + # Command runner + args = ap.parse_args() + args.func(args) diff --git a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/bcm5396.py b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/bcm5396.py index e1aba47..91d9a85 100644 --- a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/bcm5396.py +++ b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/bcm5396.py @@ -16,10 +16,13 @@ # 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301 USA # +from __future__ import print_function + import subprocess import time + class Bcm5396MDIO: '''The class to access BCM5396 through MDIO intf''' MDIO_CMD = 'mdio-bb' @@ -254,23 +257,35 @@ class Bcm5396SPI: except Exception as e: print(e) + class Bcm5396: '''The class for BCM5396 Switch''' MDIO_ACCESS = 0 SPI_ACCESS = 1 - def __init__(self, access, **kwargs): + def __init__(self, access, verbose=False, **kwargs): + self.verbose = verbose if access == self.MDIO_ACCESS: self.access = Bcm5396MDIO(**kwargs) else: self.access = Bcm5396SPI(**kwargs) def write(self, page, reg, value, n_bytes): + if self.verbose: + print('WRITE {:2x} {:2x} {:2x} '.format(page, reg, n_bytes), end='') + bytes = '{:2x}'.format(value) + print([bytes[i:i+2] for i in range(0, len(bytes), 2)][-n_bytes:]) return self.access.write(page, reg, value, n_bytes) def read(self, page, reg, n_bytes): - return self.access.read(page, reg, n_bytes) + if self.verbose: + print('READ {:2x} {:2x} {:2x} '.format(page, reg, n_bytes), end='') + result = self.access.read(page, reg, n_bytes) + if self.verbose: + bytes = '{:2x}'.format(result) + print([bytes[i:i+2] for i in range(0, len(bytes), 2)][-n_bytes:]) + return result def __add_remove_vlan(self, add, vid, untag, fwd, spt): VLAN_PAGE = 0x5 diff --git a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/bcm5396_util.py b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/bcm5396_util.py index 1496412..0759b08 100644 --- a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/bcm5396_util.py +++ b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/bcm5396_util.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python -tt # Copyright 2004-present Facebook. All rights reserved. # # This program file is free software; you can redistribute it and/or modify it @@ -29,9 +29,11 @@ def auto_int(x): def get_bcm(args): if args.spi: return Bcm5396(Bcm5396.SPI_ACCESS, cs=args.cs, clk=args.clk, - mosi=args.mosi, miso=args.miso) + mosi=args.mosi, miso=args.miso, + verbose=args.verbose) else: - return Bcm5396(Bcm5396.MDIO_ACCESS, mdc=args.mdc, mdio=args.mdio) + return Bcm5396(Bcm5396.MDIO_ACCESS, mdc=args.mdc, mdio=args.mdio, + verbose=args.verbose) def read_register(args): @@ -249,6 +251,10 @@ def access_parser(ap): if __name__ == '__main__': ap = ArgumentParser() + ap.add_argument('-v', '--verbose', action='store_true', + help='Dump the switch page, register, and value ' + 'for each operation') + access_parser(ap) subparsers = ap.add_subparsers() diff --git a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/board-utils.sh b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/board-utils.sh new file mode 100644 index 0000000..e4d34aa --- /dev/null +++ b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/board-utils.sh @@ -0,0 +1,163 @@ +# Copyright 2014-present Facebook. All Rights Reserved. +wedge_iso_buf_enable() { + # GPIOC2 (18) to low, SCU90[0] and SCU90[24] must be 0 + devmem_clear_bit $(scu_addr 90) 0 + devmem_clear_bit $(scu_addr 90) 24 + gpio_set 18 0 +} + +wedge_iso_buf_disable() { + # GPIOC2 (18) to low, SCU90[0] and SCU90[24] must be 0 + devmem_clear_bit $(scu_addr 90) 0 + devmem_clear_bit $(scu_addr 90) 24 + gpio_set 18 1 +} + +wedge_is_us_on() { + local val n retries prog + if [ $# -gt 0 ]; then + retries="$1" + else + retries=1 + fi + if [ $# -gt 1 ]; then + prog="$2" + else + prog="" + fi + if [ $# -gt 2 ]; then + default=$3 # value 0 means defaul is 'ON' + else + default=1 + fi + n=1 + while true; do + val=$(cat /sys/class/i2c-adapter/i2c-4/4-0040/gpio_inputs 2>/dev/null) + if [ -n "$val" ]; then + break + fi + n=$((n+1)) + if [ $n -gt $retries ]; then + echo -n " failed to read GPIO. " + return $default + break + fi + echo -n "$prog" + sleep 1 + done + if [ "$((val & (0x1 << 14)))" != "0" ]; then + # powered on already + return 0 + else + return 1 + fi +} + + +# Return the board type, 'LC', 'FC-LEFT', 'FC-RIGHT', or, 'WEDGE' +wedge_board_type() { + local pn + pn=$(/usr/bin/weutil 2> /dev/null | grep -i '^Location on Fabric:') + case "$pn" in + *LEFT*) + echo 'FC-LEFT' + ;; + *RIGHT*) + echo 'FC-RIGHT' + ;; + *LC*) + echo 'LC' + ;; + *) + echo 'WEDGE' + ;; + esac +} + +# On FC, +# board rev < 2: +# FAB_SLOT_ID (GPIOU0), low == FC0; high == FC1 +# else: +# FAB_SLOT_ID (GPIOU6), low == FC0; high == FC1 +## On LC, Wedge, +# board rev < 3: +# GPIOU0(ID0), GPIOU1(ID1), GPIOU2(ID2), GPIOU3(ID3) +# else: +# GPIOU6(ID0), GPIOU7(ID1), GPIOV0(ID2), GPIOV1(ID3) +# +# ID[2:0] ID3 Slot# +# 000 0 1 +# 000 1 2 +# 001 0 3 +# 001 1 4 +# 010 0 5 +# 010 1 6 +# 011 0 7 +# 011 1 8 + +wedge_slot_id() { + local type slot id3 id2 id1 id0 FC_CARD_BASE board_rev + FC_CARD_BASE=65 + # need to check the board rev + board_rev=$(wedge_board_rev) + case "$1" in + FC-LEFT|FC-RIGHT) + # On FC + if [ $board_rev -lt 2 ]; then + slot=$(gpio_get U0) + else + slot=$(gpio_get U6) + fi + if [ "$1" = "FC-LEFT" ]; then + # fabric card left + slot=$((FC_CARD_BASE + slot * 2)) + else + # fabric card right + slot=$((FC_CARD_BASE + slot * 2 + 1)) + fi + ;; + *) + # either edge or LC + if [ $board_rev -lt 3 ]; then + id0=$(gpio_get U0) + id1=$(gpio_get U1) + id2=$(gpio_get U2) + id3=$(gpio_get U3) + else + id0=$(gpio_get U6) + id1=$(gpio_get U7) + id2=$(gpio_get V0) + id3=$(gpio_get V1) + fi + slot=$(((id2 * 4 + id1 * 2 + id0) * 2 + id3 + 1)) + esac + echo "$slot" +} + +# wedge_board_rev() is only valid after GPIO Y0, Y1, and Y2 are enabled +wedge_board_rev() { + local val0 val1 val2 + val0=$(cat /sys/class/gpio/gpio192/value 2>/dev/null) + val1=$(cat /sys/class/gpio/gpio193/value 2>/dev/null) + val2=$(cat /sys/class/gpio/gpio194/value 2>/dev/null) + echo $((val0 | (val1 << 1) | (val2 << 2))) +} + +# Should we enable OOB interface or not +wedge_should_enable_oob() { + board_rev=$(wedge_board_rev) + board_type=$(wedge_board_type) + case "$board_type" in + FC-LEFT|FC-RIGHT) + if [ $board_rev -lt 2 ]; then + return 0 + fi + ;; + *) + if [ $board_rev -lt 3 ]; then + return 0 + fi + ;; + esac + return -1 +} diff --git a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/create_vlan_intf b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/create_vlan_intf index 2cf7a9a..8c7e74b 100644 --- a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/create_vlan_intf +++ b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/create_vlan_intf @@ -21,7 +21,7 @@ # only care about 'eth0' and 'oob' intf [ "$IFACE" != "eth0" ] && [ "$IFACE" != "oob" ] && exit 0 -. /usr/local/fbpackages/utils/ast-functions +. /usr/local/bin/openbmc-utils.sh board=$(wedge_board_type) diff --git a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/eth0_mac_fixup.sh b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/eth0_mac_fixup.sh index 1cdbcb6..f244bd0 100644 --- a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/eth0_mac_fixup.sh +++ b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/eth0_mac_fixup.sh @@ -29,13 +29,27 @@ PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin +# get the MAC from EEPROM mac=$(weutil 2>/dev/null | grep '^Local MAC' 2>/dev/null | cut -d' ' -f3 2>/dev/null) +# get the MAC from u-boot environment +ethaddr=$(fw_printenv ethaddr 2>/dev/null | cut -d'=' -f2 2>/dev/null) + +if [ -z "$mac" ] && [ -n "$ethaddr" ]; then + # no MAC from EEPROM, use the one from u-boot environment + mac="$ethaddr" +fi + if [ -n "$mac" ]; then ifconfig eth0 hw ether $mac - # compare the 'ethaddr' from u-boot env - ethaddr=$(fw_printenv ethaddr 2>/dev/null | cut -d'=' -f2 2>/dev/null) - if [ "$ethaddr" != "$mac" ]; then - fw_setenv "ethaddr" "$mac" - fi +else + # no MAC from either EEPROM or u-boot environment + mac=$(ifconfig eth0 2>/dev/null |grep HWaddr 2>/dev/null |awk '{ print $5 }') + +fi + +if [ "$ethaddr" != "$mac" ]; then + # set the MAC from EEPROM or ifconfig back to u-boot environment so that u-boot + # can use it + fw_setenv "ethaddr" "$mac" fi diff --git a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/post_led.sh b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/post_led.sh index c23349f..b653cb3 100644 --- a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/post_led.sh +++ b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/post_led.sh @@ -24,7 +24,7 @@ usage() { echo "Usage: $0 <value>" } -. /usr/local/fbpackages/utils/ast-functions +. /usr/local/bin/openbmc-utils.sh # Function to set the less significant hex digit display_lower() { diff --git a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/power-on.sh b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/power-on.sh index 843b79a..ace3c6a 100644 --- a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/power-on.sh +++ b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/power-on.sh @@ -25,7 +25,7 @@ # Default-Stop: # Short-Description: Power on micro-server ### END INIT INFO -. /usr/local/fbpackages/utils/ast-functions +. /usr/local/bin/openbmc-utils.sh PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin diff --git a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/power_led.sh b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/power_led.sh index 20206a1..066646e 100755 --- a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/power_led.sh +++ b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/power_led.sh @@ -23,7 +23,7 @@ usage() { exit -1 } -. /usr/local/fbpackages/utils/ast-functions +. /usr/local/bin/openbmc-utils.sh PATH=/sbin:/bin:/usr/sbin:/usr/bin diff --git a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/reset_usb.sh b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/reset_usb.sh index 7d1c2c6..c63ed10 100644 --- a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/reset_usb.sh +++ b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/reset_usb.sh @@ -18,7 +18,7 @@ # Boston, MA 02110-1301 USA # -. /usr/local/fbpackages/utils/ast-functions +. /usr/local/bin/openbmc-utils.sh echo -n "Reset USB Switch ... " diff --git a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/setup-gpio.sh b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/setup-gpio.sh index 9f0b543..717bcd8 100755 --- a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/setup-gpio.sh +++ b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/setup-gpio.sh @@ -39,7 +39,7 @@ # When defined, the system doesn't reboot cleanly. We're still # investigating this. -. /usr/local/fbpackages/utils/ast-functions +. /usr/local/bin/openbmc-utils.sh # Set up to read the board revision pins, Y0, Y1, Y2 devmem_set_bit $(scu_addr 70) 19 @@ -182,8 +182,8 @@ devmem_set_bit $(scu_addr 70) 13 # GPIOQ5 is ISO_FLASH_HOLD, must be 1 to be out of reset # To use GPIOQ4 and GPIOQ5, SCU90[27] must be 0 devmem_clear_bit $(scu_addr 90) 27 -gpio_set 134 1 -gpio_set 135 1 +gpio_set Q4 1 +gpio_set Q5 1 # GPIOD6 is ISO_FL_PRG_SEL, set it to 0 so that BMC does not have control # on the EEPROM by default. # To use GPIOD6, SCU90[1] must be 0, SCU8C[21] must be 0, and Strap[21] must be 0 @@ -244,31 +244,139 @@ board_type=$(wedge_board_type) case "$board_type" in FC-LEFT|FC-RIGHT) # On FC - # FAB_SLOT_ID is GPIOU0 - # PEER_FAB_PRSNT is GPIOU1 - devmem_set_bit $(scu_addr a0) 8 - devmem_set_bit $(scu_addr a0) 9 - gpio_export U0 - gpio_export U1 - # T2_POWER_UP is GPIOT6 - devmem_set_bit $(scu_addr a0) 6 - gpio_export T6 - # HS_FAULT_N is GPIOT7 - devmem_set_bit $(scu_addr a0) 7 - gpio_export T7 - if [ "$board_type" = "FC-LEFT" ]; then - # GPIOE2 is CPU_EEPROM_SEL, on FC-LEFT - devmem_clear_bit $(scu_addr 80) 18 - devmem_clear_bit $(scu_addr 8c) 13 - devmem_clear_bit $(scu_addr 70) 22 - gpio_export E2 - # GPIOA6 and GPIOA7 are MAC2 MDIO pins, we use them as - # GPIO for bitbang driver - devmem_clear_bit $(scu_addr 90) 2 - devmem_clear_bit $(scu_addr 80) 6 - devmem_clear_bit $(scu_addr 80) 7 - gpio_export A6 - gpio_export A7 + if [ $board_rev -lt 2 ]; then + # EVT board + # FAB_SLOT_ID is GPIOU0 + # PEER_FAB_PRSNT is GPIOU1 + devmem_set_bit $(scu_addr a0) 8 + devmem_set_bit $(scu_addr a0) 9 + gpio_export U0 + gpio_export U1 + # T2_POWER_UP is GPIOT6 + devmem_set_bit $(scu_addr a0) 6 + gpio_export T6 T2_POWER_UP + # HS_FAULT_N is GPIOT7 + devmem_set_bit $(scu_addr a0) 7 + gpio_export T7 + if [ "$board_type" = "FC-LEFT" ]; then + # GPIOE2 is CPU_EEPROM_SEL, on FC-LEFT + devmem_clear_bit $(scu_addr 80) 18 + devmem_clear_bit $(scu_addr 8c) 13 + devmem_clear_bit $(scu_addr 70) 22 + gpio_export E2 + # GPIOA6 and GPIOA7 are MAC2 MDIO pins, we use them as + # GPIO for bitbang driver + devmem_clear_bit $(scu_addr 90) 2 + devmem_clear_bit $(scu_addr 80) 6 + devmem_clear_bit $(scu_addr 80) 7 + gpio_export A6 + gpio_export A7 + fi + else + # DVT board + if [ "$board_type" = "FC-LEFT" ]; then # Left FC + # BMC_SW_RST is GPIOL0, 16p switch + # SCU84[16] must be 0 + devmem_clear_bit $(scu_addr 84) 16 + gpio_set L0 1 + + # MDC|MDIO_CONT are GPIOR6 and GPIOR7, 16p switch + # SCU88[30:31] must be 0 + devmem_clear_bit $(scu_addr 88) 30 + devmem_clear_bit $(scu_addr 88) 31 + gpio_set R6 1 + gpio_set R7 1 + + # SWITCH_EEPROM1_WRT is GPIOE2, 16p switch EEPROM (U61) + # SCU80[18], SCU8C[13], and SCU70[22] must be 0 + devmem_clear_bit $(scu_addr 80) 18 + devmem_clear_bit $(scu_addr 8C) 13 + devmem_clear_bit $(scu_addr 70) 22 + gpio_export E2 + + # SPI bus to 16p switch EEPROM + # GPIOI4 <--> BMC_EEPROM1_SPI_SS + # GPIOI5 <--> BMC_EEPROM1_SPI_SCK + # GPIOI6 <--> BMC_EEPROM1_SPI_MOSI + # GPIOI7 <--> BMC_EEPROM1_SPI_MISO + # The EEPROM SPI clk does not match with the BMC SPI master. + # Have to configure these pins as GPIO to use with + # SPI bitbang driver. + # SCU70[13:12,5] must be 0 + devmem_clear_bit $(scu_addr 70) 5 + devmem_clear_bit $(scu_addr 70) 12 + devmem_clear_bit $(scu_addr 70) 13 + gpio_export I4 + gpio_export I5 + gpio_export I6 + gpio_export I7 + + # BMC_PHY_RST is GPIOT0, Front Panel Port PHY on the 16p switch + # SCUA0[0] must be 1 + devmem_set_bit $(scu_addr a0) 0 + gpio_set T0 1 + + # BMC_5PORTSW_RST is GPIOT1, 5p switch + # SCUA0[1] must be 1 + devmem_set_bit $(scu_addr a0) 1 + gpio_set T1 1 + + # ISO_SWITCH1_MDC|MDIO are GPIOT4 and GPIOT5, 5p switch + # SCUA0[4:5] must be 1 + devmem_set_bit $(scu_addr a0) 4 + devmem_set_bit $(scu_addr a0) 5 + gpio_set T4 1 + gpio_set T5 1 + + # ISO_SWITCH_EEPROM2_WRT is GPIOV0, 5p switch EEPROM (U114) + # SCUA0[16] must be 1 + devmem_set_bit $(scu_addr a0) 16 + gpio_export V0 + + # SPI bus to 5p switch EEPROM (U114) + # GPIOI0 <--> ISO_BMC_EEPROM2_SPI_SS + # GPIOI1 <--> ISO_BMC_EEPROM2_SPI_SCK + # GPIOI2 <--> ISO_BMC_EEPROM2_SPI_MOSI + # GPIOI3 <--> ISO_BMC_EEPROM2_SPI_MISO + # The EEPROM SPI clk does not match with the BMC SPI master. + # Have to configure these pins as GPIO to use with + # SPI bitbang driver. + # SCU70[13] must be 0, has already been set when + # preparing for GPIOI4-GPIOI7 + gpio_export I0 + gpio_export I1 + gpio_export I2 + gpio_export I3 + + # BMC_PHYL_RST is GPIOF0, Left BMC PHY + # SCU80[24] must be 0 + devmem_clear_bit $(scu_addr 80) 24 + gpio_set F0 1 + else # Right FC + # BMC_PHYR_RST is GPIOL1, Right BMC PHY + # SCU84[17] must be 0 + devmem_clear_bit $(scu_addr 84) 17 + gpio_set L1 1 + fi + # T2_POWER_UP is GPIOU4 + # SCUA0[12] must be 1 + devmem_set_bit $(scu_addr a0) 12 + gpio_export U4 T2_POWER_UP + + # HS_FAULT_N is GPIOU5 + # SCUA0[13] must be 1 + devmem_set_bit $(scu_addr a0) 13 + gpio_export U5 + + # FAB_SLOT_ID is GPIOU6 + # SCUA0[14] must be 1 + devmem_set_bit $(scu_addr a0) 14 + gpio_export U6 + + # PEER_FAB_PRSNT is GPIOU7 + # SCUA0[15] must be 1 + devmem_set_bit $(scu_addr a0) 15 + gpio_export U7 fi ;; *) @@ -289,7 +397,7 @@ case "$board_type" in gpio_export U3 # T2_POWER_UP is GPIOT6 devmem_set_bit $(scu_addr a0) 6 - gpio_export T6 + gpio_export T6 T2_POWER_UP # HS_FAULT_N is GPIOT7 devmem_set_bit $(scu_addr a0) 7 gpio_export T7 @@ -307,7 +415,7 @@ case "$board_type" in gpio_export V1 # T2_POWER_UP is GPIOU4 devmem_set_bit $(scu_addr a0) 12 - gpio_export U4 + gpio_export U4 T2_POWER_UP # HS_FAULT_N is GPIOU5 devmem_set_bit $(scu_addr a0) 13 gpio_export U5 diff --git a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/setup_rov.sh b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/setup_rov.sh index 749fe65..1400464 100755 --- a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/setup_rov.sh +++ b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/setup_rov.sh @@ -24,7 +24,7 @@ # outgoing voltage on the first buck converter, and bring T2 up out of # reset. -. /usr/local/fbpackages/utils/ast-functions +. /usr/local/bin/openbmc-utils.sh # read the T2 ROV after the GPIOs are enabled t2_rov() { diff --git a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/sol.sh b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/sol.sh index ccbdc61..2998c81 100755 --- a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/sol.sh +++ b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/sol.sh @@ -18,7 +18,14 @@ # Boston, MA 02110-1301 USA # -CONSOLE_SH=/usr/local/fbpackages/utils/us_console.sh +CONSOLE_SH=/usr/local/bin/us_console.sh +FILE=/etc/us_pseudo_tty +TTY=/dev/ttyS1 + +if [ -a $FILE ] + then + read -r TTY<$FILE +fi $CONSOLE_SH connect @@ -29,7 +36,7 @@ echo trap '"$CONSOLE_SH" disconnect' INT TERM QUIT EXIT -/usr/bin/microcom -s 57600 /dev/ttyS1 +/usr/bin/microcom -s 57600 $TTY echo echo diff --git a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/start_us_monitor.sh b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/start_us_monitor.sh new file mode 100644 index 0000000..19f3198 --- /dev/null +++ b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/start_us_monitor.sh @@ -0,0 +1,73 @@ +#! /bin/sh +# +# Copyright 2014-present Facebook. All Rights Reserved. +# +# This program file 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; version 2 of the License. +# +# 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 in a file named COPYING; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301 USA +# + +### BEGIN INIT INFO +# Provides: us-monitor +# Required-Start: +# Required-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Start the microserver reset monitoring script +# +### END INIT INFO + +PATH=/sbin:/bin:/usr/sbin:/usr/bin +NAME="us_monitor" +DESC="monitoring microserver reset" +DAEMON="us_monitor.sh" + +# source function library +. /etc/init.d/functions + +. /usr/local/bin/openbmc-utils.sh + +STOPPER= +ACTION="$1" + +case "$ACTION" in + start) + echo -n "Starting $DESC: " + /usr/local/bin/${DAEMON} > /dev/null 2>&1 & + echo "$NAME." + ;; + stop) + echo -n "Stopping $DESC: " + killall ${DAEMON} + echo "$NAME." + ;; + restart|force-reload) + echo -n "Restarting $DESC: " + killall ${DAEMON} + /usr/local/bin/${DAEMON} > /dev/null 2>&1 & + echo "$NAME." + ;; + status) + status ${DAEMON} + exit $? + ;; + *) + N=${0##*/} + N=${N#[SK]??} + echo "Usage: $N {start|stop|status|restart|force-reload}" >&2 + exit 1 + ;; +esac + +exit 0 diff --git a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/us_console.sh b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/us_console.sh index 6f445ee..75bbcea 100755 --- a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/us_console.sh +++ b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/us_console.sh @@ -22,7 +22,7 @@ usage() { echo "$0 <connect | disconnect>" } -. /usr/local/fbpackages/utils/ast-functions +. /usr/local/bin/openbmc-utils.sh if [ $# -ne 1 ]; then usage diff --git a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/us_monitor.sh b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/us_monitor.sh new file mode 100644 index 0000000..b7a9cb6 --- /dev/null +++ b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/us_monitor.sh @@ -0,0 +1,56 @@ +#!/bin/bash +# +# Copyright 2015-present Facebook. All Rights Reserved. +# +# This program file 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; version 2 of the License. +# +# 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 in a file named COPYING; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301 USA + +. /usr/local/bin/openbmc-utils.sh + +PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin + +# Because the voltage leak from uS COM pins could cause uS to struck when +# transitting from S5 to S0, we will need to explicitely pull down uS COM +# pins before powering off/reset and restoring COM pins after + +pull_down_us_com() { + # set GPIOL6 and GPIOL7 low + devmem_clear_bit $(scu_addr 84) 22 + devmem_clear_bit $(scu_addr 84) 23 + gpio_set 94 0 + gpio_set 95 0 + # now, connect uart from BMC to the uS + gpio_set 32 1 +} + +restore_us_com() { + devmem_set_bit $(scu_addr 84) 22 + devmem_set_bit $(scu_addr 84) 23 + # if sol.sh is running, keep uart from uS connected with BMC + if pidof -x sol.sh > /dev/null 2>&1; then + gpio_set 32 1 + else + gpio_set 32 0 + fi +} + +while true; do + if ! wedge_is_us_on 1 '' 0 > /dev/null 2>&1; then + pull_down_us_com + else + restore_us_com + fi + usleep 400000 # 400ms +done diff --git a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/wedge_power.sh b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/wedge_power.sh index 5ba5311..ce734ef 100644 --- a/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/wedge_power.sh +++ b/meta-facebook/meta-wedge/recipes-wedge/fbutils/files/wedge_power.sh @@ -18,7 +18,7 @@ # Boston, MA 02110-1301 USA # -. /usr/local/fbpackages/utils/ast-functions +. /usr/local/bin/openbmc-utils.sh PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin @@ -43,31 +43,6 @@ usage() { echo } -# Because the voltage leak from uS COM pins could cause uS to struck when transitting -# from S5 to S0, we will need to explicitely pull down uS COM pins before powering off/reset -# and restoring COM pins after - -pull_down_us_com() { - # set GPIOL6 and GPIOL7 low - devmem_clear_bit $(scu_addr 84) 22 - devmem_clear_bit $(scu_addr 84) 23 - gpio_set 94 0 - gpio_set 95 0 - # now, connect uart from BMC to the uS - gpio_set 32 1 -} - -restore_us_com() { - devmem_set_bit $(scu_addr 84) 22 - devmem_set_bit $(scu_addr 84) 23 - # if sol.sh is running, keep uart from uS connected with BMC - if ps | grep sol.sh > /dev/null 2>&1; then - gpio_set 32 1 - else - gpio_set 32 0 - fi -} - do_status() { echo -n "Microserver power is " if wedge_is_us_on; then @@ -79,7 +54,7 @@ do_status() { } do_on() { - local force opt + local force opt pulse_us n retries force=0 while getopts "f" opt; do case $opt in @@ -103,14 +78,31 @@ do_on() { fi # first make sure, GPIOD1 (25) is high gpio_set 25 1 + sleep 1 # then, put GPIOP7 (127) to low gpio_set 127 0 - # generate the power on pulse - gpio_set 25 0 - sleep 1 - gpio_set 25 1 - sleep 1 - restore_us_com + pulse_us=500000 # 500ms + retries=3 + n=1 + while true; do + # first make sure, GPIOD1 (25) is high + gpio_set 25 1 + usleep $pulse_us + # generate the power on pulse + gpio_set 25 0 + usleep $pulse_us + gpio_set 25 1 + sleep 3 + if wedge_is_us_on 1 '' 1; then + break + fi + n=$((n+1)) + if [ $n -gt $retries ]; then + echo " Failed" + return 1 + fi + echo -n "..." + done # Turn on the power LED (GPIOE5) /usr/local/bin/power_led.sh on echo " Done" @@ -119,7 +111,6 @@ do_on() { do_off() { echo -n "Power off microserver ..." - pull_down_us_com # first make sure, GPIOD1 (25) is high gpio_set 25 1 # then, put GPIOP7 (127) to low @@ -158,14 +149,12 @@ do_reset() { return -1 fi echo -n "Power reset microserver ..." - pull_down_us_com # then, put GPIOP7 (127) to low gpio_set 127 0 gpio_set 17 0 sleep 1 gpio_set 17 1 sleep 1 - restore_us_com fi echo " Done" return 0 |