summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTING.md8
-rw-r--r--common/recipes-connectivity/lldp-util/lldp-util/src/LICENSE30
-rw-r--r--common/recipes-connectivity/lldp-util/lldp-util/src/Makefile19
-rw-r--r--common/recipes-connectivity/lldp-util/lldp-util/src/PATENTS23
-rw-r--r--common/recipes-connectivity/lldp-util/lldp-util/src/lldp_util.c703
-rw-r--r--common/recipes-connectivity/lldp-util/lldp-util_0.1.bb21
-rw-r--r--common/recipes-core/base-files/base-files_%.bbappend4
-rw-r--r--common/recipes-core/cfg-util/cfg-util_0.1.bb36
-rw-r--r--common/recipes-core/cfg-util/files/Makefile11
-rw-r--r--common/recipes-core/cfg-util/files/cfg-util.c78
-rw-r--r--common/recipes-core/consoled/consoled_0.1.bb36
-rw-r--r--common/recipes-core/consoled/files/Makefile11
-rw-r--r--common/recipes-core/consoled/files/consoled.c284
-rw-r--r--common/recipes-core/fan-ctrl/fan-ctrl/Makefile26
-rw-r--r--common/recipes-core/fan-ctrl/fan-ctrl/README5
-rw-r--r--common/recipes-core/fan-ctrl/fan-ctrl/fand.cpp1030
-rw-r--r--common/recipes-core/fan-ctrl/fan-ctrl/watchdog.cpp201
-rw-r--r--common/recipes-core/fan-ctrl/fan-ctrl/watchdog.h60
-rw-r--r--common/recipes-core/fan-ctrl/fan-ctrl_0.1.bb61
-rw-r--r--common/recipes-core/fruid/files/Makefile26
-rw-r--r--common/recipes-core/fruid/files/fruid-util.c145
-rw-r--r--common/recipes-core/fruid/fruid_0.1.bb55
-rw-r--r--common/recipes-core/ipmbd/files/Makefile10
-rw-r--r--common/recipes-core/ipmbd/files/ipmbd.c843
-rw-r--r--common/recipes-core/ipmbd/ipmbd_0.1.bb19
-rw-r--r--common/recipes-core/ipmid/files/Makefile29
-rw-r--r--common/recipes-core/ipmid/files/fruid.h28
-rw-r--r--common/recipes-core/ipmid/files/ipmid.c1412
-rw-r--r--common/recipes-core/ipmid/files/sdr.c414
-rw-r--r--common/recipes-core/ipmid/files/sdr.h72
-rw-r--r--common/recipes-core/ipmid/files/sel.c440
-rw-r--r--common/recipes-core/ipmid/files/sel.h51
-rw-r--r--common/recipes-core/ipmid/files/sensor.h117
-rw-r--r--common/recipes-core/ipmid/files/timestamp.c46
-rw-r--r--common/recipes-core/ipmid/files/timestamp.h30
-rw-r--r--common/recipes-core/ipmid/ipmid_0.2.bb42
-rw-r--r--common/recipes-core/power-util/files/Makefile11
-rw-r--r--common/recipes-core/power-util/files/power-util.c295
-rw-r--r--common/recipes-core/power-util/power-util_0.1.bb36
-rw-r--r--common/recipes-core/sensor-mon/files/Makefile26
-rw-r--r--common/recipes-core/sensor-mon/files/sensord.c1031
-rw-r--r--common/recipes-core/sensor-mon/sensor-mon_0.1.bb58
-rw-r--r--common/recipes-core/sensor-util/files/Makefile11
-rw-r--r--common/recipes-core/sensor-util/files/sensor-util.c173
-rw-r--r--common/recipes-core/sensor-util/sensor-util_0.1.bb34
-rw-r--r--common/recipes-core/watchdog-ctrl/watchdog-ctrl_0.1.bb15
-rw-r--r--common/recipes-lib/fruid/files/Makefile27
-rw-r--r--common/recipes-lib/fruid/files/fruid.c682
-rw-r--r--common/recipes-lib/fruid/files/fruid.h192
-rw-r--r--common/recipes-lib/fruid/libfruid_0.1.bb43
-rw-r--r--common/recipes-lib/gpio/files/src/Makefile27
-rw-r--r--common/recipes-lib/gpio/files/src/gpio.c107
-rw-r--r--common/recipes-lib/gpio/files/src/gpio.h42
-rw-r--r--common/recipes-lib/gpio/libgpio_0.1.bb40
-rw-r--r--common/recipes-lib/ipmb/files/Makefile11
-rw-r--r--common/recipes-lib/ipmb/files/ipmb.c82
-rw-r--r--common/recipes-lib/ipmb/files/ipmb.h75
-rw-r--r--common/recipes-lib/ipmb/libipmb_0.1.bb26
-rw-r--r--common/recipes-lib/ipmi/files/Makefile27
-rw-r--r--common/recipes-lib/ipmi/files/ipmi.c80
-rw-r--r--common/recipes-lib/ipmi/files/ipmi.h453
-rw-r--r--common/recipes-lib/ipmi/libipmi_0.2.bb41
-rw-r--r--common/recipes-lib/log/files/src/log.h59
-rw-r--r--common/recipes-lib/log/liblog_0.1.bb36
-rw-r--r--common/recipes-lib/sdr/files/Makefile11
-rw-r--r--common/recipes-lib/sdr/files/sdr.c210
-rw-r--r--common/recipes-lib/sdr/files/sdr.h163
-rw-r--r--common/recipes-lib/sdr/libsdr_0.1.bb30
-rw-r--r--common/recipes-rest/rest-api/files/node.py42
-rw-r--r--common/recipes-rest/rest-api/files/node_api.py31
-rw-r--r--common/recipes-rest/rest-api/files/node_bmc.py95
-rw-r--r--common/recipes-rest/rest-api/files/node_config.py65
-rw-r--r--common/recipes-rest/rest-api/files/node_fruid.py58
-rw-r--r--common/recipes-rest/rest-api/files/node_sensors.py60
-rw-r--r--common/recipes-rest/rest-api/files/node_server.py69
-rw-r--r--common/recipes-rest/rest-api/files/node_spb.py52
-rw-r--r--common/recipes-rest/rest-api/files/pal.py94
-rw-r--r--common/recipes-rest/rest-api/files/rest.py105
-rw-r--r--common/recipes-rest/rest-api/files/tree.py46
-rw-r--r--common/recipes-rest/rest-api/rest-api_0.2.bb36
-rw-r--r--common/recipes-utils/bitbang/bitbang_0.1.bb37
-rw-r--r--common/recipes-utils/bitbang/files/src/Makefile29
-rw-r--r--common/recipes-utils/bitbang/files/src/bitbang.c236
-rw-r--r--common/recipes-utils/bitbang/files/src/bitbang.h66
-rw-r--r--common/recipes-utils/bitbang/files/src/mdio_bb.c335
-rw-r--r--common/recipes-utils/bitbang/files/src/spi_bb.c317
-rw-r--r--common/recipes-utils/flashrom/files/01-include-make-local.patch11
-rw-r--r--common/recipes-utils/flashrom/files/flashrom-0.9.8/make.local9
-rw-r--r--common/recipes-utils/flashrom/flashrom_0.9.8.bb18
-rw-r--r--common/recipes-utils/jbi/files/code/COPYING340
-rw-r--r--common/recipes-utils/jbi/files/code/Makefile26
-rw-r--r--common/recipes-utils/jbi/files/code/jbicomp.c416
-rw-r--r--common/recipes-utils/jbi/files/code/jbicomp.h37
-rw-r--r--common/recipes-utils/jbi/files/code/jbiexprt.h224
-rw-r--r--common/recipes-utils/jbi/files/code/jbijtag.c1675
-rw-r--r--common/recipes-utils/jbi/files/code/jbijtag.h147
-rw-r--r--common/recipes-utils/jbi/files/code/jbimain.c3290
-rw-r--r--common/recipes-utils/jbi/files/code/jbiport.h45
-rw-r--r--common/recipes-utils/jbi/files/code/jbistub.c2222
-rw-r--r--common/recipes-utils/jbi/files/make/Microsoft/nmake.mak65
-rw-r--r--common/recipes-utils/jbi/files/make/PCVS/PVCS16.MAK61
-rw-r--r--common/recipes-utils/jbi/files/make/PCVS/pvcs32.mak61
-rw-r--r--common/recipes-utils/jbi/files/readme.openbmc5
-rw-r--r--common/recipes-utils/jbi/files/readme.txt464
-rw-r--r--common/recipes-utils/jbi/jbi_2.2.bb41
-rw-r--r--common/recipes-utils/openbmc-gpio/files/COPYING340
-rw-r--r--common/recipes-utils/openbmc-gpio/files/board_gpio_table.py23
-rw-r--r--common/recipes-utils/openbmc-gpio/files/openbmc_gpio.py164
-rw-r--r--common/recipes-utils/openbmc-gpio/files/openbmc_gpio_setup.py76
-rw-r--r--common/recipes-utils/openbmc-gpio/files/openbmc_gpio_table.py269
-rw-r--r--common/recipes-utils/openbmc-gpio/files/openbmc_gpio_util.py153
-rw-r--r--common/recipes-utils/openbmc-gpio/files/phymemory.py100
-rw-r--r--common/recipes-utils/openbmc-gpio/files/setup.py36
-rw-r--r--common/recipes-utils/openbmc-gpio/files/soc_gpio.py19
-rw-r--r--common/recipes-utils/openbmc-gpio/files/soc_gpio_table.py23
-rw-r--r--common/recipes-utils/openbmc-gpio/openbmc-gpio_0.1.bb75
-rw-r--r--common/recipes-utils/openbmc-utils/files/COPYING340
-rw-r--r--common/recipes-utils/openbmc-utils/files/openbmc-utils.sh133
-rw-r--r--common/recipes-utils/openbmc-utils/openbmc-utils_0.1.bb48
-rw-r--r--common/recipes-utils/spatula/files/setup-spatula.sh80
-rw-r--r--common/recipes-utils/spatula/files/spatula_wrapper.py120
-rw-r--r--common/recipes-utils/spatula/spatula_0.1.bb47
-rw-r--r--meta-aspeed/recipes-bsp/u-boot/files/patch-2013.07/0002-Create-snapshot-of-OpenBMC.patch1234
-rw-r--r--meta-aspeed/recipes-bsp/u-boot/u-boot-fw-utils_2013.07%.bbappend17
-rw-r--r--meta-aspeed/recipes-bsp/u-boot/u-boot_2013.07%.bbappend14
-rw-r--r--meta-aspeed/recipes-core/images/files/aspeed_device_table3
-rw-r--r--meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0029-Create-snapshot-of-OpenBMC.patch11455
-rw-r--r--meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0029-mtd-m25p80-Add-support-for-the-Winbond-W25Q64.patch29
-rw-r--r--meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0030-net-Don-t-leak-packets-when-a-netns-is-going-down.patch56
-rw-r--r--meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0031-IPv6-Print-error-value-when-skb-allocation-fails.patch43
-rw-r--r--meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0032-Create-snapshot-of-OpenBMC.patch8462
-rw-r--r--meta-aspeed/recipes-kernel/linux/linux-aspeed_2.6.28.9.bb21
-rw-r--r--meta-facebook/meta-wedge/conf/machine/wedge.conf5
-rw-r--r--meta-facebook/meta-wedge/recipes-core/images/wedge-image.inc6
-rw-r--r--meta-facebook/meta-wedge/recipes-core/init-ifupdown/files/dhcpv6_down27
-rw-r--r--meta-facebook/meta-wedge/recipes-core/init-ifupdown/files/dhcpv6_up28
-rw-r--r--meta-facebook/meta-wedge/recipes-core/init-ifupdown/init-ifupdown_%.bbappend16
-rw-r--r--meta-facebook/meta-wedge/recipes-kernel/linux/linux-aspeed_2.6%.bbappend2
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/bmc-log/bmc-log_0.1.bb50
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/bmc-log/files/Makefile24
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/bmc-log/files/bmc-log-config16
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/bmc-log/files/bmc-log.c559
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/bmc-log/files/bmc-log.h46
-rwxr-xr-xmeta-facebook/meta-wedge/recipes-wedge/bmc-log/files/bmc-log.sh77
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/fan-ctrl/fan-ctrl/setup-fan.sh18
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/fan-ctrl/fan-ctrl_0.1.bbappend64
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/fblibs/files/alert_control/Makefile18
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/fblibs/files/ipmi/Makefile18
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/fblibs/libalert-control_0.1.bb16
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/fblibs/libipmi_0.1.bb16
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/fbutils/files/at93cx6.py318
-rwxr-xr-xmeta-facebook/meta-wedge/recipes-wedge/fbutils/files/at93cx6_util.py223
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/fbutils/files/bcm5396.py19
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/fbutils/files/bcm5396_util.py12
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/fbutils/files/board-utils.sh163
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/fbutils/files/create_vlan_intf2
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/fbutils/files/eth0_mac_fixup.sh24
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/fbutils/files/post_led.sh2
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/fbutils/files/power-on.sh2
-rwxr-xr-xmeta-facebook/meta-wedge/recipes-wedge/fbutils/files/power_led.sh2
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/fbutils/files/reset_usb.sh2
-rwxr-xr-xmeta-facebook/meta-wedge/recipes-wedge/fbutils/files/setup-gpio.sh168
-rwxr-xr-xmeta-facebook/meta-wedge/recipes-wedge/fbutils/files/setup_rov.sh2
-rwxr-xr-xmeta-facebook/meta-wedge/recipes-wedge/fbutils/files/sol.sh11
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/fbutils/files/start_us_monitor.sh73
-rwxr-xr-xmeta-facebook/meta-wedge/recipes-wedge/fbutils/files/us_console.sh2
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/fbutils/files/us_monitor.sh56
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/fbutils/files/wedge_power.sh61
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/fbutils/openbmc-utils_%.bbappend95
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/ipmid/files/Makefile16
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/ipmid/files/setup-ipmid.sh16
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/ipmid/ipmid_0.1.bb15
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/lm_sensors/lmsensors_%.bbappend6
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/Makefile16
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/etc/oob-nic.sh10
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/i2craw.c2
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/intf.c2
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/main.c52
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/nic.c94
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/nic_defs.h18
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic_0.1.bb17
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/po-eeprom/files/Makefile16
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/po-eeprom/po-eeprom_0.1.bb17
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/Makefile34
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/hexfile.py174
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/modbus.c181
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/modbus.h47
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/modbuscmd.c152
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/modbussim.c2
-rwxr-xr-xmeta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/psu-update-delta.py269
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/rackmon-config.py93
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/rackmond.c637
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/rackmond.h46
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/rackmondata.c58
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/setup-rackmond.sh20
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon_0.1.bb33
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/rest-api/files/rest.py88
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/rest-api/files/rest_bmc.py10
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/rest-api/files/rest_modbus.py28
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/rest-api/files/rest_sensors.py4
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/rest-api/files/rest_slotid.py33
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/rest-api/files/setup-rest-api.sh16
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/rest-api/rest-api_0.1.bb19
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/sensor-setup/sensor-setup_0.1.bb15
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/sms-kcsd/sms-kcsd/Makefile16
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/sms-kcsd/sms-kcsd/setup-sms-kcs.sh16
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/sms-kcsd/sms-kcsd_0.1.bb15
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/usb-console/usb-console_0.1.bb15
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/files/lib/Makefile18
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/files/lib/wedge_eeprom.c4
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/files/utils/Makefile16
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/files/utils/weutil.c2
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/libwedge-eeprom_0.1.bb18
-rw-r--r--meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/wedge-eeprom_0.1.bb15
-rw-r--r--meta-facebook/meta-yosemite/conf/bblayers.conf.sample21
-rw-r--r--meta-facebook/meta-yosemite/conf/conf-notes.txt2
-rw-r--r--meta-facebook/meta-yosemite/conf/layer.conf10
-rw-r--r--meta-facebook/meta-yosemite/conf/local.conf.sample140
-rw-r--r--meta-facebook/meta-yosemite/conf/machine/yosemite.conf7
-rw-r--r--meta-facebook/meta-yosemite/recipes-core/busybox/busybox/busybox.cfg18
-rw-r--r--meta-facebook/meta-yosemite/recipes-core/busybox/busybox_%.bbappend5
-rw-r--r--meta-facebook/meta-yosemite/recipes-core/images/yosemite-image.bb1
-rw-r--r--meta-facebook/meta-yosemite/recipes-core/images/yosemite-image.inc82
-rw-r--r--meta-facebook/meta-yosemite/recipes-core/init-ifupdown/files/interfaces11
-rw-r--r--meta-facebook/meta-yosemite/recipes-core/init-ifupdown/init-ifupdown_%.bbappend2
-rw-r--r--meta-facebook/meta-yosemite/recipes-core/sysvinit/sysvinit-inittab_%.bbappend2
-rw-r--r--meta-facebook/meta-yosemite/recipes-kernel/linux/linux-aspeed_2.6%.bbappend5
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/bic-cached/bic-cached_0.1.bb44
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/bic-cached/files/Makefile10
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/bic-cached/files/bic-cached.c133
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/bic-cached/files/setup-bic-cached.sh33
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/consoled/consoled_0.1.bbappend53
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/consoled/files/setup-consoled.sh51
-rwxr-xr-xmeta-facebook/meta-yosemite/recipes-yosemite/fan-ctrl/fan-ctrl/get_fan_speed.sh53
-rwxr-xr-xmeta-facebook/meta-yosemite/recipes-yosemite/fan-ctrl/fan-ctrl/init_pwm.sh64
-rwxr-xr-xmeta-facebook/meta-yosemite/recipes-yosemite/fan-ctrl/fan-ctrl/set_fan_speed.sh79
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fan-ctrl/fan-ctrl/setup-fan.sh36
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fan-ctrl/fan-ctrl_0.1.bbappend64
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/Makefile11
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/bic.c466
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/bic.h156
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/Makefile11
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/pal.c1151
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/pal.h98
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/Makefile11
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/yosemite_common.c55
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/yosemite_common.h44
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/Makefile27
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/yosemite_fruid.c86
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/yosemite_fruid.h37
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/Makefile27
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/yosemite_gpio.c116
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/yosemite_gpio.h39
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/Makefile11
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/yosemite_sensor.c778
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/yosemite_sensor.h133
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/libbic_0.1.bb25
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/libpal_0.1.bb28
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/libyosemite-common_0.1.bb25
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/libyosemite-fruid_0.1.bb43
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/libyosemite-gpio_0.1.bb43
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fblibs/libyosemite-sensor_0.1.bb25
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fbutils/bic-util_0.1.bb21
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fbutils/fbutils_0.1.bb102
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/COPYING340
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/ast-functions147
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/at93c46.py276
-rwxr-xr-xmeta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/at93c46_util.py194
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/bcm5396.py452
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/bcm5396_util.py260
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/bic-util/Makefile10
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/bic-util/bic-util.c384
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/create_vlan_intf37
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/eth0_mac_fixup.sh41
-rwxr-xr-xmeta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/fcswitcher.sh83
-rwxr-xr-xmeta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/mdio.py124
-rwxr-xr-xmeta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/mount_data0.sh61
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/post_led.sh105
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/power-on.sh99
-rwxr-xr-xmeta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/power_led.sh58
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/power_util.py151
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/rc.early25
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/rc.local26
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/reset_usb.sh55
-rwxr-xr-xmeta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/setup-gpio.sh307
-rwxr-xr-xmeta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/setup_rov.sh99
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/setup_switch.py49
-rwxr-xr-xmeta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/sol-util74
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/src/include/i2c-dev.h364
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/src/include/log.h59
-rwxr-xr-xmeta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/us_console.sh41
-rwxr-xr-xmeta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/watch-fc.sh34
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/wedge_us_mac.sh29
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/yosemite-sensors/Makefile10
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/yosemite-sensors/yosemite-sensors.c405
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/yosemite_power.sh169
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fbutils/yosemite-sensors_0.1.bb21
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/front-paneld/files/Makefile10
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/front-paneld/files/front-paneld.c460
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/front-paneld/files/setup-front-paneld.sh16
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/front-paneld/front-paneld_0.1.bb44
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/fruid/fruid_0.1.bbappend24
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/gpiod/files/Makefile26
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/gpiod/files/gpiod.c353
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/gpiod/files/setup-gpiod.sh33
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/gpiod/gpiod_0.1.bb62
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/ipmbd/files/setup-ipmbd.sh104
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/ipmbd/ipmbd_0.1.bbappend27
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/ipmid/files/bic.c78
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/ipmid/files/bic.h29
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/ipmid/files/fruid.c111
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/ipmid/files/sensor.c371
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/ipmid/files/setup-ipmid.sh32
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/ipmid/ipmid_0.2.bbappend46
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/lm_sensors/files/yosemite.conf44
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/lm_sensors/lmsensors_%.bbappend10
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/Makefile29
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/README10
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/etc/oob-nic.sh93
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/hlist.h73
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/i2craw.c245
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/intf.c254
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/intf.h31
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/libnetlink.c717
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/libnetlink.h161
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/ll_map.c225
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/ll_map.h32
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/main.c192
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/nic.c487
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/nic.h44
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/nic_defs.h143
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic_0.1.bb44
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/rest-api/files/plat_tree.py84
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/rest-api/files/setup-rest-api.sh32
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/rest-api/rest-api_0.2.bbappend62
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/sensor-mon/files/setup-sensord.sh35
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/sensor-mon/sensor-mon_0.1.bbappend58
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/sensor-setup/files/sensor-setup.sh54
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/sensor-setup/sensor-setup_0.1.bb38
-rwxr-xr-xmeta-facebook/meta-yosemite/recipes-yosemite/usb-console/files/usbcons.sh80
-rwxr-xr-xmeta-facebook/meta-yosemite/recipes-yosemite/usb-console/files/usbmon.sh25
-rw-r--r--meta-facebook/meta-yosemite/recipes-yosemite/usb-console/usb-console_0.1.bb42
342 files changed, 63462 insertions, 316 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index eb35050..6860be0 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -35,3 +35,11 @@ outlined on that page and do not file a public issue.
## Coding Style
* 2 spaces for indentation rather than tabs
* 80 character line length
+
+## License
+OpenBMC is made up of different packages. Each package contains recipe files
+that detail where to fetch source code from third party sources or local
+directories. The recipe files themselves are provided under the GPLv2
+license, but your use of the code fetched by each recipe file is subject to
+the licenses of each respective third party project or as defined in the local
+directory.
diff --git a/common/recipes-connectivity/lldp-util/lldp-util/src/LICENSE b/common/recipes-connectivity/lldp-util/lldp-util/src/LICENSE
new file mode 100644
index 0000000..a1dd699
--- /dev/null
+++ b/common/recipes-connectivity/lldp-util/lldp-util/src/LICENSE
@@ -0,0 +1,30 @@
+BSD License
+
+For OpenBMC lldp-util software
+
+Copyright (c) 2015-present, Facebook, Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name Facebook nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/common/recipes-connectivity/lldp-util/lldp-util/src/Makefile b/common/recipes-connectivity/lldp-util/lldp-util/src/Makefile
new file mode 100644
index 0000000..8dfacfb
--- /dev/null
+++ b/common/recipes-connectivity/lldp-util/lldp-util/src/Makefile
@@ -0,0 +1,19 @@
+# Copyright 2014-present Facebook. All Rights Reserved.
+all: lldp-util
+
+# Yocto overrides anything we do to CFLAGS using "make -e",
+# so use our own EXTRA_CFLAGS variable instead of CFLAGS.
+EXTRA_CFLAGS = -std=gnu99 -Wall -Wextra -Werror \
+ -Wno-unused -Wno-unused-parameter
+
+lldp-util: lldp_util.o
+ $(CC) -o $@ $^ $(LDFLAGS)
+
+%.o: %.c
+ @echo $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
+ $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o lldp-util
diff --git a/common/recipes-connectivity/lldp-util/lldp-util/src/PATENTS b/common/recipes-connectivity/lldp-util/lldp-util/src/PATENTS
new file mode 100644
index 0000000..97e8932
--- /dev/null
+++ b/common/recipes-connectivity/lldp-util/lldp-util/src/PATENTS
@@ -0,0 +1,23 @@
+Additional Grant of Patent Rights
+
+"Software" means the OpenBMC lldp-util software distributed by Facebook, Inc.
+
+Facebook hereby grants you a perpetual, worldwide, royalty-free, non-exclusive,
+irrevocable (subject to the termination provision below) license under any
+rights in any patent claims owned by Facebook, to make, have made, use, sell,
+offer to sell, import, and otherwise transfer the Software. For avoidance of
+doubt, no license is granted under Facebook’s rights in any patent claims that
+are infringed by (i) modifications to the Software made by you or a third party,
+or (ii) the Software in combination with any software or other technology
+provided by you or a third party.
+
+The license granted hereunder will terminate, automatically and without notice,
+for anyone that makes any claim (including by filing any lawsuit, assertion or
+other action) alleging (a) direct, indirect, or contributory infringement or
+inducement to infringe any patent: (i) by Facebook or any of its subsidiaries or
+affiliates, whether or not such claim is related to the Software, (ii) by any
+party if such claim arises in whole or in part from any software, product or
+service of Facebook or any of its subsidiaries or affiliates, whether or not
+such claim is related to the Software, or (iii) by any party relating to the
+Software; or (b) that any right in any patent claim of Facebook is invalid or
+unenforceable.
diff --git a/common/recipes-connectivity/lldp-util/lldp-util/src/lldp_util.c b/common/recipes-connectivity/lldp-util/lldp-util/src/lldp_util.c
new file mode 100644
index 0000000..a4ffc11
--- /dev/null
+++ b/common/recipes-connectivity/lldp-util/lldp-util/src/lldp_util.c
@@ -0,0 +1,703 @@
+/*
+ * Copyright 2004-present Facebook. All Rights Reserved.
+ *
+ * A simple utility for printing LLDP and CDP packets received on an interface.
+ * Eventually it might be worth replacing this with lldpd or lldpad,
+ * but for now this provides a simple standalone script that can be dropped
+ * onto a system and run on an as-needed basis.
+ */
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <linux/filter.h>
+#include <linux/if_ether.h>
+#include <netpacket/packet.h>
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <assert.h>
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+// The minimum ethernet frame length, without the 4-byte frame check sequence
+#define MIN_FRAME_LENGTH 60
+#define MAX_FRAME_LENGTH 9000
+
+#define ETHERTYPE_VLAN 0x8100
+#define ETHERTYPE_LLDP 0x88CC
+
+#define LLDP_CHASSIS_CDP 0xff
+#define LLDP_CHASSIS_MAC_ADDRESS 4
+#define LLDP_CHASSIS_NET_ADDRESS 5
+
+#define LLDP_PORT_CDP 0xff
+#define LLDP_PORT_MAC_ADDRESS 3
+#define LLDP_PORT_NET_ADDRESS 4
+
+#define LLDP_TYPE_END 0
+#define LLDP_TYPE_CHASSIS_ID 1
+#define LLDP_TYPE_PORT_ID 2
+#define LLDP_TYPE_SYSTEM_NAME 5
+
+#define CDP_TYPE_DEVICE_ID 1
+#define CDP_TYPE_PORT_ID 3
+#define CDP_TYPE_SYSTEM_NAME 20
+
+static const unsigned char MAC_LLDP_NEAREST_BRIDGE[] =
+ { 0x01, 0x80, 0xc2, 0x00, 0x00,0x0e };
+static const unsigned char MAC_CDP[] =
+ { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc };
+
+static bool verbose = false;
+
+void errmsg(const char* fmt, ...) __attribute__((format(printf, 1, 2)));
+void debugmsg(const char* fmt, ...) __attribute__((format(printf, 1, 2)));
+
+void errmsg(const char* fmt, ...) {
+ va_list ap;
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ fputc('\n', stderr);
+ va_end(ap);
+}
+
+void debugmsg(const char* fmt, ...) {
+ if (!verbose) {
+ return;
+ }
+
+ va_list ap;
+ va_start(ap, fmt);
+ fputs("DEBUG: ", stderr);
+ vfprintf(stderr, fmt, ap);
+ fputc('\n', stderr);
+ va_end(ap);
+}
+
+#define FAIL_ERRNO(msg, ...) \
+ do { \
+ returnCode = -errno; \
+ errmsg((msg), ##__VA_ARGS__); \
+ goto error; \
+ } while (0)
+
+#define CHECK_ERROR(rc, msg, ...) \
+ do { if ((rc) == -1) { FAIL_ERRNO((msg), ##__VA_ARGS__); } } while (0)
+
+typedef struct {
+ const char* protocol;
+ const char* local_interface;
+ const uint8_t* src_mac;
+ const uint8_t* chassis_id;
+ const uint8_t* port_id;
+ const uint8_t* system_name;
+ uint32_t chassis_id_length;
+ uint32_t port_id_length;
+ uint32_t system_name_length;
+ uint8_t chassis_id_type;
+ uint8_t port_id_type;
+} lldp_neighbor_t;
+
+
+#define DFLT_MAX_SAV_CDP 10
+
+typedef struct {
+ uint8_t *cdp_buf;
+ size_t length;
+} cdp_frame_t;
+
+typedef struct {
+ int max_sav_cdp; // max # cdp frames to save
+ int num_sav_cdp; // number currently saved
+ cdp_frame_t* frame; // saved CDP frames
+} cdp_sav_data_t;
+
+cdp_sav_data_t cdp_sav_data;
+
+volatile sig_atomic_t g_interrupt; // set in exit handler
+
+void lldp_neighbor_init(lldp_neighbor_t* neighbor,
+ const char* protocol,
+ const char* interface,
+ const uint8_t* src_mac) {
+ memset(neighbor, 0, sizeof(*neighbor));
+ neighbor->protocol = protocol;
+ neighbor->local_interface = interface;
+ neighbor->src_mac = src_mac;
+}
+
+int lldp_open(const char* interface) {
+ int fd = -1;
+ int returnCode = -EINVAL;
+
+ {
+ fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+ if (fd < 0) {
+ FAIL_ERRNO("failed to create socket for local interface %s", interface);
+ }
+
+ // Look up the interface index
+ struct ifreq ifr;
+ snprintf(ifr.ifr_name, IFNAMSIZ, interface);
+ int rc = ioctl(fd, SIOCGIFINDEX, &ifr);
+ CHECK_ERROR(rc, "failed to get interface index for %s", interface);
+
+ // Bind the socket
+ struct sockaddr_ll addr;
+ addr.sll_family = AF_PACKET;
+ addr.sll_ifindex = ifr.ifr_ifindex;
+ addr.sll_protocol = htons(ETH_P_ALL);
+ rc = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
+ CHECK_ERROR(rc, "failed to bind socket for %s", interface);
+
+ // Ask linux to also send us packets sent to LLDP "nearest bridge"
+ // multicast MAC address
+ struct packet_mreq mr;
+ memset(&mr, 0, sizeof(mr));
+ mr.mr_ifindex = ifr.ifr_ifindex;
+ mr.mr_alen = ETH_ALEN;
+ memcpy(mr.mr_address, MAC_LLDP_NEAREST_BRIDGE, ETH_ALEN);
+ mr.mr_type = PACKET_MR_MULTICAST;
+ rc = setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr));
+ CHECK_ERROR(rc, "failed to add LLDP packet membership for %s", interface);
+
+ // Ask linux to also send us packets sent to the CDP multicast MAC address
+ memcpy(mr.mr_address, MAC_CDP, ETH_ALEN);
+ rc = setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr));
+ CHECK_ERROR(rc, "failed to add CDP packet membership for %s", interface);
+
+ // Set a filter to ignore non-multicast packets, so we don't get a flood
+ // of meaningless packets that we don't care about.
+ //
+ // tcpdump -i eth0 -dd ether multicast
+ static struct sock_filter PACKET_FILTER[] = {
+ { 0x30, 0, 0, 0x00000000 },
+ { 0x45, 0, 1, 0x00000001 },
+ { 0x6, 0, 0, 0x0000ffff },
+ { 0x6, 0, 0, 0x00000000 },
+ };
+ struct sock_fprog bpf;
+ bpf.len = sizeof(PACKET_FILTER) / sizeof(PACKET_FILTER[0]);
+ bpf.filter = PACKET_FILTER;
+ rc = setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf));
+ CHECK_ERROR(rc, "failed to set socket packet filter for %s", interface);
+
+ returnCode = fd;
+ goto cleanup;
+ }
+
+error:
+ assert(returnCode < 0);
+ if (fd != -1) {
+ close(fd);
+ }
+
+cleanup:
+ return returnCode;
+}
+
+void lldp_print_value(const uint8_t* buf, uint32_t length) {
+ int n;
+
+ bool add_quotes = false;
+ for (uint32_t n = 0; n < length; ++n) {
+ uint8_t value = buf[n];
+ if (value < 0x20 || value >= 0x7f || isspace(value)) {
+ add_quotes = true;
+ break;
+ }
+ }
+
+ if (add_quotes) {
+ putchar('"');
+ }
+ for (uint32_t n = 0; n < length; ++n) {
+ uint8_t value = buf[n];
+
+ // Ignore trailing NUL characters
+ if (value == 0 && n + 1 == length) {
+ break;
+ }
+
+ if (value == '"' || value == '\\') {
+ putchar('\\');
+ putchar(value);
+ } else if (value >= 0x20 && value < 0x7f) {
+ putchar(value);
+ } else {
+ printf("\\x%02x", value);
+ }
+ }
+ if (add_quotes) {
+ putchar('"');
+ }
+}
+
+void lldp_print_mac(const uint8_t* buf, uint32_t length) {
+ if (length != 6) {
+ fputs("<bad_mac:", stdout);
+ lldp_print_value(buf, length);
+ putchar('>');
+ return;
+ }
+
+ printf("%02x:%02x:%02x:%02x:%02x:%02x",
+ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
+}
+
+void lldp_print_net_addr(const uint8_t* buf, uint32_t length) {
+ if (length < 1) {
+ return;
+ }
+
+ if (buf[0] == 1 && length == 5) {
+ // IPv4
+ struct in_addr addr;
+ memcpy(&addr.s_addr, buf + 1, length - 1);
+
+ char str[INET_ADDRSTRLEN];
+ if (inet_ntop(AF_INET, &addr, str, sizeof(str)) != NULL) {
+ fputs(str, stdout);
+ return;
+ }
+ } else if (buf[0] == 2 && length == 17) {
+ struct in6_addr addr;
+ memcpy(&addr.s6_addr, buf + 1, length - 1);
+
+ char str[INET6_ADDRSTRLEN];
+ if (inet_ntop(AF_INET6, &addr, str, sizeof(str)) != NULL) {
+ fputs(str, stdout);
+ return;
+ }
+ }
+
+ // If we are still here, this wasn't IPv4 or IPv6, or we failed to parse it.
+ printf("<net_addr:%d:", buf[0]);
+ lldp_print_value(buf + 1, length - 1);
+ putchar('>');
+}
+
+void lldp_print_neighbor(lldp_neighbor_t* neighbor) {
+ fprintf(stdout, "%s: local_port=%s",
+ neighbor->protocol, neighbor->local_interface);
+ fputs(" remote_system=", stdout);
+ if (neighbor->system_name) {
+ lldp_print_value(neighbor->system_name, neighbor->system_name_length);
+ } else if (neighbor->chassis_id_type == LLDP_CHASSIS_MAC_ADDRESS) {
+ lldp_print_mac(neighbor->chassis_id, neighbor->chassis_id_length);
+ } else if (neighbor->chassis_id_type == LLDP_CHASSIS_NET_ADDRESS) {
+ lldp_print_net_addr(neighbor->chassis_id, neighbor->chassis_id_length);
+ } else {
+ lldp_print_value(neighbor->chassis_id, neighbor->chassis_id_length);
+ }
+
+ fputs(" remote_port=", stdout);
+ if (neighbor->port_id_type == LLDP_PORT_MAC_ADDRESS) {
+ lldp_print_mac(neighbor->port_id, neighbor->port_id_length);
+ } else if (neighbor->port_id_type == LLDP_PORT_NET_ADDRESS) {
+ lldp_print_net_addr(neighbor->port_id, neighbor->port_id_length);
+ } else {
+ lldp_print_value(neighbor->port_id, neighbor->port_id_length);
+ }
+ putchar('\n');
+}
+
+uint16_t lldp_read_u16(const uint8_t** buf) {
+ // Use memcpy() to comply with strict-aliasing rules.
+ // The compiler will optimize this away anyway.
+ uint16_t result;
+ memcpy(&result, *buf, 2);
+ (*buf) += 2;
+ return htons(result);
+}
+
+int lldp_parse_lldp(lldp_neighbor_t* neighbor,
+ const uint8_t* buf,
+ const uint8_t* end) {
+ while (buf < end) {
+ // Parse the type (7 bits) and length (9 bits)
+ if ((end - buf) < 2) {
+ errmsg("LLDPDU truncated in tag/length header");
+ return -EINVAL;
+ }
+ uint16_t length = lldp_read_u16(&buf);
+ uint16_t type = (length >> 9);
+ length &= 0x01ff;
+
+ if ((end - buf) < length) {
+ errmsg("LLDPDU truncated inside field of type %d: "
+ "field_length=%d, remaining=%d", type, length, end - buf);
+ return -EINVAL;
+ }
+
+ if (type == LLDP_TYPE_CHASSIS_ID) {
+ if (length < 1) {
+ errmsg("LLDPDU with invalid chassis ID length %d", length);
+ return -EINVAL;
+ }
+ neighbor->chassis_id_type = buf[0];
+ neighbor->chassis_id = buf + 1;
+ neighbor->chassis_id_length = length - 1;
+ } else if (type == LLDP_TYPE_PORT_ID) {
+ if (length < 1) {
+ errmsg("LLDPDU with invalid port ID length %d", length);
+ return -EINVAL;
+ }
+ neighbor->port_id_type = buf[0];
+ neighbor->port_id = buf + 1;
+ neighbor->port_id_length = length - 1;
+ } else if (type == LLDP_TYPE_SYSTEM_NAME) {
+ neighbor->system_name = buf;
+ neighbor->system_name_length = length;
+ }
+
+ buf += length;
+
+ if (type == LLDP_TYPE_END) {
+ break;
+ }
+ }
+
+ if (!neighbor->chassis_id) {
+ errmsg("received LLDPDU with missing chassis ID");
+ return -EINVAL;
+ }
+ if (!neighbor->port_id) {
+ errmsg("received LLDPDU with missing port ID");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int lldp_parse_cdp(lldp_neighbor_t* neighbor,
+ const uint8_t* buf,
+ const uint8_t* end) {
+ // Skip over some initial headers:
+ // 1 byte DSAP
+ // 1 byte SSAP
+ // 1 byte LLC control field
+ // 3 byte SNAP vendor code
+ // 2 byte SNAP local code
+ // 1 byte CDP version
+ // 1 byte TTL
+ // 2 byte checksum
+ if ((end - buf) < 12) {
+ errmsg("CDP PDU truncated in initial headers: length=%d", end - buf);
+ return -EINVAL;
+ }
+ buf += 8;
+ uint8_t cdp_version = *buf;
+ if (cdp_version != 2) {
+ // We only support CDP version 2 for now.
+ debugmsg("ignoring unsupported CDP PDU with version %d", cdp_version);
+ return -EPFNOSUPPORT;
+ }
+ buf += 4;
+
+ while (buf < end) {
+ if ((end - buf) < 4) {
+ errmsg("CDP PDU truncated in tag/length header");
+ return -EINVAL;
+ }
+ uint16_t type = lldp_read_u16(&buf);
+ uint16_t length = lldp_read_u16(&buf);
+
+ if (length < 4) {
+ errmsg("CDP PDU with bad length=%d for field of type %d",
+ length, type);
+ return -EINVAL;
+ }
+ length -= 4;
+ if ((end - buf) < length) {
+ errmsg("CDP PDU truncated inside field of type %d: "
+ "field_length=%d, remaining=%d", type, length, end - buf);
+ return -EINVAL;
+ }
+
+ if (type == CDP_TYPE_DEVICE_ID) {
+ neighbor->chassis_id_type = LLDP_CHASSIS_CDP;
+ neighbor->chassis_id = buf;
+ neighbor->chassis_id_length = length;
+ } else if (type == CDP_TYPE_PORT_ID) {
+ neighbor->port_id_type = LLDP_PORT_CDP;
+ neighbor->port_id = buf;
+ neighbor->port_id_length = length;
+ } else if (type == CDP_TYPE_SYSTEM_NAME) {
+ neighbor->system_name = buf;
+ neighbor->system_name_length = length;
+ }
+ buf += length;
+ }
+
+ if (!neighbor->chassis_id) {
+ errmsg("received CDP PDU with missing device ID");
+ return -EINVAL;
+ }
+ if (!neighbor->port_id) {
+ errmsg("received CDP PDU with missing port ID");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int lldp_process_packet(const uint8_t* buf,
+ size_t length,
+ const char* interface,
+ bool process_cdp,
+ bool* processed) {
+ int returnCode = -EINVAL;
+ *processed = false;
+
+ {
+ // Bail if the minimum ethernet frame size is not met
+ if (length < MIN_FRAME_LENGTH) {
+ errmsg("received too-short frame on interface %s: length=%d",
+ interface, length);
+ returnCode = -EINVAL;
+ goto error;
+ }
+
+ const uint8_t* buf_start = buf;
+ const uint8_t* end = buf + length;
+
+ const uint8_t* dest_mac = buf;
+ buf += 6;
+ const uint8_t* src_mac = buf;
+ buf += 6;
+ uint16_t ethertype = lldp_read_u16(&buf);
+
+ if (ethertype == ETHERTYPE_VLAN) {
+ uint16_t vlan = lldp_read_u16(&buf);
+ ethertype = lldp_read_u16(&buf);
+ }
+
+ if (ethertype == ETHERTYPE_LLDP) {
+ lldp_neighbor_t neighbor;
+ lldp_neighbor_init(&neighbor, "LLDP", interface, src_mac);
+ returnCode = lldp_parse_lldp(&neighbor, buf, end);
+ if (returnCode != 0) {
+ goto error;
+ }
+ lldp_print_neighbor(&neighbor);
+ fflush(stdout);
+ *processed = true;
+ } else if ((memcmp(dest_mac, MAC_CDP, 6) == 0) && (ethertype < 0x600)) {
+ if (process_cdp) {
+ lldp_neighbor_t neighbor;
+ lldp_neighbor_init(&neighbor, "CDP", interface, src_mac);
+ returnCode = lldp_parse_cdp(&neighbor, buf, end);
+ if (returnCode != 0) {
+ goto error;
+ }
+ lldp_print_neighbor(&neighbor);
+ fflush(stdout);
+ *processed = true;
+ } else if (cdp_sav_data.num_sav_cdp < cdp_sav_data.max_sav_cdp) {
+ cdp_sav_data.frame[cdp_sav_data.num_sav_cdp].cdp_buf = malloc(length);
+ assert(cdp_sav_data.frame[cdp_sav_data.num_sav_cdp].cdp_buf);
+ memcpy(cdp_sav_data.frame[cdp_sav_data.num_sav_cdp].cdp_buf, buf_start,
+ length);
+ cdp_sav_data.frame[cdp_sav_data.num_sav_cdp].length = length;
+ cdp_sav_data.num_sav_cdp++;
+ }
+ } else {
+ // Some other packet type that we don't care about.
+ debugmsg("Ignored packet on %s: ethertype=0x%04x",
+ interface, ethertype);
+ }
+
+ returnCode = 0;
+ goto cleanup;
+ }
+
+error:
+ assert(returnCode < 0);
+cleanup:
+ return returnCode;
+}
+
+int lldp_receive(int fd, const char* interface, bool cdp, bool* processed) {
+ int returnCode = -EINVAL;
+ *processed = false;
+ {
+ uint8_t buf[MAX_FRAME_LENGTH];
+
+ struct sockaddr_ll src_addr;
+ socklen_t addr_len;
+ ssize_t len = recvfrom(fd, buf, MAX_FRAME_LENGTH, 0,
+ (struct sockaddr*)&src_addr, &addr_len);
+ if (len == -1) {
+ if (errno != EINTR) {
+ errmsg("error reading packet from %s", interface);
+ }
+ returnCode = -errno;
+ goto error;
+ }
+
+ returnCode = lldp_process_packet(buf, len, interface, cdp, processed);
+ goto cleanup;
+ }
+
+error:
+ assert(returnCode < 0);
+cleanup:
+ return returnCode;
+}
+
+void exit_handler(int signum) {
+ g_interrupt = true;
+}
+
+void usage_short(FILE* out) {
+ fprintf(out, "lldp-util [-h] [-c] [-i <interface>] "
+ "[-n <count>] [-t <timeout>]\n");
+}
+
+void usage_full(FILE* out) {
+ usage_short(out);
+ fprintf(out,
+ "\n"
+ " -c Report CDP packets as they arrive in addition "
+ "to LLDP\n"
+ " -h Show this help message and exit\n"
+ " -i <interface> Specify the interface to listen on\n"
+ " -n <count> Exit after receiving <count> LLDP packets\n"
+ " -t <timeout> Exit after <timeout> seconds\n"
+ " Negative or 0 means no timeout\n"
+ "\n"
+ "If neither -n nor -t are specified, lldp-util uses a 65 second\n"
+ "timeout by default\n"
+ );
+}
+
+int main(int argc, char* argv[]) {
+ const char* interface = "eth0";
+ long timeout = 0;
+ bool has_timeout = false;
+ long max_count = 0;
+ bool has_max_count = false;
+ bool inline_cdp = false;
+
+ while (true) {
+ int opt = getopt(argc, argv, "chi:n:t:");
+ if (opt == -1) {
+ break;
+ }
+ switch (opt) {
+ case 'c':
+ inline_cdp = true;
+ break;
+ case 'h':
+ usage_full(stdout);
+ return 0;
+ case 'i':
+ interface = optarg;
+ break;
+ case 'n': {
+ char* end;
+ max_count = strtol(optarg, &end, 10);
+ if (end == optarg || *end != '\0') {
+ fprintf(stderr, "error: bad count value: must be an integer\n");
+ return 1;
+ }
+ has_max_count = true;
+ break;
+ }
+ case 't': {
+ char* end;
+ timeout = strtol(optarg, &end, 10);
+ if (end == optarg || *end != '\0') {
+ fprintf(stderr, "error: bad timeout value: must be an integer\n");
+ return 1;
+ }
+ has_timeout = true;
+ break;
+ }
+ default:
+ usage_short(stderr);
+ return 1;
+ }
+ }
+
+ // Default to a 65 second timeout if no other limits were specified.
+ if (!has_max_count && !has_timeout) {
+ timeout = 65;
+ }
+
+ int fd = lldp_open(interface);
+ if (fd < 0) {
+ return 1;
+ }
+
+ struct sigaction sa;
+
+ // Clear all fields in sa. In particular, SA_RESTART must not be set in
+ // sa_flags field because we want recvfrom to be interrupted.
+ memset(&sa, 0, sizeof(sa));
+
+ sa.sa_handler = exit_handler;
+ sigaction(SIGINT, &sa, NULL);
+ sigaction(SIGTERM, &sa, NULL);
+
+ // Automatically stop after 65 seconds
+ if (timeout > 0) {
+ sigaction(SIGALRM, &sa, NULL);
+ alarm(timeout);
+ }
+
+ // In the case when we are asked not to report CDP packets as they arrive,
+ // we will save them in a global buffer. On exiting, if we have not seen
+ // any LLDP packets, we'll dump the CDP packets that arrived.
+ if (!inline_cdp) {
+ if (max_count > 0) {
+ cdp_sav_data.max_sav_cdp = max_count;
+ } else {
+ cdp_sav_data.max_sav_cdp = DFLT_MAX_SAV_CDP;
+ }
+ cdp_sav_data.frame = malloc(sizeof(cdp_frame_t) *
+ cdp_sav_data.max_sav_cdp);
+ if (cdp_sav_data.frame == NULL) {
+ printf("memory allocation failed for saved frames\n");
+ exit(1);
+ }
+ }
+
+ printf("Listening for LLDP packets...\n");
+ fflush(stdout);
+ long count = 0;
+ bool processed;
+ while (true) {
+ lldp_receive(fd, interface, inline_cdp, &processed);
+ if (processed) {
+ ++count;
+ if (max_count > 0 && count >= max_count) {
+ break;
+ }
+ }
+ if (g_interrupt) {
+ break;
+ }
+ }
+
+ // Print saved CDP packets if we haven't printed anything yet
+ if (count == 0) {
+ for (int i = 0; i < cdp_sav_data.num_sav_cdp; i++) {
+ lldp_process_packet(cdp_sav_data.frame[i].cdp_buf,
+ cdp_sav_data.frame[i].length,
+ interface, true, &processed);
+ }
+ }
+
+ return 0;
+}
diff --git a/common/recipes-connectivity/lldp-util/lldp-util_0.1.bb b/common/recipes-connectivity/lldp-util/lldp-util_0.1.bb
new file mode 100644
index 0000000..eb53e9a
--- /dev/null
+++ b/common/recipes-connectivity/lldp-util/lldp-util_0.1.bb
@@ -0,0 +1,21 @@
+# Copyright 2014-present Facebook. All Rights Reserved.
+
+SUMMARY = "LLDP Utility"
+DESCRIPTION = "A utility for reporting LLDP information"
+SECTION = "base"
+PR = "r1"
+LICENSE = "BSD"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=cc7ed73f378cc0ea228aebab24237853 \
+ file://PATENTS;md5=aed2575e5dba9ba3aea25cfeddb8f1d2 "
+
+SRC_URI = "file://src \
+ "
+
+S = "${WORKDIR}/src"
+
+do_install() {
+ install -d ${D}${bindir}
+ install -m 755 lldp-util ${D}${bindir}
+}
+
+FILES_${PN} = " ${bindir} "
diff --git a/common/recipes-core/base-files/base-files_%.bbappend b/common/recipes-core/base-files/base-files_%.bbappend
index 340ad2c..6a73f2b 100644
--- a/common/recipes-core/base-files/base-files_%.bbappend
+++ b/common/recipes-core/base-files/base-files_%.bbappend
@@ -15,8 +15,8 @@ do_install_bmc_issue () {
dir=$(dirname $dir)
done
- if [ -d "$dir/meta-aspeed/.git" ]; then
- srcdir="$dir/meta-aspeed"
+ if [ -d "$dir/meta-openbmc/.git" ]; then
+ srcdir="$dir/meta-openbmc"
srcdir_git="${srcdir}/.git"
version=$(git --git-dir=${srcdir_git} --work-tree=${srcdir} describe --dirty 2> /dev/null)
else
diff --git a/common/recipes-core/cfg-util/cfg-util_0.1.bb b/common/recipes-core/cfg-util/cfg-util_0.1.bb
new file mode 100644
index 0000000..13b6568
--- /dev/null
+++ b/common/recipes-core/cfg-util/cfg-util_0.1.bb
@@ -0,0 +1,36 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+SUMMARY = "Configuration Utility"
+DESCRIPTION = "Utility for reading or writing configuration"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://cfg-util.c;beginline=4;endline=16;md5=b395943ba8a0717a83e62ca123a8d238"
+
+SRC_URI = "file://Makefile \
+ file://cfg-util.c \
+ "
+S = "${WORKDIR}"
+
+LDFLAGS =+ " -lpal "
+
+DEPENDS =+ " libpal "
+
+binfiles = "cfg-util"
+
+pkgdir = "cfg-util"
+
+do_install() {
+ dst="${D}/usr/local/fbpackages/${pkgdir}"
+ bin="${D}/usr/local/bin"
+ install -d $dst
+ install -d $bin
+ install -m 755 cfg-util ${dst}/cfg-util
+ ln -snf ../fbpackages/${pkgdir}/cfg-util ${bin}/cfg-util
+}
+
+FBPACKAGEDIR = "${prefix}/local/fbpackages"
+
+FILES_${PN} = "${FBPACKAGEDIR}/cfg-util ${prefix}/local/bin"
+
+INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
+INHIBIT_PACKAGE_STRIP = "1"
diff --git a/common/recipes-core/cfg-util/files/Makefile b/common/recipes-core/cfg-util/files/Makefile
new file mode 100644
index 0000000..05b9b16
--- /dev/null
+++ b/common/recipes-core/cfg-util/files/Makefile
@@ -0,0 +1,11 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+all: cfg-util
+
+
+cfg-util: cfg-util.o
+ $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o cfg-util
diff --git a/common/recipes-core/cfg-util/files/cfg-util.c b/common/recipes-core/cfg-util/files/cfg-util.c
new file mode 100644
index 0000000..99618f7
--- /dev/null
+++ b/common/recipes-core/cfg-util/files/cfg-util.c
@@ -0,0 +1,78 @@
+/*
+ * cfg-util
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <string.h>
+#include <openbmc/pal.h>
+
+static void
+print_usage(void) {
+ printf("Usage: cfg-util <dump-all|key> <value>\n");
+}
+
+int
+main(int argc, char **argv) {
+
+ int ret;
+ uint8_t key[MAX_KEY_LEN] = {0};
+ uint8_t val[MAX_VALUE_LEN] = {0};
+
+ // Handle boundary checks
+ if (argc < 2 || argc > 3) {
+ goto err_exit;
+ }
+
+ // Handle dump of key value data base
+ if ((argc == 2) && (!strcmp(argv[1], "dump-all"))){
+ pal_dump_key_value();
+ return 0;
+ }
+
+ // Handle Get the Configuration
+ if (argc == 2) {
+ snprintf(key, MAX_KEY_LEN, "%s", argv[1]);
+
+ ret = pal_get_key_value(key, val);
+ if (ret) {
+ goto err_exit;
+ }
+
+ printf("%s\n", val);
+ return 0;
+ }
+
+ // Handle Set the configuration
+ snprintf(key, MAX_KEY_LEN, "%s", argv[1]);
+ snprintf(val, MAX_VALUE_LEN, "%s", argv[2]);
+
+ ret = pal_set_key_value(key, val);
+ if (ret) {
+ goto err_exit;
+ }
+
+ return 0;
+
+err_exit:
+ print_usage();
+ exit(-1);
+}
diff --git a/common/recipes-core/consoled/consoled_0.1.bb b/common/recipes-core/consoled/consoled_0.1.bb
new file mode 100644
index 0000000..5b6edd1
--- /dev/null
+++ b/common/recipes-core/consoled/consoled_0.1.bb
@@ -0,0 +1,36 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+SUMMARY = "Serial Buffer"
+DESCRIPTION = "Daemon for serial buffering"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://consoled.c;beginline=4;endline=16;md5=b395943ba8a0717a83e62ca123a8d238"
+
+SRC_URI = "file://Makefile \
+ file://consoled.c \
+ "
+S = "${WORKDIR}"
+
+LDFLAGS =+ " -lpal "
+
+DEPENDS =+ " libpal "
+
+binfiles = "consoled"
+
+pkgdir = "consoled"
+
+do_install() {
+ dst="${D}/usr/local/fbpackages/${pkgdir}"
+ bin="${D}/usr/local/bin"
+ install -d $dst
+ install -d $bin
+ install -m 755 consoled ${dst}/consoled
+ ln -snf ../fbpackages/${pkgdir}/consoled ${bin}/consoled
+}
+
+FBPACKAGEDIR = "${prefix}/local/fbpackages"
+
+FILES_${PN} = "${FBPACKAGEDIR}/consoled ${prefix}/local/bin"
+
+INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
+INHIBIT_PACKAGE_STRIP = "1"
diff --git a/common/recipes-core/consoled/files/Makefile b/common/recipes-core/consoled/files/Makefile
new file mode 100644
index 0000000..2b30ef2
--- /dev/null
+++ b/common/recipes-core/consoled/files/Makefile
@@ -0,0 +1,11 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+all: consoled
+
+
+consoled: consoled.o
+ $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o consoled
diff --git a/common/recipes-core/consoled/files/consoled.c b/common/recipes-core/consoled/files/consoled.c
new file mode 100644
index 0000000..9f17e31
--- /dev/null
+++ b/common/recipes-core/consoled/files/consoled.c
@@ -0,0 +1,284 @@
+/*
+ * consoled
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <termios.h>
+#include <signal.h>
+#include <openbmc/pal.h>
+
+#define BAUDRATE B57600
+#define CTRL_X 0x18
+#define ASCII_ENTER 0x0D
+
+static sig_atomic_t sigexit = 0;
+
+static void
+write_data(int file, char *buf, int len, char *fname) {
+ int wlen = 0;
+ char *tbuf = buf;
+ while(len > 0) {
+ errno = 0;
+ wlen = write(file, tbuf, len);
+ // In case wlen < 0, retry write()
+ if (wlen >= 0) {
+ len -= wlen;
+ tbuf = tbuf + wlen;
+ } else {
+ syslog(LOG_ALERT, "write_data: write() failed to file %s | errno: %d",
+ fname, errno);
+ return;
+ }
+ }
+}
+
+static void
+exit_session(int sig)
+{
+ sigexit = sig;
+}
+
+static void
+print_usage() {
+ printf("Usage: consoled [ %s ]\n", pal_server_list);
+}
+
+static void
+run_console(char* fru_name, int term) {
+
+ int i;
+ int tty; // serial port
+ int buf_fd; // Buffer File
+ int blen; // len for
+ int nfd = 0; // For number of fd
+ int nevents; // For number of events in fd
+ int nline = 0;
+ //int pid_fd;
+ int flags;
+ pid_t pid; // For pid of the daemon
+ uint8_t fru;
+ char in; // For stdin character
+ char data[32];
+ char pid_file[64];
+ char devtty[32]; // For tty dev path
+ char bfname[32]; // For buffer file path
+ char old_bfname[32]; // For old buffer file path
+ char buf[256]; // For buffer data
+ struct termios ottytio, nttytio; // For the tty dev
+
+ int stdi; // STDIN_FILENO
+ int stdo; // STDOUT_FILENO
+ struct termios ostditio, nstditio; // For STDIN_FILENO
+ struct termios ostdotio, nstdotio; // For STDOUT_FILENO
+
+ struct pollfd pfd[2];
+
+ /* Start Daemon for the console buffering */
+ if (!term) {
+ daemon(0,1);
+ openlog("consoled", LOG_CONS, LOG_DAEMON);
+ syslog(LOG_INFO, "consoled: daemon started");
+ }
+
+ if (pal_get_fru_id(fru_name, &fru)) {
+ exit(-1);
+ }
+
+ if (pal_get_fru_devtty(fru, devtty)) {
+ exit(-1);
+ }
+
+ /* Handling the few Signals differently */
+ signal(SIGHUP, exit_session);
+ signal(SIGINT, exit_session);
+ signal(SIGTERM, exit_session);
+ signal(SIGPIPE, exit_session);
+ signal(SIGQUIT, exit_session);
+
+ /* Different flag value for tty dev */
+ flags = term == 1 ? (O_RDWR | O_NOCTTY | O_NONBLOCK) :
+ (O_RDONLY | O_NOCTTY | O_NONBLOCK);
+
+ if ((tty = open(devtty, flags)) < 0) {
+ syslog(LOG_ALERT, "Cannot open the file %s", devtty);
+ exit(-1);
+ }
+ fcntl(tty, F_SETFL, O_RDWR);
+
+ /* Changing the attributes of the tty dev */
+ tcgetattr(tty, &ottytio);
+ memcpy(&nttytio, &ottytio, sizeof(struct termios));
+ cfmakeraw(&nttytio);
+ cfsetspeed(&nttytio, BAUDRATE);
+ tcflush(tty, TCIFLUSH);
+ tcsetattr(tty, TCSANOW, &nttytio);
+ pfd[0].fd = tty;
+ pfd[0].events = POLLIN;
+ nfd++;
+
+ /* Buffering the console data into a file */
+ sprintf(old_bfname, "/tmp/consoled_%s_log-old", fru_name);
+ sprintf(bfname, "/tmp/consoled_%s_log", fru_name);
+ if ((buf_fd = open(bfname, O_RDWR | O_APPEND | O_CREAT, 0666)) < 0) {
+ syslog(LOG_ALERT, "Cannot open the file %s", bfname);
+ exit(-1);
+ }
+
+ if (term) {
+ /* Changing the attributes of STDIN_FILENO */
+ stdi = STDIN_FILENO;
+ tcgetattr(stdi, &ostditio);
+ memcpy(&nstditio, &ostditio, sizeof(struct termios));
+ cfmakeraw(&nstditio);
+ tcflush(stdi, TCIFLUSH);
+ tcsetattr(stdi, TCSANOW, &nstditio);
+
+ /* Changing the attributes of STDOUT_FILENO */
+ stdo = STDOUT_FILENO;
+ tcgetattr(stdo, &ostdotio);
+ memcpy(&nstdotio, &ostdotio, sizeof(struct termios));
+ cfmakeraw(&nstdotio);
+ tcflush(stdo, TCIFLUSH);
+ tcsetattr(stdo, TCSANOW, &nstdotio);
+
+ /* Adding STDIN_FILENO to the poll fd set */
+ pfd[1].fd = stdi;
+ pfd[1].events = POLLIN;
+ nfd++;
+ }
+
+ /* Handling the input event from the terminal and tty dev */
+ while (!sigexit && (nevents = poll(pfd, nfd, -1 /* Timeout */))) {
+
+ /* Input to the terminal from the user */
+ if (term && nevents && nfd > 1 && pfd[1].revents > 0) {
+ blen = read(stdi, &in, sizeof(in));
+ if (blen < 1) {
+ nfd--;
+ }
+
+ if (in == CTRL_X) {
+ break;
+ }
+
+ write_data(tty, &in, sizeof(in), "tty");
+
+ nevents--;
+ }
+
+ /* Input from the tty dev */
+ if (nevents && pfd[0].revents > 0) {
+ blen = read(tty, buf, sizeof(buf));
+ if (blen > 0) {
+ for (i = 0; i < blen; i++) {
+ if (buf[i] == 0xD)
+ nline++;
+ }
+ write_data(buf_fd, buf, blen, bfname);
+ fsync(buf_fd);
+ if (term) {
+ write_data(stdo, buf, blen, "STDOUT_FILENO");
+ }
+ } else if (blen < 0) {
+ raise(SIGHUP);
+ }
+
+ /* Log Rotation */
+ if (nline >= 300) {
+ close(buf_fd);
+ remove(old_bfname);
+ rename(bfname, old_bfname);
+ if ((buf_fd = open(bfname, O_RDWR | O_APPEND | O_CREAT, 0666)) < 0) {
+ syslog(LOG_ALERT, "Cannot open the file %s", bfname);
+ exit(-1);
+ }
+ nline = 0;
+ }
+ nevents--;
+ }
+ }
+
+ /* Close the console buffer file */
+ close(buf_fd);
+
+ /* Revert the tty dev to old attributes */
+ tcflush(tty, TCIFLUSH);
+ tcsetattr(tty, TCSANOW, &ottytio);
+
+ /* Revert STDIN to old attributes */
+ if (term) {
+ tcflush(stdo, TCIFLUSH);
+ tcsetattr(stdo, TCSANOW, &ostdotio);
+ tcflush(stdi, TCIFLUSH);
+ tcsetattr(stdi, TCSANOW, &ostditio);
+ }
+
+ /* Delete the pid file */
+ if (!term)
+ remove(pid_file);
+}
+
+int
+main(int argc, void **argv) {
+ int dev, rc, lock_file;
+ char file[64];
+ int term;
+ char *fru_name;
+
+ if (argc != 3) {
+ print_usage();
+ exit(1);
+ }
+
+ // A lock file for one instance of consoled for each fru
+ sprintf(file, "/var/lock/consoled_%s", argv[1]);
+ lock_file = open(file, O_CREAT | O_RDWR, 0666);
+ rc = flock(lock_file, LOCK_EX | LOCK_NB);
+ if(rc) {
+ if(errno == EWOULDBLOCK) {
+ printf("Another consoled %s instance is running...\n", argv[1]);
+ exit(-1);
+ }
+ } else {
+
+ fru_name = argv[1];
+
+ if (!strcmp(argv[2], "--buffer")) {
+ term = 0;
+ } else if (!strcmp(argv[2], "--term")) {
+ term = 1;
+ } else {
+ print_usage();
+ exit(-1);
+ }
+
+ run_console(fru_name, term);
+ }
+
+ return sigexit;
+}
+
diff --git a/common/recipes-core/fan-ctrl/fan-ctrl/Makefile b/common/recipes-core/fan-ctrl/fan-ctrl/Makefile
new file mode 100644
index 0000000..da74a34
--- /dev/null
+++ b/common/recipes-core/fan-ctrl/fan-ctrl/Makefile
@@ -0,0 +1,26 @@
+# 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
+
+all: fand
+
+fand: fand.cpp watchdog.cpp
+ $(CXX) $(CXXFLAGS) -pthread -o $@ $^ $(LDFLAGS)
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o fand
diff --git a/common/recipes-core/fan-ctrl/fan-ctrl/README b/common/recipes-core/fan-ctrl/fan-ctrl/README
new file mode 100644
index 0000000..2a92b9d
--- /dev/null
+++ b/common/recipes-core/fan-ctrl/fan-ctrl/README
@@ -0,0 +1,5 @@
+The AST PWM/Tach driver is in the kernel sources at drivers/hwmon/ast_pwm_fan.c
+
+There are 7 PWM output pins. Each PWM can be configured in one of 3 types (M,
+N, or O). The clock settings for each type are configurable. See init_pwm.sh
+for more comments about how we configure the settings.
diff --git a/common/recipes-core/fan-ctrl/fan-ctrl/fand.cpp b/common/recipes-core/fan-ctrl/fan-ctrl/fand.cpp
new file mode 100644
index 0000000..49c6f6b
--- /dev/null
+++ b/common/recipes-core/fan-ctrl/fan-ctrl/fand.cpp
@@ -0,0 +1,1030 @@
+/*
+ * fand
+ *
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ *
+ * Daemon to manage the fan speed to ensure that we stay within a reasonable
+ * temperature range. We're using a simplistic algorithm to get started:
+ *
+ * If the fan is already on high, we'll move it to medium if we fall below
+ * a top temperature. If we're on medium, we'll move it to high
+ * if the temperature goes over the top value, and to low if the
+ * temperature falls to a bottom level. If the fan is on low,
+ * we'll increase the speed if the temperature rises to the top level.
+ *
+ * To ensure that we're not just turning the fans up, then back down again,
+ * we'll require an extra few degrees of temperature drop before we lower
+ * the fan speed.
+ *
+ * We check the RPM of the fans against the requested RPMs to determine
+ * whether the fans are failing, in which case we'll turn up all of
+ * the other fans and report the problem..
+ *
+ * TODO: Implement a PID algorithm to closely track the ideal temperature.
+ * TODO: Determine if the daemon is already started.
+ */
+
+/* Yeah, the file ends in .cpp, but it's a C program. Deal. */
+
+#if !defined(CONFIG_YOSEMITE) && !defined(CONFIG_WEDGE)
+#error "No hardware platform defined!"
+#endif
+#if defined(CONFIG_YOSEMITE) && defined(CONFIG_WEDGE)
+#error "Both hardware platform defined!"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <syslog.h>
+#ifdef CONFIG_YOSEMITE
+#include <openbmc/ipmi.h>
+#include <facebook/bic.h>
+#include <facebook/yosemite_sensor.h>
+#endif
+#ifdef CONFIG_WEDGE
+#include <facebook/wedge_eeprom.h>
+#endif
+
+#include "watchdog.h"
+
+/* Sensor definitions */
+
+#ifdef CONFIG_WEDGE
+#define INTERNAL_TEMPS(x) ((x) * 1000) // stored a C * 1000
+#define EXTERNAL_TEMPS(x) ((x) / 1000)
+#elif CONFIG_YOSEMITE
+#define INTERNAL_TEMPS(x) (x)
+#define EXTERNAL_TEMPS(x) (x)
+#define TOTAL_1S_SERVERS 4
+#endif
+
+#define I2C_BUS_3_DIR "/sys/class/i2c-adapter/i2c-3/"
+#define I2C_BUS_4_DIR "/sys/class/i2c-adapter/i2c-4/"
+
+#define INTAKE_TEMP_DEVICE I2C_BUS_3_DIR "3-0048"
+#define T2_TEMP_DEVICE I2C_BUS_3_DIR "3-0049"
+#define EXHAUST_TEMP_DEVICE I2C_BUS_3_DIR "3-004a"
+#define USERVER_TEMP_DEVICE I2C_BUS_4_DIR "4-0040"
+
+/*
+ * The sensor for the uServer CPU is not on the CPU itself, so it reads
+ * a little low. We are special casing this, but we should obviously
+ * be thinking about a way to generalize these tweaks, and perhaps
+ * the entire configuration. JSON file?
+ */
+
+#ifdef CONFIG_WEDGE
+#define USERVER_TEMP_FUDGE INTERNAL_TEMPS(10)
+#else
+#define USERVER_TEMP_FUDGE INTERNAL_TEMPS(1)
+#endif
+
+#define BAD_TEMP INTERNAL_TEMPS(-60)
+
+#define BAD_READ_THRESHOLD 4 /* How many times can reads fail */
+#define FAN_FAILURE_THRESHOLD 4 /* How many times can a fan fail */
+#define FAN_SHUTDOWN_THRESHOLD 20 /* How long fans can be failed before */
+ /* we just shut down the whole thing. */
+
+
+#define PWM_DIR "/sys/devices/platform/ast_pwm_tacho.0"
+
+#define PWM_UNIT_MAX 96
+
+#define LARGEST_DEVICE_NAME 120
+
+#define GPIO_USERVER_POWER_DIRECTION "/sys/class/gpio/gpio25/direction"
+#define GPIO_USERVER_POWER "/sys/class/gpio/gpio25/value"
+#define GPIO_T2_POWER_DIRECTION "/tmp/gpionames/T2_POWER_UP/direction"
+#define GPIO_T2_POWER "/tmp/gpionames/T2_POWER_UP/value"
+
+#define GPIO_FAN0_LED "/sys/class/gpio/gpio53/value"
+#define GPIO_FAN1_LED "/sys/class/gpio/gpio54/value"
+#define GPIO_FAN2_LED "/sys/class/gpio/gpio55/value"
+#define GPIO_FAN3_LED "/sys/class/gpio/gpio72/value"
+
+const char *fan_led[] = {GPIO_FAN0_LED, GPIO_FAN1_LED,
+ GPIO_FAN2_LED, GPIO_FAN3_LED};
+
+#define FAN_LED_RED "0"
+#define FAN_LED_BLUE "1"
+
+#define GPIO_PIN_ID "/sys/class/gpio/gpio%d/value"
+#define REV_IDS 3
+#define GPIO_REV_ID_START 192
+
+#define BOARD_IDS 4
+#define GPIO_BOARD_ID_START 160
+
+/*
+ * With hardware revisions after 3, we use a different set of pins for
+ * the BOARD_ID.
+ */
+
+#define REV_ID_NEW_BOARD_ID 3
+#define GPIO_BOARD_ID_START_NEW 166
+
+#define REPORT_TEMP 720 /* Report temp every so many cycles */
+
+/* Sensor limits and tuning parameters */
+
+#define INTAKE_LIMIT INTERNAL_TEMPS(60)
+#define T2_LIMIT INTERNAL_TEMPS(80)
+#define USERVER_LIMIT INTERNAL_TEMPS(90)
+
+#define TEMP_TOP INTERNAL_TEMPS(70)
+#define TEMP_BOTTOM INTERNAL_TEMPS(40)
+
+/*
+ * Toggling the fan constantly will wear it out (and annoy anyone who
+ * can hear it), so we'll only turn down the fan after the temperature
+ * has dipped a bit below the point at which we'd otherwise switch
+ * things up.
+ */
+
+#define COOLDOWN_SLOP INTERNAL_TEMPS(6)
+
+#define WEDGE_FAN_LOW 35
+#define WEDGE_FAN_MEDIUM 50
+#define WEDGE_FAN_HIGH 70
+#define WEDGE_FAN_MAX 99
+
+#define SIXPACK_FAN_LOW 35
+#define SIXPACK_FAN_MEDIUM 55
+#define SIXPACK_FAN_HIGH 75
+#define SIXPACK_FAN_MAX 99
+
+/*
+ * Mapping physical to hardware addresses for fans; it's different for
+ * RPM measuring and PWM setting, naturally. Doh.
+ */
+
+#ifdef CONFIG_WEDGE
+int fan_to_rpm_map[] = {3, 2, 0, 1};
+int fan_to_pwm_map[] = {7, 6, 0, 1};
+#define FANS 4
+// Tacho offset between front and rear fans:
+#define REAR_FAN_OFFSET 4
+#define BACK_TO_BACK_FANS
+#else
+int fan_to_rpm_map[] = {0, 1};
+int fan_to_pwm_map[] = {0, 1};
+#define FANS 2
+// Tacho offset between front and rear fans:
+#define REAR_FAN_OFFSET 1
+#endif
+
+
+/*
+ * The measured RPM of the fans doesn't match linearly to the requested
+ * rate. In addition, there are coaxially mounted fans, so the rear fans
+ * feed into the front fans. The rear fans will run slower since they're
+ * grabbing still air, and the front fants are getting an extra boost.
+ *
+ * We'd like to measure the fan RPM and compare it to the expected RPM
+ * so that we can detect failed fans, so we have a table (derived from
+ * hardware testing):
+ */
+
+struct rpm_to_pct_map {
+ ushort pct;
+ ushort rpm;
+};
+
+#ifdef CONFIG_WEDGE
+struct rpm_to_pct_map rpm_front_map[] = {{30, 6150},
+ {35, 7208},
+ {40, 8195},
+ {45, 9133},
+ {50, 10017},
+ {55, 10847},
+ {60, 11612},
+ {65, 12342},
+ {70, 13057},
+ {75, 13717},
+ {80, 14305},
+ {85, 14869},
+ {90, 15384},
+ {95, 15871},
+ {100, 16095}};
+#define FRONT_MAP_SIZE (sizeof(rpm_front_map) / sizeof(struct rpm_to_pct_map))
+
+struct rpm_to_pct_map rpm_rear_map[] = {{30, 3911},
+ {35, 4760},
+ {40, 5587},
+ {45, 6434},
+ {50, 7295},
+ {55, 8187},
+ {60, 9093},
+ {65, 10008},
+ {70, 10949},
+ {75, 11883},
+ {80, 12822},
+ {85, 13726},
+ {90, 14690},
+ {95, 15516},
+ {100, 15897}};
+#define REAR_MAP_SIZE (sizeof(rpm_rear_map) / sizeof(struct rpm_to_pct_map))
+#else
+struct rpm_to_pct_map rpm_map[] = {{30, 3413},
+ {35, 3859},
+ {40, 4305},
+ {45, 4686},
+ {50, 5032},
+ {55, 5432},
+ {60, 5991},
+ {65, 6460},
+ {70, 6927},
+ {75, 7379},
+ {80, 7733},
+ {85, 8156},
+ {90, 8599},
+ {95, 9049},
+ {100, 9265}};
+struct rpm_to_pct_map *rpm_front_map = rpm_map;
+struct rpm_to_pct_map *rpm_rear_map = rpm_map;
+#define MAP_SIZE (sizeof(rpm_map) / sizeof(struct rpm_to_pct_map))
+#define FRONT_MAP_SIZE MAP_SIZE
+#define REAR_MAP_SIZE MAP_SIZE
+
+#endif
+
+#define FAN_FAILURE_OFFSET 30
+
+int fan_low = WEDGE_FAN_LOW;
+int fan_medium = WEDGE_FAN_MEDIUM;
+int fan_high = WEDGE_FAN_HIGH;
+int fan_max = WEDGE_FAN_MAX;
+int total_fans = FANS;
+int fan_offset = 0;
+
+int temp_bottom = TEMP_BOTTOM;
+int temp_top = TEMP_TOP;
+
+int report_temp = REPORT_TEMP;
+bool verbose = false;
+
+void usage() {
+ fprintf(stderr,
+ "fand [-v] [-l <low-pct>] [-m <medium-pct>] "
+ "[-h <high-pct>]\n"
+ "\t[-b <temp-bottom>] [-t <temp-top>] [-r <report-temp>]\n\n"
+ "\tlow-pct defaults to %d%% fan\n"
+ "\tmedium-pct defaults to %d%% fan\n"
+ "\thigh-pct defaults to %d%% fan\n"
+ "\ttemp-bottom defaults to %dC\n"
+ "\ttemp-top defaults to %dC\n"
+ "\treport-temp defaults to every %d measurements\n\n"
+ "fand compensates for uServer temperature reading %d degrees low\n"
+ "kill with SIGUSR1 to stop watchdog\n",
+ fan_low,
+ fan_medium,
+ fan_high,
+ EXTERNAL_TEMPS(temp_bottom),
+ EXTERNAL_TEMPS(temp_top),
+ report_temp,
+ EXTERNAL_TEMPS(USERVER_TEMP_FUDGE));
+ exit(1);
+}
+
+/* We need to open the device each time to read a value */
+
+int read_device(const char *device, int *value) {
+ FILE *fp;
+ int rc;
+
+ fp = fopen(device, "r");
+ if (!fp) {
+ int err = errno;
+
+ syslog(LOG_INFO, "failed to open device %s", device);
+ return err;
+ }
+
+ rc = fscanf(fp, "%d", value);
+ fclose(fp);
+
+ if (rc != 1) {
+ syslog(LOG_INFO, "failed to read device %s", device);
+ return ENOENT;
+ } else {
+ return 0;
+ }
+}
+
+/* We need to open the device again each time to write a value */
+
+int write_device(const char *device, const char *value) {
+ FILE *fp;
+ int rc;
+
+ fp = fopen(device, "w");
+ if (!fp) {
+ int err = errno;
+
+ syslog(LOG_INFO, "failed to open device for write %s", device);
+ return err;
+ }
+
+ rc = fputs(value, fp);
+ fclose(fp);
+
+ if (rc < 0) {
+ syslog(LOG_INFO, "failed to write device %s", device);
+ return ENOENT;
+ } else {
+ return 0;
+ }
+}
+
+#ifdef CONFIG_WEDGE
+int read_temp(const char *device, int *value) {
+ char full_name[LARGEST_DEVICE_NAME + 1];
+
+ /* We set an impossible value to check for errors */
+ *value = BAD_TEMP;
+ snprintf(
+ full_name, LARGEST_DEVICE_NAME, "%s/temp1_input", device);
+ return read_device(full_name, value);
+}
+
+int read_gpio_value(const int id, const char *device, int *value) {
+ char full_name[LARGEST_DEVICE_NAME];
+
+ snprintf(full_name, LARGEST_DEVICE_NAME, device, id);
+ return read_device(full_name, value);
+}
+
+int read_gpio_values(const int start, const int count,
+ const char *device, int *result) {
+ int status = 0;
+ int value;
+
+ *result = 0;
+ for (int i = 0; i < count; i++) {
+ status |= read_gpio_value(start + i, GPIO_PIN_ID, &value);
+ *result |= value << i;
+ }
+ return status;
+}
+
+int read_ids(int *rev_id, int *board_id) {
+ int status = 0;
+ int value;
+
+ status = read_gpio_values(GPIO_REV_ID_START, REV_IDS, GPIO_PIN_ID, rev_id);
+ if (status != 0) {
+ syslog(LOG_INFO, "failed to read rev_id");
+ return status;
+ }
+
+ int board_id_start;
+ if (*rev_id >= REV_ID_NEW_BOARD_ID) {
+ board_id_start = GPIO_BOARD_ID_START_NEW;
+ } else {
+ board_id_start = GPIO_BOARD_ID_START;
+ }
+
+ status = read_gpio_values(board_id_start, BOARD_IDS, GPIO_PIN_ID, board_id);
+ if (status != 0) {
+ syslog(LOG_INFO, "failed to read board_id");
+ }
+ return status;
+}
+
+bool is_two_fan_board(bool verbose) {
+ struct wedge_eeprom_st eeprom;
+ /* Retrieve the board type from EEPROM */
+ if (wedge_eeprom_parse(NULL, &eeprom) == 0) {
+ /* able to parse EEPROM */
+ if (verbose) {
+ syslog(LOG_INFO, "board type is %s", eeprom.fbw_location);
+ }
+ /* only WEDGE is NOT two-fan board */
+ return strncasecmp(eeprom.fbw_location, "wedge",
+ sizeof(eeprom.fbw_location));
+ } else {
+ int status;
+ int board_id = 0;
+ int rev_id = 0;
+ /*
+ * Could not parse EEPROM. Most likely, it is an old HW without EEPROM.
+ * In this case, use board ID to distinguish if it is wedge or 6-pack.
+ */
+ status = read_ids(&rev_id, &board_id);
+ if (verbose) {
+ syslog(LOG_INFO, "rev ID %d, board id %d", rev_id, board_id);
+ }
+ if (status == 0 && board_id != 0xf) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
+#endif
+
+int read_fan_value(const int fan, const char *device, int *value) {
+ char device_name[LARGEST_DEVICE_NAME];
+ char output_value[LARGEST_DEVICE_NAME];
+ char full_name[LARGEST_DEVICE_NAME];
+
+ snprintf(device_name, LARGEST_DEVICE_NAME, device, fan);
+ snprintf(full_name, LARGEST_DEVICE_NAME, "%s/%s", PWM_DIR, device_name);
+ return read_device(full_name, value);
+}
+
+int write_fan_value(const int fan, const char *device, const int value) {
+ char full_name[LARGEST_DEVICE_NAME];
+ char device_name[LARGEST_DEVICE_NAME];
+ char output_value[LARGEST_DEVICE_NAME];
+
+ snprintf(device_name, LARGEST_DEVICE_NAME, device, fan);
+ snprintf(full_name, LARGEST_DEVICE_NAME, "%s/%s", PWM_DIR, device_name);
+ snprintf(output_value, LARGEST_DEVICE_NAME, "%d", value);
+ return write_device(full_name, output_value);
+}
+
+/* Return fan speed as a percentage of maximum -- not necessarily linear. */
+
+int fan_rpm_to_pct(const struct rpm_to_pct_map *table,
+ const int table_len,
+ int rpm) {
+ int i;
+
+ for (i = 0; i < table_len; i++) {
+ if (table[i].rpm > rpm) {
+ break;
+ }
+ }
+
+ /*
+ * If the fan RPM is lower than the lowest value in the table,
+ * we may have a problem -- fans can only go so slow, and it might
+ * have stopped. In this case, we'll return an interpolated
+ * percentage, as just returning zero is even more problematic.
+ */
+
+ if (i == 0) {
+ return (rpm * table[i].pct) / table[i].rpm;
+ } else if (i == table_len) { // Fell off the top?
+ return table[i - 1].pct;
+ }
+
+ // Interpolate the right percentage value:
+
+ int percent_diff = table[i].pct - table[i - 1].pct;
+ int rpm_diff = table[i].rpm - table[i - 1].rpm;
+ int fan_diff = table[i].rpm - rpm;
+
+ return table[i].pct - (fan_diff * percent_diff / rpm_diff);
+}
+
+int fan_speed_okay(const int fan, const int speed, const int slop) {
+ int front_fan, rear_fan;
+ int front_pct, rear_pct;
+ int real_fan;
+ int okay;
+
+ /*
+ * The hardware fan numbers are different from the physical order
+ * in the box, so we have to map them:
+ */
+
+ real_fan = fan_to_rpm_map[fan];
+
+ front_fan = 0;
+ read_fan_value(real_fan, "tacho%d_rpm", &front_fan);
+ front_pct = fan_rpm_to_pct(rpm_front_map, FRONT_MAP_SIZE, front_fan);
+#ifdef BACK_TO_BACK_FANS
+ rear_fan = 0;
+ read_fan_value(real_fan + REAR_FAN_OFFSET, "tacho%d_rpm", &rear_fan);
+ rear_pct = fan_rpm_to_pct(rpm_rear_map, REAR_MAP_SIZE, rear_fan);
+#endif
+
+
+ /*
+ * If the fans are broken, the measured rate will be rather
+ * different from the requested rate, and we can turn up the
+ * rest of the fans to compensate. The slop is the percentage
+ * of error that we'll tolerate.
+ *
+ * XXX: I suppose that we should only measure negative values;
+ * running too fast isn't really a problem.
+ */
+
+#ifdef BACK_TO_BACK_FANS
+ okay = (abs(front_pct - speed) * 100 / speed < slop &&
+ abs(rear_pct - speed) * 100 / speed < slop);
+#else
+ okay = (abs(front_pct - speed) * 100 / speed < slop);
+#endif
+
+ if (!okay || verbose) {
+ syslog(!okay ? LOG_ALERT : LOG_INFO,
+#ifdef BACK_TO_BACK_FANS
+ "fan %d rear %d (%d%%), front %d (%d%%), expected %d",
+#else
+ "fan %d %d RPM (%d%%), expected %d",
+#endif
+ fan,
+#ifdef BACK_TO_BACK_FANS
+ rear_fan,
+ rear_pct,
+#endif
+ front_fan,
+ front_pct,
+ speed);
+ }
+
+ return okay;
+}
+
+/* Set fan speed as a percentage */
+
+int write_fan_speed(const int fan, const int value) {
+ /*
+ * The hardware fan numbers for pwm control are different from
+ * both the physical order in the box, and the mapping for reading
+ * the RPMs per fan, above.
+ */
+
+ int real_fan = fan_to_pwm_map[fan];
+
+ if (value == 0) {
+ return write_fan_value(real_fan, "pwm%d_en", 0);
+ } else {
+ int unit = value * PWM_UNIT_MAX / 100;
+ int status;
+
+ if (unit == PWM_UNIT_MAX)
+ unit = 0;
+
+ if ((status = write_fan_value(real_fan, "pwm%d_type", 0)) != 0 ||
+ (status = write_fan_value(real_fan, "pwm%d_rising", 0)) != 0 ||
+ (status = write_fan_value(real_fan, "pwm%d_falling", unit)) != 0 ||
+ (status = write_fan_value(real_fan, "pwm%d_en", 1)) != 0) {
+ return status;
+ }
+ }
+}
+
+/* Set up fan LEDs */
+
+int write_fan_led(const int fan, const char *color)
+{
+#ifdef CONFIG_WEDGE
+ return write_device(fan_led[fan], color);
+#else
+ return 0;
+#endif
+}
+
+int server_shutdown(const char *why) {
+ int fan;
+ for (fan = 0; fan < total_fans; fan++) {
+ write_fan_speed(fan + fan_offset, fan_max);
+ }
+
+ syslog(LOG_EMERG, "Shutting down: %s", why);
+ write_device(GPIO_USERVER_POWER_DIRECTION, "out");
+ write_device(GPIO_USERVER_POWER, "0");
+#ifdef CONFIG_WEDGE
+ /*
+ * Putting T2 in reset generates a non-maskable interrupt to uS,
+ * the kernel running on uS might panic depending on its version.
+ * sleep 5s here to make sure uS is completely down.
+ */
+ sleep(5);
+
+ if (write_device(GPIO_T2_POWER_DIRECTION, "out") ||
+ write_device(GPIO_T2_POWER, "1")) {
+ /*
+ * We're here because something has gone badly wrong. If we
+ * didn't manage to shut down the T2, cut power to the whole box,
+ * using the PMBus OPERATION register. This will require a power
+ * cycle (removal of both power inputs) to recover.
+ */
+ syslog(LOG_EMERG, "T2 power off failed; turning off via ADM1278");
+ system("rmmod adm1275");
+ system("i2cset -y 12 0x10 0x01 00");
+ }
+
+#else
+ // TODO(7088822): try throttling, then shutting down server.
+ syslog(LOG_EMERG, "Need to implement actual shutdown!\n");
+#endif
+
+ /*
+ * We have to stop the watchdog, or the system will be automatically
+ * rebooted some seconds after fand exits (and stops kicking the
+ * watchdog).
+ */
+
+ stop_watchdog();
+
+ sleep(2);
+ exit(2);
+}
+
+/* Gracefully shut down on receipt of a signal */
+
+void fand_interrupt(int sig)
+{
+ int fan;
+ for (fan = 0; fan < total_fans; fan++) {
+ write_fan_speed(fan + fan_offset, fan_max);
+ }
+
+ syslog(LOG_ALERT, "Shutting down fand on signal %s", strsignal(sig));
+ if (sig == SIGUSR1) {
+ stop_watchdog();
+ }
+ exit(3);
+}
+
+int main(int argc, char **argv) {
+ /* Sensor values */
+
+#ifdef CONFIG_WEDGE
+ int intake_temp;
+ int exhaust_temp;
+ int t2_temp;
+ int userver_temp;
+#else
+ float intake_temp;
+ float exhaust_temp;
+ float userver_temp;
+#endif
+
+ int fan_speed = fan_high;
+ int bad_reads = 0;
+ int fan_failure = 0;
+ int fan_speed_changes = 0;
+ int old_speed;
+
+ int fan_bad[FANS];
+ int fan;
+
+ unsigned log_count = 0; // How many times have we logged our temps?
+ int opt;
+ int prev_fans_bad = 0;
+
+ struct sigaction sa;
+
+ sa.sa_handler = fand_interrupt;
+ sa.sa_flags = 0;
+ sigemptyset(&sa.sa_mask);
+
+ sigaction(SIGTERM, &sa, NULL);
+ sigaction(SIGINT, &sa, NULL);
+ sigaction(SIGUSR1, &sa, NULL);
+
+ // Start writing to syslog as early as possible for diag purposes.
+
+ openlog("fand", LOG_CONS, LOG_DAEMON);
+
+#ifdef CONFIG_WEDGE
+ if (is_two_fan_board(false)) {
+ /* Alternate, two fan configuration */
+ total_fans = 2;
+ fan_offset = 2; /* fan 3 is the first */
+
+ fan_low = SIXPACK_FAN_LOW;
+ fan_medium = SIXPACK_FAN_MEDIUM;
+ fan_high = SIXPACK_FAN_HIGH;
+ fan_max = SIXPACK_FAN_MAX;
+ fan_speed = fan_high;
+ }
+#endif
+
+ while ((opt = getopt(argc, argv, "l:m:h:b:t:r:v")) != -1) {
+ switch (opt) {
+ case 'l':
+ fan_low = atoi(optarg);
+ break;
+ case 'm':
+ fan_medium = atoi(optarg);
+ break;
+ case 'h':
+ fan_high = atoi(optarg);
+ break;
+ case 'b':
+ temp_bottom = INTERNAL_TEMPS(atoi(optarg));
+ break;
+ case 't':
+ temp_top = INTERNAL_TEMPS(atoi(optarg));
+ break;
+ case 'r':
+ report_temp = atoi(optarg);
+ break;
+ case 'v':
+ verbose = true;
+ break;
+ default:
+ usage();
+ break;
+ }
+ }
+
+ if (optind > argc) {
+ usage();
+ }
+
+ if (temp_bottom > temp_top) {
+ fprintf(stderr,
+ "Should temp-bottom (%d) be higher than "
+ "temp-top (%d)? Starting anyway.\n",
+ EXTERNAL_TEMPS(temp_bottom),
+ EXTERNAL_TEMPS(temp_top));
+ }
+
+ if (fan_low > fan_medium || fan_low > fan_high || fan_medium > fan_high) {
+ fprintf(stderr,
+ "fan RPMs not strictly increasing "
+ "-- %d, %d, %d, starting anyway\n",
+ fan_low,
+ fan_medium,
+ fan_high);
+ }
+
+ daemon(1, 0);
+
+ if (verbose) {
+ syslog(LOG_DEBUG, "Starting up; system should have %d fans.",
+ total_fans);
+ }
+
+ for (fan = 0; fan < total_fans; fan++) {
+ fan_bad[fan] = 0;
+ write_fan_speed(fan + fan_offset, fan_speed);
+ write_fan_led(fan + fan_offset, FAN_LED_BLUE);
+ }
+
+#ifdef CONFIG_YOSEMITE
+ /* Ensure that we can read from sensors before proceeding. */
+
+ while (yosemite_sensor_read(1, BIC_SENSOR_SOC_TEMP, &userver_temp))
+ syslog(LOG_DEBUG, "Failed reading of SOC_TEMP.");
+#endif
+
+ /* Start watchdog in manual mode */
+ start_watchdog(0);
+
+ /* Set watchdog to persistent mode so timer expiry will happen independent
+ * of this process's liveliness. */
+ set_persistent_watchdog(WATCHDOG_SET_PERSISTENT);
+
+ sleep(5); /* Give the fans time to come up to speed */
+
+ while (1) {
+ int max_temp;
+ old_speed = fan_speed;
+
+ /* Read sensors */
+
+#ifdef CONFIG_WEDGE
+ read_temp(INTAKE_TEMP_DEVICE, &intake_temp);
+ read_temp(EXHAUST_TEMP_DEVICE, &exhaust_temp);
+ read_temp(T2_TEMP_DEVICE, &t2_temp);
+ read_temp(USERVER_TEMP_DEVICE, &userver_temp);
+
+ /*
+ * uServer can be powered down, but all of the rest of the sensors
+ * should be readable at any time.
+ */
+
+ if ((intake_temp == BAD_TEMP || exhaust_temp == BAD_TEMP ||
+ t2_temp == BAD_TEMP)) {
+ bad_reads++;
+ }
+#else
+ userver_temp = BAD_TEMP;
+ if (yosemite_sensor_read(1, SP_SENSOR_INLET_TEMP, &intake_temp) ||
+ yosemite_sensor_read(1, SP_SENSOR_OUTLET_TEMP, &exhaust_temp))
+ bad_reads++;
+
+ /*
+ * There are a number of 1S servers; any or all of them
+ * could be powered off and returning no values. Ignore these
+ * invalid values.
+ */
+ for (int node = 1; node <= TOTAL_1S_SERVERS; node++) {
+ float new_temp;
+ if (!yosemite_sensor_read(node, BIC_SENSOR_SOC_TEMP, &new_temp)) {
+ if (userver_temp < new_temp) {
+ userver_temp = new_temp;
+ }
+ }
+ }
+#endif
+
+ if (bad_reads > BAD_READ_THRESHOLD) {
+ server_shutdown("Some sensors couldn't be read");
+ }
+
+ if (log_count++ % report_temp == 0) {
+ syslog(LOG_DEBUG,
+#ifdef CONFIG_WEDGE
+ "Temp intake %d, t2 %d, "
+ " userver %d, exhaust %d, "
+ "fan speed %d, speed changes %d",
+#else
+ "Temp intake %f, max server %f, exhaust %f, "
+ "fan speed %d, speed changes %d",
+#endif
+ intake_temp,
+#ifdef CONFIG_WEDGE
+ t2_temp,
+#endif
+ userver_temp,
+ exhaust_temp,
+ fan_speed,
+ fan_speed_changes);
+ }
+
+ /* Protection heuristics */
+
+ if (intake_temp > INTAKE_LIMIT) {
+ server_shutdown("Intake temp limit reached");
+ }
+
+#ifdef CONFIG_WEDGE
+ if (t2_temp > T2_LIMIT) {
+ server_shutdown("T2 temp limit reached");
+ }
+#endif
+
+ if (userver_temp + USERVER_TEMP_FUDGE > USERVER_LIMIT) {
+ server_shutdown("uServer temp limit reached");
+ }
+
+ /*
+ * Calculate change needed -- we should eventually
+ * do something more sophisticated, like PID.
+ *
+ * We should use the intake temperature to adjust this
+ * as well.
+ */
+
+#ifdef CONFIG_WEDGE
+ if (t2_temp > userver_temp + USERVER_TEMP_FUDGE) {
+ max_temp = t2_temp;
+ } else {
+ max_temp = userver_temp + USERVER_TEMP_FUDGE;
+ }
+#else
+ /* Yosemite could have no servers turned on, so ignore that case. */
+ if (userver_temp + USERVER_TEMP_FUDGE > exhaust_temp) {
+ max_temp = userver_temp + USERVER_TEMP_FUDGE;
+ } else {
+ max_temp = exhaust_temp;
+ }
+#endif
+
+ /*
+ * If recovering from a fan problem, spin down fans gradually in case
+ * temperatures are still high. Gradual spin down also reduces wear on
+ * the fans.
+ */
+ if (fan_speed == fan_max) {
+ if (fan_failure == 0) {
+ fan_speed = fan_high;
+ }
+ } else if (fan_speed == fan_high) {
+ if (max_temp + COOLDOWN_SLOP < temp_top) {
+ fan_speed = fan_medium;
+ }
+ } else if (fan_speed == fan_medium) {
+ if (max_temp > temp_top) {
+ fan_speed = fan_high;
+ } else if (max_temp + COOLDOWN_SLOP < temp_bottom) {
+ fan_speed = fan_low;
+ }
+ } else {/* low */
+ if (max_temp > temp_bottom) {
+ fan_speed = fan_medium;
+ }
+ }
+
+ /*
+ * Update fans only if there are no failed ones. If any fans failed
+ * earlier, all remaining fans should continue to run at max speed.
+ */
+
+ if (fan_failure == 0 && fan_speed != old_speed) {
+ syslog(LOG_NOTICE,
+ "Fan speed changing from %d to %d",
+ old_speed,
+ fan_speed);
+ fan_speed_changes++;
+ for (fan = 0; fan < total_fans; fan++) {
+ write_fan_speed(fan + fan_offset, fan_speed);
+ }
+ }
+
+ /*
+ * Wait for some change. Typical I2C temperature sensors
+ * only provide a new value every second and a half, so
+ * checking again more quickly than that is a waste.
+ *
+ * We also have to wait for the fan changes to take effect
+ * before measuring them.
+ */
+
+ sleep(5);
+
+ /* Check fan RPMs */
+
+ for (fan = 0; fan < total_fans; fan++) {
+ /*
+ * Make sure that we're within some percentage
+ * of the requested speed.
+ */
+ if (fan_speed_okay(fan + fan_offset, fan_speed, FAN_FAILURE_OFFSET)) {
+ if (fan_bad[fan] > FAN_FAILURE_THRESHOLD) {
+ write_fan_led(fan + fan_offset, FAN_LED_BLUE);
+ syslog(LOG_NOTICE,
+ "Fan %d has recovered",
+ fan);
+ }
+ fan_bad[fan] = 0;
+ } else {
+ fan_bad[fan]++;
+ }
+ }
+
+ fan_failure = 0;
+ for (fan = 0; fan < total_fans; fan++) {
+ if (fan_bad[fan] > FAN_FAILURE_THRESHOLD) {
+ fan_failure++;
+ write_fan_led(fan + fan_offset, FAN_LED_RED);
+ }
+ }
+
+ if (fan_failure > 0) {
+ if (prev_fans_bad != fan_failure) {
+ syslog(LOG_ALERT, "%d fans failed", fan_failure);
+ }
+
+ /*
+ * If fans are bad, we need to blast all of the
+ * fans at 100%; we don't bother to turn off
+ * the bad fans, in case they are all that is left.
+ *
+ * Note that we have a temporary bug with setting fans to
+ * 100% so we only do fan_max = 99%.
+ */
+
+ fan_speed = fan_max;
+ for (fan = 0; fan < total_fans; fan++) {
+ write_fan_speed(fan + fan_offset, fan_speed);
+ }
+
+ if (fan_failure == total_fans) {
+ int count = 0;
+ for (fan = 0; fan < total_fans; fan++) {
+ if (fan_bad[fan] > FAN_SHUTDOWN_THRESHOLD)
+ count++;
+ }
+ if (count == total_fans) {
+ server_shutdown("all fans are bad for more than 12 cycles");
+ }
+ }
+
+
+ /*
+ * Fans can be hot swapped and replaced; in which case the fan daemon
+ * will automatically detect the new fan and (assuming the new fan isn't
+ * itself faulty), automatically readjust the speeds for all fans down
+ * to a more suitable rpm. The fan daemon does not need to be restarted.
+ */
+ }
+
+ /* Suppress multiple warnings for similar number of fan failures. */
+ prev_fans_bad = fan_failure;
+
+ /* if everything is fine, restart the watchdog countdown. If this process
+ * is terminated, the persistent watchdog setting will cause the system
+ * to reboot after the watchdog timeout. */
+ kick_watchdog();
+ }
+}
diff --git a/common/recipes-core/fan-ctrl/fan-ctrl/watchdog.cpp b/common/recipes-core/fan-ctrl/fan-ctrl/watchdog.cpp
new file mode 100644
index 0000000..ebb390a
--- /dev/null
+++ b/common/recipes-core/fan-ctrl/fan-ctrl/watchdog.cpp
@@ -0,0 +1,201 @@
+/*
+ * watchdog
+ *
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "watchdog.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#define WATCHDOG_START_KEY "x"
+#define WATCHDOG_STOP_KEY "X"
+/* The "magic close" character (as defined in Linux watchdog specs). */
+#define WATCHDOG_PERSISTENT_KEY "V"
+#define WATCHDOG_NON_PERSISTENT_KEY "a"
+
+static int watchdog_dev = -1;
+
+/* This is needed to prevent rapid consecutive stop/start watchdog calls from
+ * generating multiple threads. */
+static int watchdog_started = 0;
+
+static const char* watchdog_kick_key = WATCHDOG_PERSISTENT_KEY;
+static pthread_t watchdog_tid;
+static pthread_mutex_t watchdog_lock = PTHREAD_MUTEX_INITIALIZER;
+
+/* Forward declarations. */
+static void* watchdog_thread(void* args);
+static int kick_watchdog_unsafe();
+
+/*
+ * When started, this background thread will constantly reset the watchdog
+ * at every 5 second interval.
+ */
+
+static void* watchdog_thread(void* args) {
+
+ pthread_detach(pthread_self());
+
+ /* Make sure another instance of the thread hasn't already been started. */
+ pthread_mutex_lock(&watchdog_lock);
+ if (watchdog_started) {
+ goto done;
+ } else {
+ watchdog_started = 1;
+ }
+ pthread_mutex_unlock(&watchdog_lock);
+
+ /* Actual loop for refreshing the watchdog timer. */
+ while (1) {
+ pthread_mutex_lock(&watchdog_lock);
+ if (watchdog_dev != -1) {
+ kick_watchdog_unsafe();
+ } else {
+ break;
+ }
+ pthread_mutex_unlock(&watchdog_lock);
+ sleep(5);
+ }
+
+ /* Broke out of loop because watchdog was stopped. */
+ watchdog_started = 0;
+done:
+ pthread_mutex_unlock(&watchdog_lock);
+ return NULL;
+}
+
+/*
+ * Starts the watchdog timer. timer counts down and restarts the ARM chip
+ * upon timeout. use kick_watchdog() to restart the timer.
+ *
+ * Returns: 1 on success; 0 otherwise.
+ */
+
+int start_watchdog(const int auto_mode) {
+ int status;
+
+ pthread_mutex_lock(&watchdog_lock);
+
+ /* Don't start the watchdog again if it has already been started. */
+ if (watchdog_dev != -1) {
+ while ((status = write(watchdog_dev, WATCHDOG_START_KEY, 1)) == 0
+ && errno == EINTR);
+ pthread_mutex_unlock(&watchdog_lock);
+ syslog(LOG_ALERT, "system watchdog already started.\n");
+ return 0;
+ }
+
+ while (((watchdog_dev = open("/dev/watchdog", O_WRONLY)) == -1) &&
+ errno == EINTR);
+
+ /* Fail if watchdog device is invalid or if the user asked for auto
+ * mode and the thread failed to spawn. */
+ if ((watchdog_dev == -1) ||
+ (auto_mode == 1 && watchdog_started == 0 &&
+ pthread_create(&watchdog_tid, NULL, watchdog_thread, NULL) != 0)) {
+ goto fail;
+ }
+
+ while ((status = write(watchdog_dev, WATCHDOG_START_KEY, 1)) == 0
+ && errno == EINTR);
+ pthread_mutex_unlock(&watchdog_lock);
+ syslog(LOG_INFO, "system watchdog started.\n");
+ return 1;
+
+fail:
+ if (watchdog_dev != -1) {
+ close(watchdog_dev);
+ watchdog_dev = -1;
+ }
+
+ pthread_mutex_unlock(&watchdog_lock);
+ syslog(LOG_ALERT, "system watchdog failed to start!\n");
+ return 0;
+}
+
+/*
+ * Toggles between watchdog persistent modes. In persistent mode, the watchdog
+ * timer will continue to tick even after process shutdown. Under non-
+ * persistent mode, the watchdog timer will automatically be disabled when the
+ * process shuts down.
+ */
+void set_persistent_watchdog(enum watchdog_persistent_en persistent) {
+ switch (persistent) {
+ case WATCHDOG_SET_PERSISTENT:
+ watchdog_kick_key = WATCHDOG_PERSISTENT_KEY;
+ break;
+ default:
+ watchdog_kick_key = WATCHDOG_NON_PERSISTENT_KEY;
+ break;
+ }
+ kick_watchdog();
+}
+
+/*
+ * Restarts the countdown timer on the watchdog, delaying restart by another
+ * timeout period (default: 11 seconds as configured in the device driver).
+ *
+ * This function assumes the watchdog lock has already been acquired and is
+ * only used internally within the watchdog code.
+ *
+ * Returns 1 on success; 0 or -1 indicates failure (check errno).
+ */
+
+static int kick_watchdog_unsafe() {
+ int status = 0;
+ if (watchdog_dev != -1) {
+ while ((status = write(watchdog_dev, watchdog_kick_key, 1)) == 0
+ && errno == EINTR);
+ }
+ return status;
+}
+
+/*
+ * Acquires the watchdog lock and resets the watchdog atomically. For use by
+ * library users.
+ */
+
+int kick_watchdog() {
+ int result;
+ pthread_mutex_lock(&watchdog_lock);
+ result = kick_watchdog_unsafe();
+ pthread_mutex_unlock(&watchdog_lock);
+
+ return result;
+}
+
+/* Shuts down the watchdog gracefully and disables the watchdog timer so that
+ * restarts no longer happen.
+ */
+
+void stop_watchdog() {
+ int status;
+ pthread_mutex_lock(&watchdog_lock);
+ if (watchdog_dev != -1) {
+ while ((status = write(watchdog_dev, WATCHDOG_STOP_KEY, 1)) == 0
+ && errno == EINTR);
+ close(watchdog_dev);
+ watchdog_dev = -1;
+ syslog(LOG_INFO, "system watchdog stopped.\n");
+ }
+ pthread_mutex_unlock(&watchdog_lock);
+}
diff --git a/common/recipes-core/fan-ctrl/fan-ctrl/watchdog.h b/common/recipes-core/fan-ctrl/fan-ctrl/watchdog.h
new file mode 100644
index 0000000..19b9944
--- /dev/null
+++ b/common/recipes-core/fan-ctrl/fan-ctrl/watchdog.h
@@ -0,0 +1,60 @@
+/*
+ * watchdog
+ *
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ *
+ * Utility library to handle the aspeed watchdog. Only one watchdog
+ * should be in use at any time throughout the entire system (multiple users
+ * will not cause adverse effects but the behavior of the watchdog becomes
+ * undefined).
+ *
+ * The watchdog can be started in either manual or automatic mode. In manual
+ * mode, the watchdog has to be constantly reset by the user via the
+ * kick_watchdog() function. Under automatic mode, the watchdog will
+ * run in a separate thread and reset the timer on its own so no intervention
+ * is required from the user.
+ *
+ * In both modes, the watchdog timer will not stop when the process is
+ * terminated, unless a call to stop_watchdog() has been made beforehand, or
+ * if the user runs in manual mode and uses a non persistent watchdog kick.
+ *
+ * The default timeout for the watchdog is 11 seconds. When this time period
+ * elapses, the ARM chip is restarted and the kernel is rebooted. Other
+ * hardware state is not reset, so this may introduce strange behavior on
+ * reboot (example: an I2C bus may be left in the open state, triggering
+ * constant interrupts). In rare cases, this could result in the kernel
+ * failing to fully restart itself and thus preclude the possibility of
+ * reinitializing the watchdog timer. Someone will then have to go over and
+ * physically restart the machine.
+ *
+ * The alternative to the soft reset is to request the watchdog device driver
+ * for a hard reset on timeout. However this will stop the fans. If the
+ * kernel fails to fully boot and restart the fan daemon, the system could
+ * overheat. For this reason, we've chosen to take the risk of a stuck soft
+ * reset instead.
+ *
+ */
+
+/* Forward declarations. */
+int start_watchdog(const int auto_mode);
+enum watchdog_persistent_en {
+ WATCHDOG_SET_PERSISTENT,
+ WATCHDOG_SET_NONPERSISTENT,
+};
+void set_persistent_watchdog(enum watchdog_persistent_en persistent);
+int kick_watchdog();
+void stop_watchdog();
diff --git a/common/recipes-core/fan-ctrl/fan-ctrl_0.1.bb b/common/recipes-core/fan-ctrl/fan-ctrl_0.1.bb
new file mode 100644
index 0000000..1abfaaa
--- /dev/null
+++ b/common/recipes-core/fan-ctrl/fan-ctrl_0.1.bb
@@ -0,0 +1,61 @@
+# 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
+SUMMARY = "Fan controller"
+DESCRIPTION = "The utilities to control fan."
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://fand.cpp;beginline=6;endline=18;md5=da35978751a9d71b73679307c4d296ec"
+
+SRC_URI = "file://README \
+ file://Makefile \
+ file://fand.cpp \
+ file://watchdog.h \
+ file://watchdog.cpp \
+ "
+
+S = "${WORKDIR}"
+
+binfiles = "fand \
+ "
+
+otherfiles = "README"
+
+pkgdir = "fan_ctrl"
+
+do_install() {
+ dst="${D}/usr/local/fbpackages/${pkgdir}"
+ bin="${D}/usr/local/bin"
+ install -d $dst
+ install -d $bin
+ for f in ${binfiles}; do
+ install -m 755 $f ${dst}/$f
+ ln -snf ../fbpackages/${pkgdir}/$f ${bin}/$f
+ done
+ for f in ${otherfiles}; do
+ install -m 644 $f ${dst}/$f
+ done
+}
+
+FBPACKAGEDIR = "${prefix}/local/fbpackages"
+
+FILES_${PN} = "${FBPACKAGEDIR}/fan_ctrl ${prefix}/local/bin"
+
+# Inhibit complaints about .debug directories for the fand binary:
+
+INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
+INHIBIT_PACKAGE_STRIP = "1"
diff --git a/common/recipes-core/fruid/files/Makefile b/common/recipes-core/fruid/files/Makefile
new file mode 100644
index 0000000..5c6aff4
--- /dev/null
+++ b/common/recipes-core/fruid/files/Makefile
@@ -0,0 +1,26 @@
+# 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
+
+all: fruid-util
+
+fruid: fruid-util.c
+ $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o fruid-util
diff --git a/common/recipes-core/fruid/files/fruid-util.c b/common/recipes-core/fruid/files/fruid-util.c
new file mode 100644
index 0000000..3c8d2e1
--- /dev/null
+++ b/common/recipes-core/fruid/files/fruid-util.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <openbmc/fruid.h>
+#include <openbmc/pal.h>
+
+/* Print the FRUID in detail */
+void print_fruid_info(fruid_info_t *fruid, const char *name)
+{
+ /* Print format */
+ printf("%-27s: %s", "\nFRU Information",
+ name /* Name of the FRU device */ );
+ printf("%-27s: %s", "\n---------------", "------------------");
+
+ if (fruid->chassis.flag) {
+ printf("%-27s: %s", "\nChassis Type",fruid->chassis.type_str);
+ printf("%-27s: %s", "\nChassis Part",fruid->chassis.part);
+ printf("%-27s: %s", "\nChassis Serial Number",fruid->chassis.serial);
+ printf("%-27s: %s", "\nChassis Custom Data",fruid->chassis.custom);
+ }
+
+ if (fruid->board.flag) {
+ printf("%-27s: %s", "\nBoard Mfg Time",fruid->board.mfg_time_str);
+ printf("%-27s: %s", "\nBoard Manufacturer",fruid->board.mfg);
+ printf("%-27s: %s", "\nBoard Name",fruid->board.name);
+ printf("%-27s: %s", "\nBoard Serial Number",fruid->board.serial);
+ printf("%-27s: %s", "\nBoard Part",fruid->board.part);
+ printf("%-27s: %s", "\nBoard FRU ID",fruid->board.fruid);
+ printf("%-27s: %s", "\nBoard Custom Data",fruid->board.custom);
+ }
+
+ if (fruid->product.flag) {
+ printf("%-27s: %s", "\nProduct Manufacturer",fruid->product.mfg);
+ printf("%-27s: %s", "\nProduct Name",fruid->product.name);
+ printf("%-27s: %s", "\nProduct Part",fruid->product.part);
+ printf("%-27s: %s", "\nProduct Version",fruid->product.version);
+ printf("%-27s: %s", "\nProduct Serial Number",fruid->product.serial);
+ printf("%-27s: %s", "\nProduct Asset Tag",fruid->product.asset_tag);
+ printf("%-27s: %s", "\nProduct FRU ID",fruid->product.fruid);
+ printf("%-27s: %s", "\nProduct Custom Data",fruid->product.custom);
+ }
+
+ printf("\n");
+}
+
+/* Populate and print fruid_info by parsing the fru's binary dump */
+void get_fruid_info(uint8_t fru, char *path, char* name) {
+ int ret;
+ fruid_info_t fruid;
+
+ ret = fruid_parse(path, &fruid);
+ if (ret) {
+ fprintf(stderr, "Failed print FRUID for %s\nCheck syslog for errors!\n",
+ name);
+ } else {
+ print_fruid_info(&fruid, name);
+ free_fruid_info(&fruid);
+ }
+
+}
+
+static int
+print_usage() {
+ printf("Usage: fruid-util [ %s ]\n", pal_fru_list);
+}
+
+/* Utility to just print the FRUID */
+int main(int argc, char * argv[]) {
+
+ int ret;
+ uint8_t fru;
+ char path[64] = {0};
+ char name[64] = {0};
+
+ if (argc != 2) {
+ print_usage();
+ exit(-1);
+ }
+
+ ret = pal_get_fru_id(argv[1], &fru);
+ if (ret < 0) {
+ print_usage();
+ return ret;
+ }
+
+ if (fru == 0) {
+ fru = 1;
+ while (fru <= MAX_NUM_FRUS) {
+ ret = pal_get_fruid_path(fru, path);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = pal_get_fruid_name(fru, name);
+ if (ret < 0) {
+ return ret;
+ }
+
+ if (fru == FRU_NIC) {
+ printf("fruid-util does not support nic\n");
+ exit(-1);
+ }
+
+ get_fruid_info(fru, path, name);
+
+ fru++;
+ }
+ } else {
+ ret = pal_get_fruid_path(fru, path);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = pal_get_fruid_name(fru, name);
+ if (ret < 0) {
+ return ret;
+ }
+
+ if (fru == FRU_NIC) {
+ printf("fruid-util does not support nic\n");
+ exit(-1);
+ }
+
+ get_fruid_info(fru, path, name);
+ }
+
+ return 0;
+}
diff --git a/common/recipes-core/fruid/fruid_0.1.bb b/common/recipes-core/fruid/fruid_0.1.bb
new file mode 100644
index 0000000..604845f
--- /dev/null
+++ b/common/recipes-core/fruid/fruid_0.1.bb
@@ -0,0 +1,55 @@
+# 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
+
+SUMMARY = "IPMI FRUID Utilities"
+DESCRIPTION = "Util for ipmi fruid"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://fruid-util.c;beginline=4;endline=16;md5=da35978751a9d71b73679307c4d296ec"
+
+LDFLAGS = " -lfruid -lpal "
+DEPENDS = "libfruid libpal "
+
+SRC_URI = "file://Makefile \
+ file://fruid-util.c \
+ "
+
+S = "${WORKDIR}"
+
+binfiles = "fruid-util \
+ "
+
+pkgdir = "fruid"
+
+do_install() {
+ dst="${D}/usr/local/fbpackages/${pkgdir}"
+ bin="${D}/usr/local/bin"
+ install -d $dst
+ install -d $bin
+ for f in ${binfiles}; do
+ install -m 755 $f ${dst}/$f
+ ln -snf ../fbpackages/${pkgdir}/$f ${bin}/$f
+ done
+}
+
+FBPACKAGEDIR = "${prefix}/local/fbpackages"
+
+FILES_${PN} = "${FBPACKAGEDIR}/fruid ${prefix}/local/bin"
+
+INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
+INHIBIT_PACKAGE_STRIP = "1"
diff --git a/common/recipes-core/ipmbd/files/Makefile b/common/recipes-core/ipmbd/files/Makefile
new file mode 100644
index 0000000..719ccc3
--- /dev/null
+++ b/common/recipes-core/ipmbd/files/Makefile
@@ -0,0 +1,10 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+all: ipmbd
+
+ipmbd: ipmbd.o
+ $(CC) $(CFLAGS) -pthread -lrt -lipmi -std=gnu99 -o $@ $^ $(LDFLAGS)
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o ipmbd
diff --git a/common/recipes-core/ipmbd/files/ipmbd.c b/common/recipes-core/ipmbd/files/ipmbd.c
new file mode 100644
index 0000000..5ea5af3
--- /dev/null
+++ b/common/recipes-core/ipmbd/files/ipmbd.c
@@ -0,0 +1,843 @@
+/*
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+
+/*
+ * This module handles all the IPMB communication protocol
+ * Refer http://www.intel.com/content/www/us/en/servers/ipmi/ipmp-spec-v1-0.html
+ * for more information.
+ *
+ * IPMB packet format is described here for quick reference
+ * Request:
+ * <Responder Slave Address(rsSA)>
+ * <NetFn/ResponderLUN(Netfn/rsLUN)>
+ * <Header Checksum(hdrCksum)>
+ * <Requester Slave Address(rqSA)>
+ * <Requester Sequence Number/RequesterLUN(rqSeq/rqLUN>
+ * <Command>
+ * <Data[0..n]>
+ * <Data Checksum(dataCksum)>
+ * Response:
+ * <Requester Slave Address(rqSA)>
+ * <NetFn/RequesterLUN(Netfn/rqLUN)>
+ * <Header Checksum(hdrCksum)>
+ * <Responder Slave Address(rsSA)>
+ * <Requester Sequence Number/ResponderLUN(rqSeq/rsLUN>
+ * <Command>
+ * <Completion Code(CC)>
+ * <Data[0..n]>
+ * <Data Checksum(dataCksum)>
+ */
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <syslog.h>
+#include <pthread.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <mqueue.h>
+#include <semaphore.h>
+
+#include "facebook/i2c-dev.h"
+#include "openbmc/ipmi.h"
+#include "openbmc/ipmb.h"
+
+//#define DEBUG 0
+
+#define MAX_BYTES 255
+
+#define MQ_IPMB_REQ "/mq_ipmb_req"
+#define MQ_IPMB_RES "/mq_ipmb_res"
+#define MQ_MAX_MSG_SIZE MAX_BYTES
+#define MQ_MAX_NUM_MSGS 10
+
+#define SEQ_NUM_MAX 64
+
+#define I2C_RETRIES_MAX 3
+
+// Structure for i2c file descriptor and socket
+typedef struct _ipmb_sfd_t {
+ int fd;
+ int sock;
+} ipmb_sfd_t;
+
+// Structure for sequence number and buffer
+typedef struct _seq_buf_t {
+ bool in_use; // seq# is being used
+ uint8_t len; // buffer size
+ uint8_t *p_buf; // pointer to buffer
+ sem_t s_seq; // semaphore for thread sync.
+} seq_buf_t;
+
+// Structure for holding currently used sequence number and
+// array of all possible sequence number
+typedef struct _ipmb_sbuf_t {
+ uint8_t curr_seq; // currently used seq#
+ seq_buf_t seq[SEQ_NUM_MAX]; //array of all possible seq# struct.
+} ipmb_sbuf_t;
+
+// Global storage for holding IPMB sequence number and buffer
+ipmb_sbuf_t g_seq;
+
+// mutex to protect global data access
+pthread_mutex_t m_seq;
+
+pthread_mutex_t m_i2c;
+
+#ifdef CONFIG_YOSEMITE
+// Returns the payload ID from IPMB bus routing
+// Slot#1: bus#3, Slot#2: bus#1, Slot#3: bus#7, Slot#4: bus#5
+static uint8_t
+get_payload_id(uint8_t bus_id) {
+ uint8_t payload_id = 0xFF; // Invalid payload ID
+
+ switch(bus_id) {
+ case 1:
+ payload_id = 2;
+ break;
+ case 3:
+ payload_id = 1;
+ break;
+ case 5:
+ payload_id = 4;
+ break;
+ case 7:
+ payload_id = 3;
+ break;
+ default:
+ syslog(LOG_ALERT, "get_payload_id: Wrong bus ID\n");
+ break;
+ }
+
+ return payload_id;
+}
+#endif
+
+// Returns an unused seq# from all possible seq#
+static uint8_t
+seq_get_new(void) {
+ uint8_t ret = -1;
+ uint8_t index;
+
+ pthread_mutex_lock(&m_seq);
+
+ // Search for unused sequence number
+ index = g_seq.curr_seq;
+ do {
+ if (g_seq.seq[index].in_use == false) {
+ // Found it!
+ ret = index;
+ g_seq.seq[index].in_use = true;
+ g_seq.seq[index].len = 0;
+ break;
+ }
+
+ if (++index == SEQ_NUM_MAX) {
+ index = 0;
+ }
+ } while (index != g_seq.curr_seq);
+
+ // Update the current seq num
+ if (ret >= 0) {
+ if (++index == SEQ_NUM_MAX) {
+ index = 0;
+ }
+ g_seq.curr_seq = index;
+ }
+
+ pthread_mutex_unlock(&m_seq);
+
+ return ret;
+}
+
+static int
+i2c_open(uint8_t bus_num) {
+ int fd;
+ char fn[32];
+ int rc;
+
+ snprintf(fn, sizeof(fn), "/dev/i2c-%d", bus_num);
+ fd = open(fn, O_RDWR);
+ if (fd == -1) {
+ syslog(LOG_ALERT, "Failed to open i2c device %s", fn);
+ return -1;
+ }
+
+ rc = ioctl(fd, I2C_SLAVE, BRIDGE_SLAVE_ADDR);
+ if (rc < 0) {
+ syslog(LOG_ALERT, "Failed to open slave @ address 0x%x", BRIDGE_SLAVE_ADDR);
+ close(fd);
+ return -1;
+ }
+
+ return fd;
+}
+
+static int
+i2c_write(int fd, uint8_t *buf, uint8_t len) {
+ struct i2c_rdwr_ioctl_data data;
+ struct i2c_msg msg;
+ int rc;
+ int i;
+
+ memset(&msg, 0, sizeof(msg));
+
+ msg.addr = BRIDGE_SLAVE_ADDR;
+ msg.flags = 0;
+ msg.len = len;
+ msg.buf = buf;
+
+ data.msgs = &msg;
+ data.nmsgs = 1;
+
+ pthread_mutex_lock(&m_i2c);
+
+ for (i = 0; i < I2C_RETRIES_MAX; i++) {
+ rc = ioctl(fd, I2C_RDWR, &data);
+ if (rc < 0) {
+ sleep(1);
+ continue;
+ } else {
+ break;
+ }
+ }
+
+ if (rc < 0) {
+ syslog(LOG_ALERT, "Failed to do raw io");
+ pthread_mutex_unlock(&m_i2c);
+ return -1;
+ }
+
+ pthread_mutex_unlock(&m_i2c);
+
+ return 0;
+}
+
+static int
+i2c_slave_open(uint8_t bus_num) {
+ int fd;
+ char fn[32];
+ int rc;
+ struct i2c_rdwr_ioctl_data data;
+ struct i2c_msg msg;
+ uint8_t read_bytes[MAX_BYTES] = { 0 };
+
+ snprintf(fn, sizeof(fn), "/dev/i2c-%d", bus_num);
+ fd = open(fn, O_RDWR);
+ if (fd == -1) {
+ syslog(LOG_ALERT, "Failed to open i2c device %s", fn);
+ return -1;
+ }
+
+ memset(&msg, 0, sizeof(msg));
+
+ msg.addr = BMC_SLAVE_ADDR;
+ msg.flags = I2C_S_EN;
+ msg.len = 1;
+ msg.buf = read_bytes;
+ msg.buf[0] = 1;
+
+ data.msgs = &msg;
+ data.nmsgs = 1;
+
+ rc = ioctl(fd, I2C_SLAVE_RDWR, &data);
+ if (rc < 0) {
+ syslog(LOG_ALERT, "Failed to open slave @ address 0x%x", BMC_SLAVE_ADDR);
+ close(fd);
+ }
+
+ return fd;
+}
+
+static int
+i2c_slave_read(int fd, uint8_t *buf, uint8_t *len) {
+ struct i2c_rdwr_ioctl_data data;
+ struct i2c_msg msg;
+ int rc;
+
+ memset(&msg, 0, sizeof(msg));
+
+ msg.addr = BMC_SLAVE_ADDR;
+ msg.flags = 0;
+ msg.len = MAX_BYTES;
+ msg.buf = buf;
+
+ data.msgs = &msg;
+ data.nmsgs = 1;
+
+ rc = ioctl(fd, I2C_SLAVE_RDWR, &data);
+ if (rc < 0) {
+ return -1;
+ }
+
+ *len = msg.len;
+
+ return 0;
+}
+
+// Thread to handle new requests
+static void*
+ipmb_req_handler(void *bus_num) {
+ uint8_t *bnum = (uint8_t*) bus_num;
+ mqd_t mq;
+ int fd;
+ int i;
+
+ //Buffers for IPMB transport
+ uint8_t rxbuf[MQ_MAX_MSG_SIZE] = {0};
+ uint8_t txbuf[MQ_MAX_MSG_SIZE] = {0};
+ ipmb_req_t *p_ipmb_req;
+ ipmb_res_t *p_ipmb_res;
+
+ p_ipmb_req = (ipmb_req_t*) rxbuf;
+ p_ipmb_res = (ipmb_res_t*) txbuf;
+
+ //Buffers for IPMI Stack
+ uint8_t rbuf[MQ_MAX_MSG_SIZE] = {0};
+ uint8_t tbuf[MQ_MAX_MSG_SIZE] = {0};
+ ipmi_mn_req_t *p_ipmi_mn_req;
+ ipmi_res_t *p_ipmi_res;
+
+ p_ipmi_mn_req = (ipmi_mn_req_t*) rbuf;
+ p_ipmi_res = (ipmi_res_t*) tbuf;
+
+ uint8_t rlen = 0;
+ uint8_t tlen = 0;
+
+ char mq_ipmb_req[64] = {0};
+
+ sprintf(mq_ipmb_req, "%s_%d", MQ_IPMB_REQ, *bnum);
+
+ // Open Queue to receive requests
+ mq = mq_open(mq_ipmb_req, O_RDONLY);
+ if (mq == (mqd_t) -1) {
+ return NULL;
+ }
+
+ // Open the i2c bus for sending response
+ fd = i2c_open(*bnum);
+ if (fd < 0) {
+ syslog(LOG_ALERT, "i2c_open failure\n");
+ close(mq);
+ return NULL;
+ }
+
+ // Loop to process incoming requests
+ while (1) {
+ if ((rlen = mq_receive(mq, rxbuf, MQ_MAX_MSG_SIZE, NULL)) < 0) {
+ sleep(1);
+ continue;
+ }
+
+#ifdef DEBUG
+ syslog(LOG_ALERT, "Received Request of %d bytes\n", rlen);
+ for (i = 0; i < rlen; i++) {
+ syslog(LOG_ALERT, "0x%X", rxbuf[i]);
+ }
+#endif
+
+ // Create IPMI request from IPMB data
+#ifdef CONFIG_YOSEMITE
+ p_ipmi_mn_req->payload_id = get_payload_id(*bnum);
+#else
+ // For single node systems use payload ID as 1
+ p_ipmi_mn_req->payload_id = 0x1;
+#endif
+ p_ipmi_mn_req->netfn_lun = p_ipmb_req->netfn_lun;
+ p_ipmi_mn_req->cmd = p_ipmb_req->cmd;
+
+ memcpy(p_ipmi_mn_req->data, p_ipmb_req->data, rlen - IPMB_HDR_SIZE - IPMI_REQ_HDR_SIZE);
+
+ // Send to IPMI stack and get response
+ // Additional byte as we are adding and passing payload ID for MN support
+ lib_ipmi_handle(rbuf, rlen - IPMB_HDR_SIZE + 1, tbuf, &tlen);
+
+ // Populate IPMB response data from IPMB request
+ p_ipmb_res->req_slave_addr = p_ipmb_req->req_slave_addr;
+ p_ipmb_res->res_slave_addr = p_ipmb_req->res_slave_addr;
+ p_ipmb_res->cmd = p_ipmb_req->cmd;
+ p_ipmb_res->seq_lun = p_ipmb_req->seq_lun;
+
+ // Add IPMI response data
+ p_ipmb_res->netfn_lun = p_ipmi_res->netfn_lun;
+ p_ipmb_res->cc = p_ipmi_res->cc;
+
+ memcpy(p_ipmb_res->data, p_ipmi_res->data, tlen - IPMI_RESP_HDR_SIZE);
+
+ // Calculate Header Checksum
+ p_ipmb_res->hdr_cksum = p_ipmb_res->req_slave_addr +
+ p_ipmb_res->netfn_lun;
+ p_ipmb_res->hdr_cksum = ZERO_CKSUM_CONST - p_ipmb_res->hdr_cksum;
+
+ // Calculate Data Checksum
+ p_ipmb_res->data[tlen-IPMI_RESP_HDR_SIZE] = p_ipmb_res->res_slave_addr +
+ p_ipmb_res->seq_lun +
+ p_ipmb_res->cmd +
+ p_ipmb_res->cc;
+
+ for (i = 0; i < tlen-IPMI_RESP_HDR_SIZE; i++) {
+ p_ipmb_res->data[tlen-IPMI_RESP_HDR_SIZE] += p_ipmb_res->data[i];
+ }
+
+ p_ipmb_res->data[tlen-IPMI_RESP_HDR_SIZE] = ZERO_CKSUM_CONST -
+ p_ipmb_res->data[tlen-IPMI_RESP_HDR_SIZE];
+
+#ifdef DEBUG
+ syslog(LOG_ALERT, "Sending Response of %d bytes\n", tlen+IPMB_HDR_SIZE-1);
+ for (i = 1; i < tlen+IPMB_HDR_SIZE; i++) {
+ syslog(LOG_ALERT, "0x%X:", txbuf[i]);
+ }
+#endif
+
+ // Send response back
+ i2c_write(fd, &txbuf[1], tlen+IPMB_HDR_SIZE-1);
+ }
+}
+
+// Thread to handle the incoming responses
+static void*
+ipmb_res_handler(void *bus_num) {
+ uint8_t *bnum = (uint8_t*) bus_num;
+ uint8_t buf[MQ_MAX_MSG_SIZE] = { 0 };
+ uint8_t len = 0;
+ mqd_t mq;
+ ipmb_res_t *p_res;
+ uint8_t index;
+ char mq_ipmb_res[64] = {0};
+
+ sprintf(mq_ipmb_res, "%s_%d", MQ_IPMB_RES, *bnum);
+
+ // Open the message queue
+ mq = mq_open(mq_ipmb_res, O_RDONLY);
+ if (mq == (mqd_t) -1) {
+ syslog(LOG_ALERT, "mq_open fails\n");
+ return NULL;
+ }
+
+ // Loop to wait for incomng response messages
+ while (1) {
+ if ((len = mq_receive(mq, buf, MQ_MAX_MSG_SIZE, NULL)) < 0) {
+ sleep(1);
+ continue;
+ }
+
+ p_res = (ipmb_res_t *) buf;
+
+ // Check the seq# of response
+ index = p_res->seq_lun >> LUN_OFFSET;
+
+ // Check if the response is being waited for
+ pthread_mutex_lock(&m_seq);
+ if (g_seq.seq[index].in_use) {
+ // Copy the response to the requester's buffer
+ memcpy(g_seq.seq[index].p_buf, buf, len);
+ g_seq.seq[index].len = len;
+
+ // Wake up the worker thread to receive the response
+ sem_post(&g_seq.seq[index].s_seq);
+ }
+ pthread_mutex_unlock(&m_seq);
+
+#ifdef DEBUG
+ syslog(LOG_ALERT, "Received Response of %d bytes\n", len);
+ int i;
+ for (i = 0; i < len; i++) {
+ syslog(LOG_ALERT, "0x%X:", buf[i]);
+ }
+#endif
+ }
+}
+
+// Thread to receive the IPMB messages over i2c bus as a slave
+static void*
+ipmb_rx_handler(void *bus_num) {
+ uint8_t *bnum = (uint8_t*) bus_num;
+ int fd;
+ uint8_t len;
+ uint8_t tlun;
+ uint8_t buf[MAX_BYTES] = { 0 };
+ mqd_t mq_req, mq_res, tmq;
+ ipmb_req_t *p_req;
+ struct timespec req;
+ struct timespec rem;
+ char mq_ipmb_req[64] = {0};
+ char mq_ipmb_res[64] = {0};
+
+ // Setup wait time
+ req.tv_sec = 0;
+ req.tv_nsec = 10000000;//10mSec
+
+ // Open the i2c bus as a slave
+ fd = i2c_slave_open(*bnum);
+ if (fd < 0) {
+ syslog(LOG_ALERT, "i2c_slave_open fails\n");
+ goto cleanup;
+ }
+
+ sprintf(mq_ipmb_req, "%s_%d", MQ_IPMB_REQ, *bnum);
+ sprintf(mq_ipmb_res, "%s_%d", MQ_IPMB_RES, *bnum);
+
+ // Open the message queues for post processing
+ mq_req = mq_open(mq_ipmb_req, O_WRONLY);
+ if (mq_req == (mqd_t) -1) {
+ syslog(LOG_ALERT, "mq_open req fails\n");
+ goto cleanup;
+ }
+
+ mq_res = mq_open(mq_ipmb_res, O_WRONLY);
+ if (mq_res == (mqd_t) -1) {
+ syslog(LOG_ALERT, "mq_open res fails\n");
+ goto cleanup;
+ }
+
+ // Loop that retrieves messages
+ while (1) {
+ // Read messages from i2c driver
+ if (i2c_slave_read(fd, buf, &len) < 0) {
+ nanosleep(&req, &rem);
+ continue;
+ }
+
+ // Check if the messages is request or response
+ // Even NetFn: Request, Odd NetFn: Response
+ p_req = (ipmb_req_t*) buf;
+ tlun = p_req->netfn_lun >> LUN_OFFSET;
+ if (tlun%2) {
+ tmq = mq_res;
+ } else {
+ tmq = mq_req;
+ }
+ // Post message to approriate Queue for further processing
+ if (mq_send(tmq, buf, len, 0)) {
+ syslog(LOG_ALERT, "mq_send failed\n");
+ sleep(1);
+ continue;
+ }
+ }
+
+cleanup:
+ if (fd > 0) {
+ close (fd);
+ }
+
+ if (mq_req > 0) {
+ close(mq_req);
+ }
+
+ if (mq_res > 0) {
+ close(mq_req);
+ }
+}
+
+/*
+ * Function to handle all IPMB requests
+ */
+static void
+ipmb_handle (int fd, unsigned char *request, unsigned char req_len,
+ unsigned char *response, unsigned char *res_len)
+{
+ ipmb_req_t *req = (ipmb_req_t *) request;
+ ipmb_res_t *res = (ipmb_res_t *) response;
+
+ uint8_t index;
+ struct timespec ts;
+
+ // Allocate right sequence Number
+ index = seq_get_new();
+ if (index < 0) {
+ *res_len = 0;
+ return ;
+ }
+
+ req->seq_lun = index << LUN_OFFSET;
+
+ // Calculate/update dataCksum
+ // Note: dataCkSum byte is last byte
+ int i;
+ for (i = IPMB_DATA_OFFSET; i < req_len-1; i++) {
+ request[req_len-1] += request[i];
+ }
+
+ request[req_len-1] = ZERO_CKSUM_CONST - request[req_len-1];
+
+ // Setup response buffer
+ pthread_mutex_lock(&m_seq);
+ g_seq.seq[index].p_buf = response;
+ pthread_mutex_unlock(&m_seq);
+
+ // Send request over i2c bus
+ // Note: Need not send first byte SlaveAddress automatically added by driver
+ if (i2c_write(fd, &request[1], req_len-1)) {
+ goto ipmb_handle_out;
+ }
+
+ // Wait on semaphore for that sequence Number
+ clock_gettime(CLOCK_REALTIME, &ts);
+
+ ts.tv_sec += TIMEOUT_IPMI;
+
+ int ret;
+ ret = sem_timedwait(&g_seq.seq[index].s_seq, &ts);
+ if (ret == -1) {
+ syslog(LOG_ALERT, "No response for sequence number: %d\n", index);
+ *res_len = 0;
+ }
+
+ipmb_handle_out:
+ // Reply to user with data
+ pthread_mutex_lock(&m_seq);
+ *res_len = g_seq.seq[index].len;
+
+ g_seq.seq[index].in_use = false;
+ pthread_mutex_unlock(&m_seq);
+
+ return;
+}
+
+void
+*conn_handler(void *sfd) {
+ ipmb_sfd_t *p_sfd = (ipmb_sfd_t *) sfd;
+
+ int sock = p_sfd->sock;
+ int fd = p_sfd->fd;
+ int n;
+ unsigned char req_buf[MAX_IPMI_MSG_SIZE];
+ unsigned char res_buf[MAX_IPMI_MSG_SIZE];
+ unsigned char res_len = 0;
+
+ n = recv(sock, req_buf, sizeof(req_buf), 0);
+ if (n <= 0) {
+ syslog(LOG_ALERT, "ipmbd: recv() failed with %d\n", n);
+ goto conn_cleanup;
+ }
+
+ ipmb_handle(fd, req_buf, n, res_buf, &res_len);
+
+ if (send(sock, res_buf, res_len, MSG_NOSIGNAL) < 0) {
+ syslog(LOG_ALERT, "ipmbd: send() failed\n");
+ }
+
+conn_cleanup:
+ close(sock);
+ free(p_sfd);
+
+ pthread_exit(NULL);
+ return 0;
+}
+
+// Thread to receive the IPMB lib messages from various apps
+static void*
+ipmb_lib_handler(void *bus_num) {
+ int s, s2, t, len;
+ struct sockaddr_un local, remote;
+ pthread_t tid;
+ ipmb_sfd_t *sfd;
+ int fd;
+ uint8_t *bnum = (uint8_t*) bus_num;
+ char sock_path[20] = {0};
+
+ // Open the i2c bus for sending request
+ fd = i2c_open(*bnum);
+ if (fd < 0) {
+ syslog(LOG_ALERT, "i2c_open failure\n");
+ return NULL;
+ }
+
+ // Initialize g_seq structure
+ int i;
+ for (i = 0; i < SEQ_NUM_MAX; i++) {
+ g_seq.seq[i].in_use = false;
+ sem_init(&g_seq.seq[i].s_seq, 0, 0);
+ g_seq.seq[i].len = 0;
+ }
+
+ // Initialize mutex to access global structure
+ pthread_mutex_init(&m_seq, NULL);
+
+ if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) == -1)
+ {
+ syslog(LOG_ALERT, "ipmbd: socket() failed\n");
+ exit (1);
+ }
+
+ sprintf(sock_path, "%s_%d", SOCK_PATH_IPMB, *bnum);
+
+ local.sun_family = AF_UNIX;
+ strcpy (local.sun_path, sock_path);
+ unlink (local.sun_path);
+ len = strlen (local.sun_path) + sizeof (local.sun_family);
+ if (bind (s, (struct sockaddr *) &local, len) == -1)
+ {
+ syslog(LOG_ALERT, "ipmbd: bind() failed\n");
+ exit (1);
+ }
+
+ if (listen (s, 5) == -1)
+ {
+ syslog(LOG_ALERT, "ipmbd: listen() failed\n");
+ exit (1);
+ }
+
+ while(1) {
+ int n;
+ t = sizeof (remote);
+ if ((s2 = accept (s, (struct sockaddr *) &remote, &t)) < 0) {
+ syslog(LOG_ALERT, "ipmbd: accept() failed\n");
+ break;
+ }
+
+ // Creating a worker thread to handle the request
+ // TODO: Need to monitor the server performance with higher load and
+ // see if we need to create pre-defined number of workers and schedule
+ // the requests among them.
+ sfd = (ipmb_sfd_t *) malloc(sizeof(ipmb_sfd_t));
+ sfd->fd = fd;
+ sfd->sock = s2;
+ if (pthread_create(&tid, NULL, conn_handler, (void*) sfd) < 0) {
+ syslog(LOG_ALERT, "ipmbd: pthread_create failed\n");
+ close(s2);
+ continue;
+ }
+
+ pthread_detach(tid);
+ }
+
+ close(s);
+ pthread_mutex_destroy(&m_seq);
+
+ return 0;
+}
+
+int
+main(int argc, char * const argv[]) {
+ pthread_t tid_ipmb_rx;
+ pthread_t tid_req_handler;
+ pthread_t tid_res_handler;
+ pthread_t tid_lib_handler;
+ uint8_t ipmb_bus_num;
+ mqd_t mqd_req, mqd_res;
+ struct mq_attr attr;
+ char mq_ipmb_req[64] = {0};
+ char mq_ipmb_res[64] = {0};
+
+ daemon(1, 0);
+ openlog("ipmbd", LOG_CONS, LOG_DAEMON);
+
+ if (argc != 2) {
+ syslog(LOG_ALERT, "ipmbd: Usage: ipmbd <bus#>");
+ exit(1);
+ }
+
+ ipmb_bus_num = atoi(argv[1]);
+syslog(LOG_ALERT, "ipmbd: bus#:%d\n", ipmb_bus_num);
+
+ pthread_mutex_init(&m_i2c, NULL);
+
+ // Create Message Queues for Request Messages and Response Messages
+ attr.mq_flags = 0;
+ attr.mq_maxmsg = MQ_MAX_NUM_MSGS;
+ attr.mq_msgsize = MQ_MAX_MSG_SIZE;
+ attr.mq_curmsgs = 0;
+
+ sprintf(mq_ipmb_req, "%s_%d", MQ_IPMB_REQ, ipmb_bus_num);
+ sprintf(mq_ipmb_res, "%s_%d", MQ_IPMB_RES, ipmb_bus_num);
+
+ // Remove the MQ if exists
+ mq_unlink(mq_ipmb_req);
+
+ errno = 0;
+ mqd_req = mq_open(mq_ipmb_req, O_RDONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, &attr);
+ if (mqd_req == (mqd_t) -1) {
+ syslog(LOG_ALERT, "ipmbd: mq_open request failed errno:%d\n", errno);
+ goto cleanup;
+ }
+
+ // Remove the MQ if exists
+ mq_unlink(mq_ipmb_res);
+
+ errno = 0;
+ mqd_res = mq_open(mq_ipmb_res, O_RDONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, &attr);
+ if (mqd_res == (mqd_t) -1) {
+ syslog(LOG_ALERT, "ipmbd: mq_open response failed errno: %d\n", errno);
+ goto cleanup;
+ }
+
+ // Create thread to handle IPMB Requests
+ if (pthread_create(&tid_req_handler, NULL, ipmb_req_handler, (void*) &ipmb_bus_num) < 0) {
+ syslog(LOG_ALERT, "ipmbd: pthread_create failed\n");
+ goto cleanup;
+ }
+
+ // Create thread to handle IPMB Responses
+ if (pthread_create(&tid_res_handler, NULL, ipmb_res_handler, (void*) &ipmb_bus_num) < 0) {
+ syslog(LOG_ALERT, "ipmbd: pthread_create failed\n");
+ goto cleanup;
+ }
+
+ // Create thread to retrieve ipmb traffic from i2c bus as slave
+ if (pthread_create(&tid_ipmb_rx, NULL, ipmb_rx_handler, (void*) &ipmb_bus_num) < 0) {
+ syslog(LOG_ALERT, "ipmbd: pthread_create failed\n");
+ goto cleanup;
+ }
+
+ // Create thread to receive ipmb library requests from apps
+ if (pthread_create(&tid_lib_handler, NULL, ipmb_lib_handler, (void*) &ipmb_bus_num) < 0) {
+ syslog(LOG_ALERT, "ipmbd: pthread_create failed\n");
+ goto cleanup;
+ }
+
+cleanup:
+ if (tid_ipmb_rx > 0) {
+ pthread_join(tid_ipmb_rx, NULL);
+ }
+
+ if (tid_req_handler > 0) {
+ pthread_join(tid_req_handler, NULL);
+ }
+
+ if (tid_res_handler > 0) {
+ pthread_join(tid_res_handler, NULL);
+ }
+
+ if (tid_lib_handler > 0) {
+ pthread_join(tid_lib_handler, NULL);
+ }
+
+ if (mqd_res > 0) {
+ mq_close(mqd_res);
+ mq_unlink(mq_ipmb_res);
+ }
+
+ if (mqd_req > 0) {
+ mq_close(mqd_req);
+ mq_unlink(mq_ipmb_req);
+ }
+
+ pthread_mutex_destroy(&m_i2c);
+
+ return 0;
+}
diff --git a/common/recipes-core/ipmbd/ipmbd_0.1.bb b/common/recipes-core/ipmbd/ipmbd_0.1.bb
new file mode 100644
index 0000000..f5724b0
--- /dev/null
+++ b/common/recipes-core/ipmbd/ipmbd_0.1.bb
@@ -0,0 +1,19 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+
+SUMMARY = "ipmbd tx/rx daemon"
+DESCRIPTION = "The ipmb daemon to receive/transmit messages"
+SECTION = "base"
+PR = "r2"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://ipmbd.c;beginline=4;endline=16;md5=da35978751a9d71b73679307c4d296ec"
+
+SRC_URI = "file://Makefile \
+ file://ipmbd.c \
+ "
+
+S = "${WORKDIR}"
+DEPENDS += "libipmi libipmb"
+
+binfiles = "ipmbd"
+
+pkgdir = "ipmbd"
diff --git a/common/recipes-core/ipmid/files/Makefile b/common/recipes-core/ipmid/files/Makefile
new file mode 100644
index 0000000..4f0db3d
--- /dev/null
+++ b/common/recipes-core/ipmid/files/Makefile
@@ -0,0 +1,29 @@
+# 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
+
+C_SRCS := $(wildcard *.c)
+C_OBJS := ${C_SRCS:.c=.o}
+
+all: ipmid
+
+ipmid: $(C_OBJS)
+ $(CC) -pthread -lpal -std=c99 -o $@ $^ $(LDFLAGS)
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o ipmid
diff --git a/common/recipes-core/ipmid/files/fruid.h b/common/recipes-core/ipmid/files/fruid.h
new file mode 100644
index 0000000..3580b08
--- /dev/null
+++ b/common/recipes-core/ipmid/files/fruid.h
@@ -0,0 +1,28 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ *
+ * 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.
+ */
+
+#ifndef __FRUID_H__
+#define __FRUID_H__
+
+int plat_fruid_size(void);
+int plat_fruid_data(int offset, int count, unsigned char *data);
+int plat_fruid_init(void);
+
+#endif /* __FRUID_H__ */
diff --git a/common/recipes-core/ipmid/files/ipmid.c b/common/recipes-core/ipmid/files/ipmid.c
new file mode 100644
index 0000000..c79d3e2
--- /dev/null
+++ b/common/recipes-core/ipmid/files/ipmid.c
@@ -0,0 +1,1412 @@
+/*
+ *
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * This file contains code to support IPMI2.0 Specificaton available @
+ * http://www.intel.com/content/www/us/en/servers/ipmi/ipmi-specifications.html
+ *
+ * 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.
+ */
+
+#include "sdr.h"
+#include "sel.h"
+#include "fruid.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <syslog.h>
+#include <string.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <openbmc/ipmi.h>
+
+// TODO: Once data storage is finalized, the following structure needs
+// to be retrieved/updated from persistant backend storage
+static lan_config_t g_lan_config = { 0 };
+static proc_info_t g_proc_info = { 0 };
+static dimm_info_t g_dimm_info[MAX_NUM_DIMMS] = { 0 };
+
+// TODO: Need to store this info after identifying proper storage
+static sys_info_param_t g_sys_info_params;
+
+// TODO: Based on performance testing results, might need fine grained locks
+// Since the global data is specific to a NetFunction, adding locs at NetFn level
+static pthread_mutex_t m_chassis;
+static pthread_mutex_t m_app;
+static pthread_mutex_t m_storage;
+static pthread_mutex_t m_transport;
+static pthread_mutex_t m_oem;
+static pthread_mutex_t m_oem_1s;
+
+static void ipmi_handle(unsigned char *request, unsigned char req_len,
+ unsigned char *response, unsigned char *res_len);
+
+/*
+ * Function(s) to handle IPMI messages with NetFn: Chassis
+ */
+// Get Chassis Status (IPMI/Section 28.2)
+static void
+chassis_get_status (unsigned char *response, unsigned char *res_len)
+{
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ unsigned char *data = &res->data[0];
+
+ res->cc = CC_SUCCESS;
+
+ // TODO: Need to obtain current power state and last power event
+ // from platform and return
+ *data++ = 0x01; // Current Power State
+ *data++ = 0x00; // Last Power Event
+ *data++ = 0x40; // Misc. Chassis Status
+ *data++ = 0x00; // Front Panel Button Disable
+
+ res_len = data - &res->data[0];
+}
+
+// Get System Boot Options (IPMI/Section 28.12)
+static void
+chassis_get_boot_options (unsigned char *request, unsigned char *response,
+ unsigned char *res_len)
+{
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
+ ipmi_res_t *res= (ipmi_res_t *) response;
+ unsigned char *data = &res->data[0];
+ unsigned char param = req->data[0];
+
+ // Fill response with default values
+ res->cc = CC_SUCCESS;
+ *data++ = 0x01; // Parameter Version
+ *data++ = req->data[0]; // Parameter
+
+ // TODO: Need to store user settings and return
+ switch (param)
+ {
+ case PARAM_SET_IN_PROG:
+ *data++ = 0x00; // Set In Progress
+ break;
+ case PARAM_SVC_PART_SELECT:
+ *data++ = 0x00; // Service Partition Selector
+ break;
+ case PARAM_SVC_PART_SCAN:
+ *data++ = 0x00; // Service Partition Scan
+ break;
+ case PARAM_BOOT_FLAG_CLR:
+ *data++ = 0x00; // BMC Boot Flag Valid Bit Clear
+ break;
+ case PARAM_BOOT_INFO_ACK:
+ *data++ = 0x00; // Write Mask
+ *data++ = 0x00; // Boot Initiator Ack Data
+ break;
+ case PARAM_BOOT_FLAGS:
+ *data++ = 0x00; // Boot Flags
+ *data++ = 0x00; // Boot Device Selector
+ *data++ = 0x00; // Firmwaer Verbosity
+ *data++ = 0x00; // BIOS Override
+ *data++ = 0x00; // Device Instance Selector
+ break;
+ case PARAM_BOOT_INIT_INFO:
+ *data++ = 0x00; // Chanel Number
+ *data++ = 0x00; // Session ID (4 bytes)
+ *data++ = 0x00;
+ *data++ = 0x00;
+ *data++ = 0x00;
+ *data++ = 0x00; // Boot Info Timestamp (4 bytes)
+ *data++ = 0x00;
+ *data++ = 0x00;
+ *data++ = 0x00;
+ break;
+ deault:
+ res->cc = CC_PARAM_OUT_OF_RANGE;
+ break;
+ }
+
+ if (res->cc == CC_SUCCESS) {
+ *res_len = data - &res->data[0];
+ }
+}
+
+// Handle Chassis Commands (IPMI/Section 28)
+static void
+ipmi_handle_chassis (unsigned char *request, unsigned char req_len,
+ unsigned char *response, unsigned char *res_len)
+{
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ unsigned char cmd = req->cmd;
+
+ pthread_mutex_lock(&m_chassis);
+ switch (cmd)
+ {
+ case CMD_CHASSIS_GET_STATUS:
+ chassis_get_status (response, res_len);
+ break;
+ case CMD_CHASSIS_GET_BOOT_OPTIONS:
+ chassis_get_boot_options (request, response, res_len);
+ break;
+ default:
+ res->cc = CC_INVALID_CMD;
+ break;
+ }
+ pthread_mutex_unlock(&m_chassis);
+}
+
+/*
+ * Function(s) to handle IPMI messages with NetFn: Application
+ */
+// Get Device ID (IPMI/Section 20.1)
+static void
+app_get_device_id (unsigned char *response, unsigned char *res_len)
+{
+
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ unsigned char *data = &res->data[0];
+
+ res->cc = CC_SUCCESS;
+
+ //TODO: Following data needs to be updated based on platform
+ *data++ = 0x20; // Device ID
+ *data++ = 0x81; // Device Revision
+ *data++ = 0x00; // Firmware Revision Major
+ *data++ = 0x09; // Firmware Revision Minor
+ *data++ = 0x02; // IPMI Version
+ *data++ = 0xBF; // Additional Device Support
+ *data++ = 0x15; // Manufacturer ID1
+ *data++ = 0xA0; // Manufacturer ID2
+ *data++ = 0x00; // Manufacturer ID3
+ *data++ = 0x46; // Product ID1
+ *data++ = 0x31; // Product ID2
+ *data++ = 0x00; // Aux. Firmware Version1
+ *data++ = 0x00; // Aux. Firmware Version2
+ *data++ = 0x00; // Aux. Firmware Version3
+ *data++ = 0x00; // Aux. Firmware Version4
+
+ *res_len = data - &res->data[0];
+}
+
+// Get Self Test Results (IPMI/Section 20.4)
+static void
+app_get_selftest_results (unsigned char *response, unsigned char *res_len)
+{
+
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ unsigned char *data = &res->data[0];
+
+ res->cc = CC_SUCCESS;
+
+ //TODO: Following data needs to be updated based on self-test results
+ *data++ = 0x55; // Self-Test result
+ *data++ = 0x00; // Extra error info in case of failure
+
+ *res_len = data - &res->data[0];
+}
+
+// Get Device GUID (IPMI/Section 20.8)
+static void
+app_get_device_guid (unsigned char *response, unsigned char *res_len)
+{
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ unsigned char *data = &res->data[0];
+
+ res->cc = 0x00;
+
+ // TODO: Following data is Globaly Unique ID i.e. MAC Address..
+ *data++ = 0x0;
+ *data++ = 0x1;
+ *data++ = 0x2;
+ *data++ = 0x3;
+ *data++ = 0x4;
+ *data++ = 0x5;
+ *data++ = 0x6;
+ *data++ = 0x7;
+ *data++ = 0x8;
+ *data++ = 0x9;
+ *data++ = 0xa;
+ *data++ = 0xb;
+ *data++ = 0xc;
+ *data++ = 0xd;
+ *data++ = 0xe;
+ *data++ = 0xf;
+
+ *res_len = data - &res->data[0];
+}
+
+// Get BMC Global Enables (IPMI/Section 22.2)
+static void
+app_get_global_enables (unsigned char *response, unsigned char *res_len)
+{
+
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ unsigned char *data = &res->data[0];
+
+ res->cc = CC_SUCCESS;
+
+ *data++ = 0x09; // Global Enable
+
+ *res_len = data - &res->data[0];
+}
+
+// Set System Info Params (IPMI/Section 22.14a)
+static void
+app_set_sys_info_params (unsigned char *request, unsigned char *response,
+ unsigned char *res_len)
+{
+
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ unsigned char param = req->data[0];
+
+ res->cc = CC_SUCCESS;
+
+ switch (param)
+ {
+ case SYS_INFO_PARAM_SET_IN_PROG:
+ g_sys_info_params.set_in_prog = req->data[1];
+ break;
+ case SYS_INFO_PARAM_SYSFW_VER:
+ memcpy(g_sys_info_params.sysfw_ver, &req->data[1], SIZE_SYSFW_VER);
+ break;
+ case SYS_INFO_PARAM_SYS_NAME:
+ memcpy(g_sys_info_params.sys_name, &req->data[1], SIZE_SYS_NAME);
+ break;
+ case SYS_INFO_PARAM_PRI_OS_NAME:
+ memcpy(g_sys_info_params.pri_os_name, &req->data[1], SIZE_OS_NAME);
+ break;
+ case SYS_INFO_PARAM_PRESENT_OS_NAME:
+ memcpy(g_sys_info_params.present_os_name, &req->data[1], SIZE_OS_NAME);
+ break;
+ case SYS_INFO_PARAM_PRESENT_OS_VER:
+ memcpy(g_sys_info_params.present_os_ver, &req->data[1], SIZE_OS_VER);
+ break;
+ case SYS_INFO_PARAM_BMC_URL:
+ memcpy(g_sys_info_params.bmc_url, &req->data[1], SIZE_BMC_URL);
+ break;
+ case SYS_INFO_PARAM_OS_HV_URL:
+ memcpy(g_sys_info_params.os_hv_url, &req->data[1], SIZE_OS_HV_URL);
+ break;
+ default:
+ res->cc = CC_INVALID_PARAM;
+ break;
+ }
+
+ return;
+}
+
+// Get System Info Params (IPMI/Section 22.14b)
+static void
+app_get_sys_info_params (unsigned char *request, unsigned char *response,
+ unsigned char *res_len)
+{
+
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ unsigned char *data = &res->data[0];
+ unsigned char param = req->data[1];
+
+ // Fill default return values
+ res->cc = CC_SUCCESS;
+ *data++ = 1; // Parameter revision
+
+ switch (param)
+ {
+ case SYS_INFO_PARAM_SET_IN_PROG:
+ *data++ = g_sys_info_params.set_in_prog;
+ break;
+ case SYS_INFO_PARAM_SYSFW_VER:
+ memcpy(data, g_sys_info_params.sysfw_ver, SIZE_SYSFW_VER);
+ data += SIZE_SYSFW_VER;
+ break;
+ case SYS_INFO_PARAM_SYS_NAME:
+ memcpy(data, g_sys_info_params.sys_name, SIZE_SYS_NAME);
+ data += SIZE_SYS_NAME;
+ break;
+ case SYS_INFO_PARAM_PRI_OS_NAME:
+ memcpy(data, g_sys_info_params.pri_os_name, SIZE_OS_NAME);
+ data += SIZE_OS_NAME;
+ break;
+ case SYS_INFO_PARAM_PRESENT_OS_NAME:
+ memcpy(data, g_sys_info_params.present_os_name, SIZE_OS_NAME);
+ data += SIZE_OS_NAME;
+ break;
+ case SYS_INFO_PARAM_PRESENT_OS_VER:
+ memcpy(data, g_sys_info_params.present_os_ver, SIZE_OS_VER);
+ data += SIZE_OS_VER;
+ break;
+ case SYS_INFO_PARAM_BMC_URL:
+ memcpy(data, g_sys_info_params.bmc_url, SIZE_BMC_URL);
+ data += SIZE_BMC_URL;
+ break;
+ case SYS_INFO_PARAM_OS_HV_URL:
+ memcpy(data, g_sys_info_params.os_hv_url, SIZE_OS_HV_URL);
+ data += SIZE_OS_HV_URL;
+ break;
+ default:
+ res->cc = CC_INVALID_PARAM;
+ break;
+ }
+
+ if (res->cc == CC_SUCCESS) {
+ *res_len = data - &res->data[0];
+ }
+
+ return;
+}
+
+// Handle Appliction Commands (IPMI/Section 20)
+static void
+ipmi_handle_app (unsigned char *request, unsigned char req_len,
+ unsigned char *response, unsigned char *res_len)
+{
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ unsigned char cmd = req->cmd;
+
+ pthread_mutex_lock(&m_app);
+ switch (cmd)
+ {
+ case CMD_APP_GET_DEVICE_ID:
+ app_get_device_id (response, res_len);
+ break;
+ case CMD_APP_GET_SELFTEST_RESULTS:
+ app_get_selftest_results (response, res_len);
+ break;
+ case CMD_APP_GET_DEVICE_GUID:
+ case CMD_APP_GET_SYSTEM_GUID:
+ // Get Device GUID and Get System GUID returns same data
+ // from IPMI stack. FYI, Get System GUID will have to be
+ // sent with in an IPMI session that includes session info
+ app_get_device_guid (response, res_len);
+ break;
+ case CMD_APP_GET_GLOBAL_ENABLES:
+ app_get_global_enables (response, res_len);
+ break;
+ case CMD_APP_SET_SYS_INFO_PARAMS:
+ app_set_sys_info_params (request, response, res_len);
+ break;
+ case CMD_APP_GET_SYS_INFO_PARAMS:
+ app_get_sys_info_params (request, response, res_len);
+ break;
+ default:
+ res->cc = CC_INVALID_CMD;
+ break;
+ }
+ pthread_mutex_unlock(&m_app);
+}
+
+/*
+ * Function(s) to handle IPMI messages with NetFn: Storage
+ */
+
+static void
+storage_get_fruid_info(unsigned char *response, unsigned char *res_len)
+{
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ unsigned char *data = &res->data[0];
+ int size = plat_fruid_size();
+
+ res->cc = CC_SUCCESS;
+
+ *data++ = size & 0xFF; // FRUID size LSB
+ *data++ = (size >> 8) & 0xFF; // FRUID size MSB
+ *data++ = 0x00; // Device accessed by bytes
+
+ *res_len = data - &res->data[0];
+
+ return;
+}
+
+static void
+storage_get_fruid_data(unsigned char *request, unsigned char *response,
+ unsigned char *res_len)
+{
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ unsigned char *data = &res->data[0];
+
+ int offset = req->data[1] + (req->data[2] << 8);
+ int count = req->data[3];
+
+ int ret = plat_fruid_data(offset, count, &(res->data[1]));
+ if (ret) {
+ res->cc = CC_UNSPECIFIED_ERROR;
+ } else {
+ res->cc = CC_SUCCESS;
+ *data++ = count;
+ data += count;
+ }
+
+ if (res->cc == CC_SUCCESS) {
+ *res_len = data - &res->data[0];
+ }
+ return;
+}
+
+static void
+storage_get_sdr_info (unsigned char *response, unsigned char *res_len)
+{
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ unsigned char *data = &res->data[0];
+ int num_entries; // number of sdr records
+ int free_space; // free space in SDR device in bytes
+ time_stamp_t ts_recent_add; // Recent Addition Timestamp
+ time_stamp_t ts_recent_erase; // Recent Erasure Timestamp
+
+ // Use platform APIs to get SDR information
+ num_entries = sdr_num_entries ();
+ free_space = sdr_free_space ();
+ sdr_ts_recent_add (&ts_recent_add);
+ sdr_ts_recent_erase (&ts_recent_erase);
+
+ res->cc = CC_SUCCESS;
+
+ *data++ = IPMI_SDR_VERSION; // SDR version
+ *data++ = num_entries & 0xFF; // number of sdr entries
+ *data++ = (num_entries >> 8) & 0xFF;
+ *data++ = free_space & 0xFF; // Free SDR Space
+ *data++ = (free_space >> 8) & 0xFF;
+
+ memcpy(data, ts_recent_add.ts, SIZE_TIME_STAMP);
+ data += SIZE_TIME_STAMP;
+
+ memcpy(data, ts_recent_erase.ts, SIZE_TIME_STAMP);
+ data += SIZE_TIME_STAMP;
+
+ *data++ = 0x02; // Operations supported
+
+ *res_len = data - &res->data[0];
+
+ return;
+}
+
+static void
+storage_rsv_sdr (unsigned char *response, unsigned char *res_len)
+{
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ unsigned char *data = &res->data[0];
+ int rsv_id; // SDR reservation ID
+
+ // Use platform APIs to get a SDR reservation ID
+ rsv_id = sdr_rsv_id ();
+ if (rsv_id < 0)
+ {
+ res->cc = CC_UNSPECIFIED_ERROR;
+ return;
+ }
+
+ res->cc = CC_SUCCESS;
+ *data++ = rsv_id & 0xFF; // Reservation ID
+ *data++ = (rsv_id >> 8) & 0XFF;
+
+ *res_len = data - &res->data[0];
+
+ return;
+}
+
+static void
+storage_get_sdr (unsigned char *request, unsigned char *response,
+ unsigned char *res_len)
+{
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ unsigned char *data = &res->data[0];
+
+ int read_rec_id; //record ID to be read
+ int next_rec_id; //record ID for the next entry
+ int rsv_id; // Reservation ID for the request
+ int rec_offset; // Read offset into the record
+ int rec_bytes; // Number of bytes to be read
+ sdr_rec_t entry; // SDR record entry
+ int ret;
+
+ rsv_id = (req->data[1] >> 8) | req->data[0];
+ read_rec_id = (req->data[3] >> 8) | req->data[2];
+ rec_offset = req->data[4];
+ rec_bytes = req->data[5];
+
+ // Use platform API to read the record Id and get next ID
+ ret = sdr_get_entry (rsv_id, read_rec_id, &entry, &next_rec_id);
+ if (ret)
+ {
+ res->cc = CC_UNSPECIFIED_ERROR;
+ return;
+ }
+
+ res->cc = CC_SUCCESS;
+ *data++ = next_rec_id & 0xFF; // next record ID
+ *data++ = (next_rec_id >> 8) & 0xFF;
+
+ memcpy (data, &entry.rec[rec_offset], rec_bytes);
+ data += rec_bytes;
+
+ *res_len = data - &res->data[0];
+
+ return;
+}
+
+static void
+storage_get_sel_info (unsigned char *response, unsigned char *res_len)
+{
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ unsigned char *data = &res->data[0];
+ int num_entries; // number of log entries
+ int free_space; // free space in SEL device in bytes
+ time_stamp_t ts_recent_add; // Recent Addition Timestamp
+ time_stamp_t ts_recent_erase; // Recent Erasure Timestamp
+
+ // Use platform APIs to get SEL information
+ num_entries = sel_num_entries ();
+ free_space = sel_free_space ();
+ sel_ts_recent_add (&ts_recent_add);
+ sel_ts_recent_erase (&ts_recent_erase);
+
+ res->cc = CC_SUCCESS;
+
+ *data++ = IPMI_SEL_VERSION; // SEL version
+ *data++ = num_entries & 0xFF; // number of log entries
+ *data++ = (num_entries >> 8) & 0xFF;
+ *data++ = free_space & 0xFF; // Free SEL Space
+ *data++ = (free_space >> 8) & 0xFF;
+
+ memcpy(data, ts_recent_add.ts, SIZE_TIME_STAMP);
+ data += SIZE_TIME_STAMP;
+
+ memcpy(data, ts_recent_erase.ts, SIZE_TIME_STAMP);
+ data += SIZE_TIME_STAMP;
+
+ *data++ = 0x02; // Operations supported
+
+ *res_len = data - &res->data[0];
+
+ return;
+}
+
+static void
+storage_rsv_sel (unsigned char *response, unsigned char *res_len)
+{
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ unsigned char *data = &res->data[0];
+ int rsv_id; // SEL reservation ID
+
+ // Use platform APIs to get a SEL reservation ID
+ rsv_id = sel_rsv_id ();
+ if (rsv_id < 0)
+ {
+ res->cc = CC_SEL_ERASE_PROG;
+ return;
+ }
+
+ res->cc = CC_SUCCESS;
+ *data++ = rsv_id & 0xFF; // Reservation ID
+ *data++ = (rsv_id >> 8) & 0XFF;
+
+ *res_len = data - &res->data[0];
+
+ return;
+}
+
+static void
+storage_get_sel (unsigned char *request, unsigned char *response,
+ unsigned char *res_len)
+{
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ unsigned char *data = &res->data[0];
+
+ int read_rec_id; //record ID to be read
+ int next_rec_id; //record ID for the next msg
+ sel_msg_t entry; // SEL log entry
+ int ret;
+
+ read_rec_id = (req->data[3] >> 8) | req->data[2];
+
+ // Use platform API to read the record Id and get next ID
+ ret = sel_get_entry (read_rec_id, &entry, &next_rec_id);
+ if (ret)
+ {
+ res->cc = CC_UNSPECIFIED_ERROR;
+ return;
+ }
+
+ res->cc = CC_SUCCESS;
+ *data++ = next_rec_id & 0xFF; // next record ID
+ *data++ = (next_rec_id >> 8) & 0xFF;
+
+ memcpy(data, entry.msg, SIZE_SEL_REC);
+ data += SIZE_SEL_REC;
+
+ *res_len = data - &res->data[0];
+
+ return;
+}
+
+static void
+storage_add_sel (unsigned char *request, unsigned char *response,
+ unsigned char *res_len)
+{
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ unsigned char *data = &res->data[0];
+
+
+ int record_id; // Record ID for added entry
+ int ret;
+
+ sel_msg_t entry;
+
+ memcpy(entry.msg, req->data, SIZE_SEL_REC);
+
+ // Use platform APIs to add the new SEL entry
+ ret = sel_add_entry (&entry, &record_id);
+ if (ret)
+ {
+ res->cc = CC_UNSPECIFIED_ERROR;
+ return;
+ }
+
+ res->cc = CC_SUCCESS;
+ *data++ = record_id & 0xFF;
+ *data++ = (record_id >> 8) & 0xFF;
+
+ *res_len = data - &res->data[0];
+
+ return;
+}
+
+static void
+storage_clr_sel (unsigned char *request, unsigned char *response,
+ unsigned char *res_len)
+{
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ unsigned char *data = &res->data[0];
+
+ sel_erase_stat_t status;
+ int ret;
+ int rsv_id;
+
+ // Verify the request to contain 'CLR' characters
+ if ((req->data[2] != 'C') || (req->data[3] != 'L') || (req->data[4] != 'R'))
+ {
+ res->cc = CC_INVALID_PARAM;
+ return;
+ }
+
+ // Populate reservation ID given in request
+ rsv_id = (req->data[1] << 8) | req->data[0];
+
+ // Use platform APIs to clear or get status
+ if (req->data[5] == IPMI_SEL_INIT_ERASE)
+ {
+ ret = sel_erase (rsv_id);
+ }
+ else if (req->data[5] == IPMI_SEL_ERASE_STAT)
+ {
+ ret = sel_erase_status (rsv_id, &status);
+ }
+ else
+ {
+ res->cc = CC_INVALID_PARAM;
+ return;
+ }
+
+ // Handle platform error and return
+ if (ret)
+ {
+ res->cc = CC_UNSPECIFIED_ERROR;
+ return;
+ }
+
+ res->cc = CC_SUCCESS;
+ *data++ = status;
+
+ *res_len = data - &res->data[0];
+
+ return;
+}
+
+static void
+ipmi_handle_storage (unsigned char *request, unsigned char req_len,
+ unsigned char *response, unsigned char *res_len)
+{
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ unsigned char cmd = req->cmd;
+
+ res->cc = CC_SUCCESS;
+ *res_len = 0;
+
+ pthread_mutex_lock(&m_storage);
+ switch (cmd)
+ {
+ case CMD_STORAGE_GET_FRUID_INFO:
+ storage_get_fruid_info (response, res_len);
+ break;
+ case CMD_STORAGE_READ_FRUID_DATA:
+ storage_get_fruid_data (request, response, res_len);
+ break;
+ case CMD_STORAGE_GET_SEL_INFO:
+ storage_get_sel_info (response, res_len);
+ break;
+ case CMD_STORAGE_RSV_SEL:
+ storage_rsv_sel (response, res_len);
+ break;
+ case CMD_STORAGE_ADD_SEL:
+ storage_add_sel (request, response, res_len);
+ break;
+ case CMD_STORAGE_GET_SEL:
+ storage_get_sel (request, response, res_len);
+ break;
+ case CMD_STORAGE_CLR_SEL:
+ storage_clr_sel (request, response, res_len);
+ break;
+ case CMD_STORAGE_GET_SDR_INFO:
+ storage_get_sdr_info (response, res_len);
+ break;
+ case CMD_STORAGE_RSV_SDR:
+ storage_rsv_sdr (response, res_len);
+ break;
+ case CMD_STORAGE_GET_SDR:
+ storage_get_sdr (request, response, res_len);
+ break;
+ default:
+ res->cc = CC_INVALID_CMD;
+ break;
+ }
+
+ pthread_mutex_unlock(&m_storage);
+ return;
+}
+
+/*
+ * Function(s) to handle IPMI messages with NetFn: Transport
+ */
+
+// Set LAN Configuration (IPMI/Section 23.1)
+static void
+transport_set_lan_config (unsigned char *request, unsigned char *response,
+ unsigned char *res_len)
+{
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ unsigned char param = req->data[1];
+
+ // Fill the response with default values
+ res->cc = CC_SUCCESS;
+
+ switch (param)
+ {
+ case LAN_PARAM_SET_IN_PROG:
+ g_lan_config.set_in_prog = req->data[2];
+ break;
+ case LAN_PARAM_AUTH_SUPPORT:
+ g_lan_config.auth_support = req->data[2];
+ break;
+ case LAN_PARAM_AUTH_ENABLES:
+ memcpy(g_lan_config.auth_enables, &req->data[2], SIZE_AUTH_ENABLES);
+ break;
+ case LAN_PARAM_IP_ADDR:
+ memcpy(g_lan_config.ip_addr, &req->data[2], SIZE_IP_ADDR);
+ break;
+ case LAN_PARAM_IP_SRC:
+ g_lan_config.ip_src = req->data[2];
+ break;
+ case LAN_PARAM_MAC_ADDR:
+ memcpy(g_lan_config.mac_addr, &req->data[2], SIZE_MAC_ADDR);
+ break;
+ case LAN_PARAM_NET_MASK:
+ memcpy(g_lan_config.net_mask, &req->data[2], SIZE_NET_MASK);
+ break;
+ case LAN_PARAM_IP_HDR:
+ memcpy(g_lan_config.ip_hdr, &req->data[2], SIZE_IP_HDR);
+ break;
+ case LAN_PARAM_PRI_RMCP_PORT:
+ g_lan_config.pri_rmcp_port[0] = req->data[2];
+ g_lan_config.pri_rmcp_port[1] = req->data[3];
+ break;
+ case LAN_PARAM_SEC_RMCP_PORT:
+ g_lan_config.sec_rmcp_port[0] = req->data[2];
+ g_lan_config.sec_rmcp_port[1] = req->data[3];
+ break;
+ case LAN_PARAM_ARP_CTRL:
+ g_lan_config.arp_ctrl = req->data[2];
+ break;
+ case LAN_PARAM_GARP_INTERVAL:
+ g_lan_config.garp_interval = req->data[2];
+ break;
+ case LAN_PARAM_DF_GW_IP_ADDR:
+ memcpy(g_lan_config.df_gw_ip_addr, &req->data[2], SIZE_IP_ADDR);
+ break;
+ case LAN_PARAM_DF_GW_MAC_ADDR:
+ memcpy(g_lan_config.df_gw_mac_addr, &req->data[2], SIZE_MAC_ADDR);
+ break;
+ case LAN_PARAM_BACK_GW_IP_ADDR:
+ memcpy(g_lan_config.back_gw_ip_addr, &req->data[2], SIZE_IP_ADDR);
+ break;
+ case LAN_PARAM_BACK_GW_MAC_ADDR:
+ memcpy(g_lan_config.back_gw_mac_addr, &req->data[2], SIZE_MAC_ADDR);
+ break;
+ case LAN_PARAM_COMMUNITY_STR:
+ memcpy(g_lan_config.community_str, &req->data[2], SIZE_COMMUNITY_STR);
+ break;
+ case LAN_PARAM_NO_OF_DEST:
+ g_lan_config.no_of_dest = req->data[2];
+ break;
+ case LAN_PARAM_DEST_TYPE:
+ memcpy(g_lan_config.dest_type, &req->data[2], SIZE_DEST_TYPE);
+ break;
+ case LAN_PARAM_DEST_ADDR:
+ memcpy(g_lan_config.dest_addr, &req->data[2], SIZE_DEST_ADDR);
+ break;
+ default:
+ res->cc = CC_INVALID_PARAM;
+ break;
+ }
+}
+
+// Get LAN Configuration (IPMI/Section 23.2)
+static void
+transport_get_lan_config (unsigned char *request, unsigned char *response,
+ unsigned char *res_len)
+{
+
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ unsigned char *data = &res->data[0];
+ unsigned char param = req->data[1];
+
+ // Fill the response with default values
+ res->cc = CC_SUCCESS;
+ *data++ = 0x01; // Parameter revision
+
+ switch (param)
+ {
+ case LAN_PARAM_SET_IN_PROG:
+ *data++ = g_lan_config.set_in_prog;
+ break;
+ case LAN_PARAM_AUTH_SUPPORT:
+ *data++ = g_lan_config.auth_support;
+ break;
+ case LAN_PARAM_AUTH_ENABLES:
+ memcpy(data, g_lan_config.auth_enables, SIZE_AUTH_ENABLES);
+ data += SIZE_AUTH_ENABLES;
+ break;
+ case LAN_PARAM_IP_ADDR:
+ memcpy(data, g_lan_config.ip_addr, SIZE_IP_ADDR);
+ data += SIZE_IP_ADDR;
+ break;
+ case LAN_PARAM_IP_SRC:
+ *data++ = g_lan_config.ip_src;
+ break;
+ case LAN_PARAM_MAC_ADDR:
+ memcpy(data, g_lan_config.mac_addr, SIZE_MAC_ADDR);
+ data += SIZE_MAC_ADDR;
+ break;
+ case LAN_PARAM_NET_MASK:
+ memcpy(data, g_lan_config.net_mask, SIZE_NET_MASK);
+ data += SIZE_NET_MASK;
+ break;
+ case LAN_PARAM_IP_HDR:
+ memcpy(data, g_lan_config.ip_hdr, SIZE_IP_HDR);
+ data += SIZE_IP_HDR;
+ break;
+ case LAN_PARAM_PRI_RMCP_PORT:
+ *data++ = g_lan_config.pri_rmcp_port[0];
+ *data++ = g_lan_config.pri_rmcp_port[1];
+ break;
+ case LAN_PARAM_SEC_RMCP_PORT:
+ *data++ = g_lan_config.sec_rmcp_port[0];
+ *data++ = g_lan_config.sec_rmcp_port[1];
+ break;
+ case LAN_PARAM_ARP_CTRL:
+ *data++ = g_lan_config.arp_ctrl;
+ break;
+ case LAN_PARAM_GARP_INTERVAL:
+ *data++ = g_lan_config.garp_interval;
+ break;
+ case LAN_PARAM_DF_GW_IP_ADDR:
+ memcpy(data, g_lan_config.df_gw_ip_addr, SIZE_IP_ADDR);
+ data += SIZE_IP_ADDR;
+ break;
+ case LAN_PARAM_DF_GW_MAC_ADDR:
+ memcpy(data, g_lan_config.df_gw_mac_addr, SIZE_MAC_ADDR);
+ data += SIZE_MAC_ADDR;
+ break;
+ case LAN_PARAM_BACK_GW_IP_ADDR:
+ memcpy(data, g_lan_config.back_gw_ip_addr, SIZE_IP_ADDR);
+ data += SIZE_IP_ADDR;
+ break;
+ case LAN_PARAM_BACK_GW_MAC_ADDR:
+ memcpy(data, g_lan_config.back_gw_mac_addr, SIZE_MAC_ADDR);
+ data += SIZE_MAC_ADDR;
+ break;
+ case LAN_PARAM_COMMUNITY_STR:
+ memcpy(data, g_lan_config.community_str, SIZE_COMMUNITY_STR);
+ data += SIZE_COMMUNITY_STR;
+ break;
+ case LAN_PARAM_NO_OF_DEST:
+ *data++ = g_lan_config.no_of_dest;
+ break;
+ case LAN_PARAM_DEST_TYPE:
+ memcpy(data, g_lan_config.dest_type, SIZE_DEST_TYPE);
+ data += SIZE_DEST_TYPE;
+ break;
+ case LAN_PARAM_DEST_ADDR:
+ memcpy(data, g_lan_config.dest_addr, SIZE_DEST_ADDR);
+ data += SIZE_DEST_ADDR;
+ break;
+ default:
+ res->cc = CC_INVALID_PARAM;
+ break;
+ }
+
+ if (res->cc == CC_SUCCESS) {
+ *res_len = data - &res->data[0];
+ }
+}
+
+// Handle Transport Commands (IPMI/Section 23)
+static void
+ipmi_handle_transport (unsigned char *request, unsigned char req_len,
+ unsigned char *response, unsigned char *res_len)
+{
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ unsigned char cmd = req->cmd;
+
+ pthread_mutex_lock(&m_transport);
+ switch (cmd)
+ {
+ case CMD_TRANSPORT_SET_LAN_CONFIG:
+ transport_set_lan_config (request, response, res_len);
+ break;
+ case CMD_TRANSPORT_GET_LAN_CONFIG:
+ transport_get_lan_config (request, response, res_len);
+ break;
+ default:
+ res->cc = CC_INVALID_CMD;
+ break;
+ }
+ pthread_mutex_unlock(&m_transport);
+}
+
+/*
+ * Function(s) to handle IPMI messages with NetFn: OEM
+ */
+
+static void
+oem_set_proc_info (unsigned char *request, unsigned char *response,
+ unsigned char *res_len)
+{
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
+ ipmi_res_t *res = (ipmi_res_t *) response;
+
+ g_proc_info.type = req->data[1];
+ g_proc_info.freq[0] = req->data[2];
+ g_proc_info.freq[1] = req->data[3];
+
+ res->cc = CC_SUCCESS;
+ *res_len = 0;
+}
+
+static void
+oem_set_dimm_info (unsigned char *request, unsigned char *response,
+ unsigned char *res_len)
+{
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
+ ipmi_res_t *res = (ipmi_res_t *) response;
+
+ unsigned char index = req->data[0];
+
+ g_dimm_info[index].type = req->data[1];
+ g_dimm_info[index].speed[0] = req->data[2];
+ g_dimm_info[index].speed[1] = req->data[3];
+ g_dimm_info[index].size[0] = req->data[4];
+ g_dimm_info[index].size[1] = req->data[5];
+
+ res->cc = CC_SUCCESS;
+ *res_len = 0;
+}
+
+static void
+oem_set_post_start (unsigned char *request, unsigned char *response,
+ unsigned char *res_len)
+{
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
+ ipmi_res_t *res = (ipmi_res_t *) response;
+
+ // TODO: For now logging the event, need to find usage for this info
+ syslog (LOG_INFO, "POST Start Event for Payload#%d\n", req->payload_id);
+
+ res->cc = CC_SUCCESS;
+ *res_len = 0;
+}
+
+static void
+oem_set_post_end (unsigned char *request, unsigned char *response,
+ unsigned char *res_len)
+{
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
+ ipmi_res_t *res = (ipmi_res_t *) response;
+
+ // TODO: For now logging the event, need to find usage for this info
+ syslog (LOG_INFO, "POST End Event for Payload#%d\n", req->payload_id);
+
+ res->cc = CC_SUCCESS;
+ *res_len = 0;
+}
+
+static void
+ipmi_handle_oem (unsigned char *request, unsigned char req_len,
+ unsigned char *response, unsigned char *res_len)
+{
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
+ ipmi_res_t *res = (ipmi_res_t *) response;
+
+ unsigned char cmd = req->cmd;
+
+ pthread_mutex_lock(&m_oem);
+ switch (cmd)
+ {
+ case CMD_OEM_SET_PROC_INFO:
+ oem_set_proc_info (request, response, res_len);
+ break;
+ case CMD_OEM_SET_DIMM_INFO:
+ oem_set_dimm_info (request, response, res_len);
+ break;
+ case CMD_OEM_SET_POST_START:
+ oem_set_post_start (request, response, res_len);
+ break;
+ case CMD_OEM_SET_POST_END:
+ oem_set_post_end (request, response, res_len);
+ break;
+ default:
+ res->cc = CC_INVALID_CMD;
+ break;
+ }
+ pthread_mutex_unlock(&m_oem);
+}
+
+static void
+oem_1s_handle_ipmb_kcs(unsigned char *request, unsigned char req_len,
+ unsigned char *response, unsigned char *res_len)
+{
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
+ ipmi_res_t *res = (ipmi_res_t *) response;
+
+ // Need to extract bridged IPMI command and handle
+ unsigned char req_buf[MAX_IPMI_MSG_SIZE] = {0};
+ unsigned char res_buf[MAX_IPMI_MSG_SIZE] = {0};
+
+ // Add the payload id from the bridged command
+ req_buf[0] = req->payload_id;
+
+ // Remove OEM IPMI Header + 1 byte for BIC interface
+ // The offset moves by one due to the payload ID
+ memcpy(&req_buf[1], &request[BIC_INTF_HDR_SIZE + 1], req_len - BIC_INTF_HDR_SIZE);
+
+ // Send the bridged KCS command along with the payload ID
+ // The offset moves by one due to the payload ID
+ ipmi_handle(req_buf, req_len - BIC_INTF_HDR_SIZE + 1, res_buf, res_len);
+
+ // Copy the response back
+ memcpy(&res->data[1], res_buf, *res_len);
+
+ // Add the OEM command's response
+ res->cc = CC_SUCCESS;
+ res->data[0] = req->data[0]; // Bridge-IC interface
+ *res_len += 1;
+}
+
+static void
+oem_1s_handle_ipmb_req(unsigned char *request, unsigned char req_len,
+ unsigned char *response, unsigned char *res_len)
+{
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
+ ipmi_res_t *res = (ipmi_res_t *) response;
+
+ // handle based on Bridge-IC interface
+ switch(req->data[0]) {
+ case BIC_INTF_ME:
+ // TODO: Need to call ME command handler
+ syslog(LOG_INFO, "oem_1s_handle_ipmb_req: Command received from ME for "
+ "payload#%d\n", req->payload_id);
+ res->data[0] = BIC_INTF_ME;
+ res->cc = CC_SUCCESS;
+ *res_len = 1;
+ break;
+ case BIC_INTF_SOL:
+ // TODO: Need to call Optional SoL message handler
+ syslog(LOG_INFO, "oem_1s_handle_ipmb_req: Command received from SOL for "
+ "payload#%d\n", req->payload_id);
+ res->data[0] = BIC_INTF_SOL;
+ res->cc = CC_SUCCESS;
+ *res_len = 1;
+ break;
+ case BIC_INTF_KCS:
+ oem_1s_handle_ipmb_kcs(request, req_len, response, res_len);
+ break;
+ default:
+ // TODO: Need to add additonal interface handler, if supported
+ syslog(LOG_ALERT, "oem_1s_handle_ipmb_req: Command received on intf#%d "
+ "for payload#%d", req->data[0], req->payload_id);
+ res->cc = CC_INVALID_PARAM;
+ *res_len = 0;
+ break;
+ }
+}
+
+static void
+ipmi_handle_oem_1s(unsigned char *request, unsigned char req_len,
+ unsigned char *response, unsigned char *res_len)
+{
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ int i;
+
+ unsigned char cmd = req->cmd;
+
+ pthread_mutex_lock(&m_oem_1s);
+ switch (cmd)
+ {
+ case CMD_OEM_1S_MSG_IN:
+ oem_1s_handle_ipmb_req(request, req_len, response, res_len);
+ break;
+ case CMD_OEM_1S_INTR:
+ syslog(LOG_INFO, "ipmi_handle_oem_1s: 1S server interrupt#%d received "
+ "for payload#%d\n", req->data[0], req->payload_id);
+
+ res->cc = CC_SUCCESS;
+ *res_len = 0;
+ break;
+ case CMD_OEM_1S_POST_BUF:
+ for (i = 1; i <= req->data[0]; i++) {
+ pal_post_handle(req->payload_id, req->data[i]);
+ }
+
+ res->cc = CC_SUCCESS;
+ *res_len = 0;
+ break;
+ case CMD_OEM_1S_PLAT_DISC:
+ syslog(LOG_INFO, "ipmi_handle_oem_1s: Platform Discovery received for "
+ "payload#%d\n", req->payload_id);
+ res->cc = CC_SUCCESS;
+ *res_len = 0;
+ break;
+ case CMD_OEM_1S_BIC_RESET:
+ syslog(LOG_INFO, "ipmi_handle_oem_1s: BIC Reset received "
+ "for payload#%d\n", req->payload_id);
+
+ if (req->data[0] == 0x0) {
+ syslog(LOG_ALERT, "Cold Reset by Firmware Update\n");
+ res->cc = CC_SUCCESS;
+ } else if (req->data[1] == 0x01) {
+ syslog(LOG_ALERT, "WDT Reset\n");
+ res->cc = CC_SUCCESS;
+ } else {
+ syslog(LOG_ALERT, "Error\n");
+ res->cc = CC_INVALID_PARAM;
+ }
+
+ *res_len = 0;
+ break;
+ case CMD_OEM_1S_BIC_UPDATE_MODE:
+ syslog(LOG_INFO, "ipmi_handle_oem_1s: BIC Update Mode received "
+ "for payload#%d\n", req->payload_id);
+
+ if (req->data[0] == 0x0) {
+ syslog(LOG_INFO, "Normal Mode\n");
+ res->cc = CC_SUCCESS;
+ } else if (req->data[1] == 0x0F) {
+ syslog(LOG_INFO, "Update Mode\n");
+ res->cc = CC_SUCCESS;
+ } else {
+ syslog(LOG_ALERT, "Error\n");
+ res->cc = CC_INVALID_PARAM;
+ }
+
+ *res_len = 0;
+ break;
+ default:
+ res->cc = CC_INVALID_CMD;
+ *res_len = 0;
+ break;
+ }
+ pthread_mutex_unlock(&m_oem_1s);
+}
+
+/*
+ * Function to handle all IPMI messages
+ */
+static void
+ipmi_handle (unsigned char *request, unsigned char req_len,
+ unsigned char *response, unsigned char *res_len)
+{
+
+ ipmi_mn_req_t *req = (ipmi_mn_req_t *) request;
+ ipmi_res_t *res = (ipmi_res_t *) response;
+ unsigned char netfn;
+
+ netfn = req->netfn_lun >> 2;
+
+ // Provide default values in the response message
+ res->cmd = req->cmd;
+ res->cc = 0xFF; // Unspecified completion code
+ *res_len = 0;
+
+ switch (netfn)
+ {
+ case NETFN_CHASSIS_REQ:
+ res->netfn_lun = NETFN_CHASSIS_RES << 2;
+ ipmi_handle_chassis (request, req_len, response, res_len);
+ break;
+ case NETFN_APP_REQ:
+ res->netfn_lun = NETFN_APP_RES << 2;
+ ipmi_handle_app (request, req_len, response, res_len);
+ break;
+ case NETFN_STORAGE_REQ:
+ res->netfn_lun = NETFN_STORAGE_RES << 2;
+ ipmi_handle_storage (request, req_len, response, res_len);
+ break;
+ case NETFN_TRANSPORT_REQ:
+ res->netfn_lun = NETFN_TRANSPORT_RES << 2;
+ ipmi_handle_transport (request, req_len, response, res_len);
+ break;
+ case NETFN_OEM_REQ:
+ res->netfn_lun = NETFN_OEM_RES << 2;
+ ipmi_handle_oem (request, req_len, response, res_len);
+ break;
+ case NETFN_OEM_1S_REQ:
+ res->netfn_lun = NETFN_OEM_1S_RES << 2;
+ ipmi_handle_oem_1s(request, req_len, response, res_len);
+ break;
+ default:
+ res->netfn_lun = (netfn + 1) << 2;
+ break;
+ }
+
+ // This header includes NetFunction, Command, and Completion Code
+ *res_len += IPMI_RESP_HDR_SIZE;
+
+ return;
+}
+
+void
+*conn_handler(void *socket_desc) {
+ int sock = *(int*)socket_desc;
+ int n;
+ unsigned char req_buf[MAX_IPMI_MSG_SIZE];
+ unsigned char res_buf[MAX_IPMI_MSG_SIZE];
+ unsigned char res_len = 0;
+
+ n = recv (sock, req_buf, sizeof(req_buf), 0);
+ if (n <= 0) {
+ syslog(LOG_ALERT, "ipmid: recv() failed with %d\n", n);
+ goto conn_cleanup;
+ }
+
+ ipmi_handle(req_buf, n, res_buf, &res_len);
+
+ if (send (sock, res_buf, res_len, 0) < 0) {
+ syslog(LOG_ALERT, "ipmid: send() failed\n");
+ }
+
+conn_cleanup:
+ close(sock);
+
+ pthread_exit(NULL);
+ return 0;
+}
+
+
+int
+main (void)
+{
+ int s, s2, t, len;
+ struct sockaddr_un local, remote;
+ pthread_t tid;
+
+ daemon(1, 0);
+ openlog("ipmid", LOG_CONS, LOG_DAEMON);
+
+
+ plat_fruid_init();
+ plat_sensor_init();
+
+ sdr_init();
+ sel_init();
+
+ pthread_mutex_init(&m_chassis, NULL);
+ pthread_mutex_init(&m_app, NULL);
+ pthread_mutex_init(&m_storage, NULL);
+ pthread_mutex_init(&m_transport, NULL);
+ pthread_mutex_init(&m_oem, NULL);
+ pthread_mutex_init(&m_oem_1s, NULL);
+
+ if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) == -1)
+ {
+ syslog(LOG_ALERT, "ipmid: socket() failed\n");
+ exit (1);
+ }
+
+ local.sun_family = AF_UNIX;
+ strcpy (local.sun_path, SOCK_PATH_IPMI);
+ unlink (local.sun_path);
+ len = strlen (local.sun_path) + sizeof (local.sun_family);
+ if (bind (s, (struct sockaddr *) &local, len) == -1)
+ {
+ syslog(LOG_ALERT, "ipmid: bind() failed\n");
+ exit (1);
+ }
+
+ if (listen (s, 5) == -1)
+ {
+ syslog(LOG_ALERT, "ipmid: listen() failed\n");
+ exit (1);
+ }
+
+ while(1) {
+ int n;
+ t = sizeof (remote);
+ if ((s2 = accept (s, (struct sockaddr *) &remote, &t)) < 0) {
+ syslog(LOG_ALERT, "ipmid: accept() failed\n");
+ break;
+ }
+
+ // Creating a worker thread to handle the request
+ // TODO: Need to monitor the server performance with higher load and
+ // see if we need to create pre-defined number of workers and schedule
+ // the requests among them.
+ if (pthread_create(&tid, NULL, conn_handler, (void*) &s2) < 0) {
+ syslog(LOG_ALERT, "ipmid: pthread_create failed\n");
+ close(s2);
+ continue;
+ }
+
+ pthread_detach(tid);
+ }
+
+ close(s);
+
+ pthread_mutex_destroy(&m_chassis);
+ pthread_mutex_destroy(&m_app);
+ pthread_mutex_destroy(&m_storage);
+ pthread_mutex_destroy(&m_transport);
+ pthread_mutex_destroy(&m_oem);
+ pthread_mutex_destroy(&m_oem_1s);
+
+ return 0;
+}
diff --git a/common/recipes-core/ipmid/files/sdr.c b/common/recipes-core/ipmid/files/sdr.c
new file mode 100644
index 0000000..91a4df5
--- /dev/null
+++ b/common/recipes-core/ipmid/files/sdr.c
@@ -0,0 +1,414 @@
+/*
+ *
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * This file represents platform specific implementation for storing
+ * SDR record entries and acts as back-end for IPMI stack
+ *
+ *
+ * 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.
+ */
+#include "sdr.h"
+#include "sensor.h"
+#include "timestamp.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <syslog.h>
+#include <string.h>
+#include <openbmc/ipmi.h>
+
+// SDR Header magic number
+#define SDR_HDR_MAGIC 0xFBFBFBFB
+
+// SDR Header version number
+#define SDR_HDR_VERSION 0x01
+
+// SDR reservation IDs can not be 0x00 or 0xFFFF
+#define SDR_RSVID_MIN 0x01
+#define SDR_RSVID_MAX 0xFFFE
+
+#define SDR_RECORDS_MAX 64 // to support around 64 sensors
+
+// SDR index to keep track
+#define SDR_INDEX_MIN 0
+#define SDR_INDEX_MAX (SDR_RECORDS_MAX - 1)
+
+// Record ID can not be 0x0 (IPMI/Section 31)
+#define SDR_RECID_MIN 1
+#define SDR_RECID_MAX SDR_RECORDS_MAX
+
+// Special RecID value for first and last (IPMI/Section 31)
+#define SDR_RECID_FIRST 0x0000
+#define SDR_RECID_LAST 0xFFFF
+
+#define SDR_VERSION 0x51
+#define SDR_LEN_MAX 64
+
+#define SDR_FULL_TYPE 0x01
+#define SDR_MGMT_TYPE 0x12
+#define SDR_OEM_TYPE 0xC0
+
+#define SDR_FULL_LEN 64
+#define SDR_MGMT_LEN 32
+#define SDR_OEM_LEN 64
+
+// SDR header struct to keep track of SEL Log entries
+typedef struct {
+ int magic; // Magic number to check validity
+ int version; // version number of this header
+ int begin; // index to the first SDR entry
+ int end; // index to the last SDR entry
+ time_stamp_t ts_add; // last addition time stamp
+ time_stamp_t ts_erase; // last erase time stamp
+} sdr_hdr_t;
+
+// Keep track of last Reservation ID
+static int g_rsv_id = 0x01;
+
+// SDR Header and data global structures
+static sdr_hdr_t g_sdr_hdr;
+static sdr_rec_t g_sdr_data[SDR_RECORDS_MAX];
+
+// Add a new SDR entry
+static int
+sdr_add_entry(sdr_rec_t *rec, int *rec_id) {
+ // If SDR is full, return error
+ if (sdr_num_entries() == SDR_RECORDS_MAX) {
+ syslog(LOG_ALERT, "sdr_add_entry: SDR full\n");
+ return -1;
+ }
+
+ // Add Record ID which is array index + 1
+ rec->rec[0] = g_sdr_hdr.end+1;
+
+ // Add the enry at end
+ memcpy(g_sdr_data[g_sdr_hdr.end].rec, rec->rec, sizeof(sdr_rec_t));
+
+ // Return the newly added record ID
+ *rec_id = g_sdr_hdr.end+1;
+
+ // Increment the end pointer
+ ++g_sdr_hdr.end;
+
+ // Update timestamp for add in header
+ time_stamp_fill(g_sdr_hdr.ts_add.ts);
+
+ return 0;
+}
+
+static int
+sdr_add_mgmt_rec(sensor_mgmt_t *p_rec) {
+ int rec_id = 0;
+ sdr_rec_t sdr = { 0 };
+ sdr_mgmt_t rec = { 0 };
+
+ // Populate SDR MGMT record
+ rec.ver = SDR_VERSION;
+ rec.type = SDR_MGMT_TYPE;
+ rec.len = SDR_MGMT_LEN;
+
+ rec.slave_addr = p_rec->slave_addr;
+ rec.chan_no = p_rec->chan_no;
+
+ rec.pwr_state_init = p_rec->pwr_state_init;
+ rec.dev_caps = p_rec->dev_caps;
+ rec.ent_id = p_rec->ent_id;
+ rec.ent_inst = p_rec->ent_inst;
+ rec.oem = p_rec->oem;
+ rec.str_type_len = p_rec->str_type_len;
+ memcpy(rec.str, p_rec->str, SENSOR_STR_SIZE);
+
+ // Copy this record to generic SDR record
+ memcpy(sdr.rec, &rec, SDR_LEN_MAX);
+
+ // Add this record to SDR repo
+ if (sdr_add_entry(&sdr, &rec_id)) {
+ syslog(LOG_ALERT, "sdr_add_mgmt_rec: sdr_add_entry failed\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+sdr_add_disc_rec(sensor_disc_t *p_rec) {
+ int rec_id = 0;
+ sdr_rec_t sdr = { 0 };
+ sdr_full_t rec = { 0 };
+
+ // Populate SDR FULL record
+ rec.ver = SDR_VERSION;
+ rec.type = SDR_FULL_TYPE;
+ rec.len = SDR_FULL_LEN;
+
+ rec.owner = p_rec->owner;
+ rec.lun = p_rec->lun;
+
+ rec.ent_id = p_rec->ent_id;
+ rec.ent_inst = p_rec->ent_inst;
+ rec.sensor_init = p_rec->sensor_init;
+ rec.sensor_caps = p_rec->sensor_caps;
+ rec.sensor_type = p_rec->sensor_type;
+ rec.evt_read_type = p_rec->evt_read_type;
+ memcpy(rec.assert_evt_mask, p_rec->assert_evt_mask, 2);
+ memcpy(rec.deassert_evt_mask, p_rec->deassert_evt_mask, 2);
+ memcpy(rec.read_evt_mask, p_rec->read_evt_mask, 2);
+ rec.oem = p_rec->oem;
+ rec.str_type_len = p_rec->str_type_len;
+ memcpy(rec.str, p_rec->str, SENSOR_STR_SIZE);
+
+ // Copy this record to generic SDR record
+ memcpy(sdr.rec, &rec, SDR_LEN_MAX);
+
+ // Add this record to SDR repo
+ if (sdr_add_entry(&sdr, &rec_id)) {
+ syslog(LOG_ALERT, "sdr_add_disc_rec: sdr_add_entry failed\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+sdr_add_thresh_rec(sensor_thresh_t *p_rec) {
+ int rec_id = 0;
+ sdr_rec_t sdr = { 0 };
+ sdr_full_t rec = { 0 };
+
+ // Populate SDR FULL record
+ rec.ver = SDR_VERSION;
+ rec.type = SDR_FULL_TYPE;
+ rec.len = SDR_FULL_LEN;
+
+ rec.owner = p_rec->owner;
+ rec.lun = p_rec->lun;
+
+ rec.ent_id = p_rec->ent_id;
+ rec.ent_inst = p_rec->ent_inst;
+ rec.sensor_init = p_rec->sensor_init;
+ rec.sensor_caps = p_rec->sensor_caps;
+ rec.sensor_type = p_rec->sensor_type;
+ rec.evt_read_type = p_rec->evt_read_type;
+ memcpy(rec.lt_read_mask, p_rec->lt_read_mask, 2);
+ memcpy(rec.ut_read_mask, p_rec->ut_read_mask, 2);
+ memcpy(rec.set_thresh_mask, p_rec->set_thresh_mask, 2);
+ rec.sensor_units1 = p_rec->sensor_units1;
+ rec.sensor_units2 = p_rec->sensor_units2;
+ rec.sensor_units3 = p_rec->sensor_units3;
+ rec.linear = p_rec->linear;
+ rec.m_val = p_rec->m_val;
+ rec.m_tolerance = p_rec->m_tolerance;
+ rec.b_val = p_rec->b_val;
+ rec.b_accuracy = p_rec->b_accuracy;
+ rec.analog_flags = p_rec->analog_flags;
+ rec.nominal = p_rec->nominal;
+ rec.normal_max = p_rec->normal_max;
+ rec.normal_min = p_rec->normal_min;
+ rec.max_reading = p_rec->max_reading;
+ rec.min_reading = p_rec->min_reading;
+ rec.unr_thresh = p_rec->unr_thresh;
+ rec.uc_thresh = p_rec->uc_thresh;
+ rec.unc_thresh = p_rec->unc_thresh;
+ rec.lnr_thresh = p_rec->lnr_thresh;
+ rec.lc_thresh = p_rec->lc_thresh;
+ rec.lnc_thresh = p_rec->lnc_thresh;
+ rec.pos_hyst = p_rec->pos_hyst;
+ rec.neg_hyst = p_rec->neg_hyst;
+ rec.oem = p_rec->oem;
+ rec.str_type_len = p_rec->str_type_len;
+ memcpy(rec.str, p_rec->str, SENSOR_STR_SIZE);
+
+ // Copy this record to generic SDR record
+ memcpy(sdr.rec, &rec, SDR_LEN_MAX);
+
+ // Add this record to SDR repo
+ if (sdr_add_entry(&sdr, &rec_id)) {
+ syslog(LOG_ALERT, "sdr_add_thresh_rec: sdr_add_entry failed\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+sdr_add_oem_rec(sensor_oem_t *p_rec) {
+ int rec_id = 0;
+ sdr_rec_t sdr = { 0 };
+ sdr_oem_t rec = { 0 };
+
+ // Populate SDR OEM record
+ rec.ver = SDR_VERSION;
+ rec.type = SDR_OEM_TYPE;
+ rec.len = SDR_OEM_LEN;
+
+ memcpy(rec.mfr_id, p_rec->mfr_id, 3);
+ memcpy(rec.oem_data, p_rec->oem_data, SENSOR_OEM_DATA_SIZE);
+
+ // Copy this record to generic SDR record
+ memcpy(sdr.rec, &rec, SDR_LEN_MAX);
+
+ // Add this record to SDR repo
+ if (sdr_add_entry(&sdr, &rec_id)) {
+ syslog(LOG_ALERT, "sdr_add_oem_rec: sdr_add_entry failed\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+// Platform specific SEL API entry points
+// Retrieve time stamp for recent add operation
+void
+sdr_ts_recent_add(time_stamp_t *ts) {
+ memcpy(ts->ts, g_sdr_hdr.ts_add.ts, 0x04);
+}
+
+// Retrieve time stamp for recent erase operation
+void
+sdr_ts_recent_erase(time_stamp_t *ts) {
+ memcpy(ts->ts, g_sdr_hdr.ts_erase.ts, 0x04);
+}
+
+// Retrieve total number of entries in SDR repo
+int
+sdr_num_entries(void) {
+ return (g_sdr_hdr.end - g_sdr_hdr.begin);
+}
+
+// Retrieve total free space available in SDR repo
+int
+sdr_free_space(void) {
+ int total_space;
+ int used_space;
+
+ total_space = SDR_RECORDS_MAX * sizeof(sdr_rec_t);
+ used_space = sdr_num_entries() * sizeof(sdr_rec_t);
+
+ return (total_space - used_space);
+}
+
+// Reserve an ID that will be used in later operations
+// IPMI/Section 33.11
+int
+sdr_rsv_id() {
+ // Increment the current reservation ID and return
+ if (g_rsv_id++ == SDR_RSVID_MAX) {
+ g_rsv_id = SDR_RSVID_MIN;
+ }
+
+ return g_rsv_id;
+}
+
+// Get the SDR entry for a given record ID
+// IPMI/Section 33.12
+int
+sdr_get_entry(int rsv_id, int read_rec_id, sdr_rec_t *rec,
+ int *next_rec_id) {
+
+ int index;
+
+ // Make sure the rsv_id matches
+ if (rsv_id != g_rsv_id) {
+ syslog(LOG_ALERT, "sdr_get_entry: Reservation ID mismatch\n");
+ return -1;
+ }
+
+ // Find the index in to array based on given index
+ if (read_rec_id == SDR_RECID_FIRST) {
+ index = g_sdr_hdr.begin;
+ } else if (read_rec_id == SDR_RECID_LAST) {
+ index = g_sdr_hdr.end - 1;
+ } else {
+ index = read_rec_id - 1;
+ }
+
+ // If the SDR repo is empty return error
+ if (sdr_num_entries() == 0) {
+ syslog(LOG_ALERT, "sdr_get_entry: No entries\n");
+ return -1;
+ }
+
+ // Check for boundary conditions
+ if ((index < SDR_INDEX_MIN) || (index > SDR_INDEX_MAX)) {
+ syslog(LOG_ALERT, "sdr_get_entry: Invalid Record ID %d\n", read_rec_id);
+ return -1;
+ }
+
+ // Check to make sure the given id is valid
+ if (index < g_sdr_hdr.begin || index >= g_sdr_hdr.end) {
+ syslog(LOG_ALERT, "sdr_get_entry: Wrong Record ID %d\n", read_rec_id);
+ return -1;
+ }
+
+ memcpy(rec->rec, g_sdr_data[index].rec, sizeof(sdr_rec_t));
+
+ // Return the next record ID in the log
+ *next_rec_id = ++read_rec_id;
+
+ // If this is the last entry in the log, return 0xFFFF
+ if (*next_rec_id == g_sdr_hdr.end) {
+ *next_rec_id = SDR_RECID_LAST;
+ }
+
+ return 0;
+}
+
+
+// Initialize SDR Repo structure
+int
+sdr_init(void) {
+ int num;
+ int i;
+ sensor_mgmt_t *p_mgmt;
+ sensor_thresh_t *p_thresh;
+ sensor_disc_t *p_disc;
+ sensor_oem_t *p_oem;
+
+ // Populate SDR Header
+ g_sdr_hdr.magic = SDR_HDR_MAGIC;
+ g_sdr_hdr.version = SDR_HDR_VERSION;
+ g_sdr_hdr.begin = SDR_INDEX_MIN;
+ g_sdr_hdr.end = SDR_INDEX_MIN;
+ memset(g_sdr_hdr.ts_add.ts, 0x0, 4);
+ memset(g_sdr_hdr.ts_erase.ts, 0x0, 4);
+
+ // Populate all mgmt control sensors
+ plat_sensor_mgmt_info(&num, &p_mgmt);
+ for (i = 0; i < num; i++) {
+ sdr_add_mgmt_rec(&p_mgmt[i]);
+ }
+
+ // Populate all discrete sensors
+ plat_sensor_disc_info(&num, &p_disc);
+ for (i = 0; i < num; i++) {
+ sdr_add_disc_rec(&p_disc[i]);
+ }
+
+ // Populate all threshold sensors
+ plat_sensor_thresh_info(&num, &p_thresh);
+ for (i = 0; i < num; i++) {
+ sdr_add_thresh_rec(&p_thresh[i]);
+ }
+
+ // Populate all OEM sensors
+ plat_sensor_oem_info(&num, &p_oem);
+ for (i = 0; i < num; i++) {
+ sdr_add_oem_rec(&p_oem[i]);
+ }
+
+ return 0;
+}
diff --git a/common/recipes-core/ipmid/files/sdr.h b/common/recipes-core/ipmid/files/sdr.h
new file mode 100644
index 0000000..5c11c31
--- /dev/null
+++ b/common/recipes-core/ipmid/files/sdr.h
@@ -0,0 +1,72 @@
+/*
+ *
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ *
+ * 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.
+ */
+
+#ifndef __SDR_H__
+#define __SDR_H__
+
+#include "timestamp.h"
+
+typedef struct {
+ unsigned char rec[64];
+} sdr_rec_t;
+
+// Mgmt. Controller SDR record; IPMI/ Section 43.9
+typedef struct {
+ // Sensor Record Header
+ unsigned char rec_id[2];
+ unsigned char ver;
+ unsigned char type;
+ unsigned char len;
+ // Record Key Bytes
+ unsigned char slave_addr;
+ unsigned char chan_no;
+ // Record Body Bytes
+ unsigned char pwr_state_init;
+ unsigned char dev_caps;
+ unsigned char rsvd[3];
+ unsigned char ent_id;
+ unsigned char ent_inst;
+ unsigned char oem;
+ unsigned char str_type_len;
+ char str[16];
+} sdr_mgmt_t;
+
+// OEM type SDR record; IPMI/Section 43.12
+typedef struct {
+ // Sensor Record Header
+ unsigned char rec_id[2];
+ unsigned char ver;
+ unsigned char type;
+ unsigned char len;
+ // Record Body Bytes
+ unsigned char mfr_id[3];
+ unsigned char oem_data[56];
+} sdr_oem_t;
+
+void sdr_ts_recent_add(time_stamp_t *ts);
+void sdr_ts_recent_erase(time_stamp_t *ts);
+int sdr_num_entries(void);
+int sdr_free_space(void);
+int sdr_rsv_id();
+int sdr_get_entry(int rsv_id, int read_rec_id, sdr_rec_t *rec,
+ int *next_rec_id);
+int sdr_init(void);
+
+#endif /* __SDR_H__ */
diff --git a/common/recipes-core/ipmid/files/sel.c b/common/recipes-core/ipmid/files/sel.c
new file mode 100644
index 0000000..d598bb1
--- /dev/null
+++ b/common/recipes-core/ipmid/files/sel.c
@@ -0,0 +1,440 @@
+/*
+ *
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * This file represents platform specific implementation for storing
+ * SEL logs and acts as back-end for IPMI stack
+ *
+ * TODO: Optimize the file handling to keep file open always instead of
+ * current open/seek/close
+ *
+ *
+ * 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.
+ */
+#include "sel.h"
+#include "timestamp.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <syslog.h>
+#include <string.h>
+
+// SEL File.
+#define SEL_LOG_FILE "/mnt/data/sel.bin"
+
+// SEL Header magic number
+#define SEL_HDR_MAGIC 0xFBFBFBFB
+
+// SEL Header version number
+#define SEL_HDR_VERSION 0x01
+
+// SEL Data offset from file beginning
+#define SEL_DATA_OFFSET 0x100
+
+// SEL reservation IDs can not be 0x00 or 0xFFFF
+#define SEL_RSVID_MIN 0x01
+#define SEL_RSVID_MAX 0xFFFE
+
+// Number of SEL records before wrap
+#define SEL_RECORDS_MAX 128 // TODO: Based on need we can make it bigger
+#define SEL_ELEMS_MAX (SEL_RECORDS_MAX+1)
+
+// Index for circular array
+#define SEL_INDEX_MIN 0x00
+#define SEL_INDEX_MAX SEL_RECORDS_MAX
+
+// Record ID can not be 0x0 (IPMI/Section 31)
+#define SEL_RECID_MIN (SEL_INDEX_MIN+1)
+#define SEL_RECID_MAX (SEL_INDEX_MAX+1)
+
+// Special RecID value for first and last (IPMI/Section 31)
+#define SEL_RECID_FIRST 0x0000
+#define SEL_RECID_LAST 0xFFFF
+
+// SEL header struct to keep track of SEL Log entries
+typedef struct {
+ int magic; // Magic number to check validity
+ int version; // version number of this header
+ int begin; // index to the begining of the log
+ int end; // index to end of the log
+ time_stamp_t ts_add; // last addition time stamp
+ time_stamp_t ts_erase; // last erase time stamp
+} sel_hdr_t;
+
+// Keep track of last Reservation ID
+static int g_rsv_id = 0x01;
+
+// Cached version of SEL Header and data
+static sel_hdr_t g_sel_hdr;
+static sel_msg_t g_sel_data[SEL_ELEMS_MAX];
+
+// Local helper functions to interact with file system
+static int
+file_get_sel_hdr(void) {
+ FILE *fp;
+
+ fp = fopen(SEL_LOG_FILE, "r");
+ if (fp == NULL) {
+ return -1;
+ }
+
+ if (fread(&g_sel_hdr, sizeof(sel_hdr_t), 1, fp) <= 0) {
+ syslog(LOG_ALERT, "file_get_sel_hdr: fread\n");
+ fclose (fp);
+ return -1;
+ }
+
+ fclose(fp);
+ return 0;
+}
+
+static int
+file_get_sel_data(void) {
+ FILE *fp;
+ int i, j;
+
+ fp = fopen(SEL_LOG_FILE, "r");
+ if (fp == NULL) {
+ syslog(LOG_ALERT, "file_get_sel_data: fopen\n");
+ return -1;
+ }
+
+ if (fseek(fp, SEL_DATA_OFFSET, SEEK_SET)) {
+ syslog(LOG_ALERT, "file_get_sel_data: fseek\n");
+ fclose(fp);
+ return -1;
+ }
+
+ unsigned char buf[SEL_ELEMS_MAX * 16];
+ if (fread(buf, 1, SEL_ELEMS_MAX * sizeof(sel_msg_t), fp) <= 0) {
+ syslog(LOG_ALERT, "file_get_sel_data: fread\n");
+ fclose(fp);
+ return -1;
+ }
+
+ fclose(fp);
+
+ for (i = 0; i < SEL_ELEMS_MAX; i++) {
+ for (j = 0; j < sizeof(sel_msg_t);j++) {
+ g_sel_data[i].msg[j] = buf[i*16 + j];
+ }
+ }
+
+ return 0;
+}
+
+static int
+file_store_sel_hdr(void) {
+ FILE *fp;
+
+ fp = fopen(SEL_LOG_FILE, "r+");
+ if (fp == NULL) {
+ syslog(LOG_ALERT, "file_store_sel_hdr: fopen\n");
+ return -1;
+ }
+
+ if (fwrite(&g_sel_hdr, sizeof(sel_hdr_t), 1, fp) <= 0) {
+ syslog(LOG_ALERT, "file_store_sel_hdr: fwrite\n");
+ fclose(fp);
+ return -1;
+ }
+
+ fclose(fp);
+
+ return 0;
+}
+
+static int
+file_store_sel_data(int recId, sel_msg_t *data) {
+ FILE *fp;
+ int index;
+
+ fp = fopen(SEL_LOG_FILE, "r+");
+ if (fp == NULL) {
+ syslog(LOG_ALERT, "file_store_sel_data: fopen\n");
+ return -1;
+ }
+
+ // Records are stored using zero-based index
+ index = (recId-1) * sizeof(sel_msg_t);
+
+ if (fseek(fp, SEL_DATA_OFFSET+index, SEEK_SET)) {
+ syslog(LOG_ALERT, "file_store_sel_data: fseek\n");
+ fclose(fp);
+ return -1;
+ }
+
+ if (fwrite(data->msg, sizeof(sel_msg_t), 1, fp) <= 0) {
+ syslog(LOG_ALERT, "file_store_sel_data: fwrite\n");
+ fclose(fp);
+ return -1;
+ }
+
+ fclose(fp);
+
+ return 0;
+}
+
+// Platform specific SEL API entry points
+// Retrieve time stamp for recent add operation
+void
+sel_ts_recent_add(time_stamp_t *ts) {
+ memcpy(ts->ts, g_sel_hdr.ts_add.ts, 0x04);
+}
+
+// Retrieve time stamp for recent erase operation
+void
+sel_ts_recent_erase(time_stamp_t *ts) {
+ memcpy(ts->ts, g_sel_hdr.ts_erase.ts, 0x04);
+}
+
+// Retrieve total number of entries in SEL log
+int
+sel_num_entries(void) {
+ if (g_sel_hdr.begin <= g_sel_hdr.end) {
+ return (g_sel_hdr.end - g_sel_hdr.begin);
+ } else {
+ return (g_sel_hdr.end + (SEL_INDEX_MAX - g_sel_hdr.begin + 1));
+ }
+}
+
+// Retrieve total free space available in SEL log
+int
+sel_free_space(void) {
+ int total_space;
+ int used_space;
+
+ total_space = SEL_RECORDS_MAX * sizeof(sel_msg_t);
+ used_space = sel_num_entries() * sizeof(sel_msg_t);
+
+ return (total_space - used_space);
+}
+
+// Reserve an ID that will be used in later operations
+// IPMI/Section 31.4
+int
+sel_rsv_id() {
+ // Increment the current reservation ID and return
+ if (g_rsv_id++ == SEL_RSVID_MAX) {
+ g_rsv_id = SEL_RSVID_MIN;
+ }
+
+ return g_rsv_id;
+}
+
+// Get the SEL entry for a given record ID
+// IPMI/Section 31.5
+int
+sel_get_entry(int read_rec_id, sel_msg_t *msg, int *next_rec_id) {
+
+ int index;
+
+ // Find the index in to array based on given index
+ if (read_rec_id == SEL_RECID_FIRST) {
+ index = g_sel_hdr.begin;
+ } else if (read_rec_id == SEL_RECID_LAST) {
+ if (g_sel_hdr.end) {
+ index = g_sel_hdr.end - 1;
+ } else {
+ index = SEL_INDEX_MAX;
+ }
+ } else {
+ index = read_rec_id - 1;
+ }
+
+ // If the log is empty return error
+ if (sel_num_entries() == 0) {
+ syslog(LOG_ALERT, "sel_get_entry: No entries\n");
+ return -1;
+ }
+
+ // Check for boundary conditions
+ if ((index < SEL_INDEX_MIN) || (index > SEL_INDEX_MAX)) {
+ syslog(LOG_ALERT, "sel_get_entry: Invalid Record ID %d\n", read_rec_id);
+ return -1;
+ }
+
+ // If begin < end, check to make sure the given id falls between
+ if (g_sel_hdr.begin < g_sel_hdr.end) {
+ if (index < g_sel_hdr.begin || index >= g_sel_hdr.end) {
+ syslog(LOG_ALERT, "sel_get_entry: Wrong Record ID %d\n", read_rec_id);
+ return -1;
+ }
+ }
+
+ // If end < begin, check to make sure the given id is valid
+ if (g_sel_hdr.begin > g_sel_hdr.end) {
+ if (index >= g_sel_hdr.end && index < g_sel_hdr.begin) {
+ syslog(LOG_ALERT, "sel_get_entry: Wrong Record ID2 %d\n", read_rec_id);
+ return -1;
+ }
+ }
+
+ memcpy(msg->msg, g_sel_data[index].msg, sizeof(sel_msg_t));
+
+ // Return the next record ID in the log
+ *next_rec_id = read_rec_id++;
+ if (*next_rec_id > SEL_INDEX_MAX) {
+ *next_rec_id = SEL_INDEX_MIN;
+ }
+
+ // If this is the last entry in the log, return 0xFFFF
+ if (*next_rec_id == g_sel_hdr.end) {
+ *next_rec_id = SEL_RECID_LAST;
+ }
+
+ return 0;
+}
+
+// Add a new entry in to SEL log
+// IPMI/Section 31.6
+int
+sel_add_entry(sel_msg_t *msg, int *rec_id) {
+ // If the SEL if full, roll over. To keep track of empty condition, use
+ // one empty location less than the max records.
+ if (sel_num_entries() == SEL_RECORDS_MAX) {
+ syslog(LOG_ALERT, "sel_add_entry: SEL rollover\n");
+ if (++g_sel_hdr.begin > SEL_INDEX_MAX) {
+ g_sel_hdr.begin = SEL_INDEX_MIN;
+ }
+ }
+
+ // Update message's time stamp starting at byte 4
+ time_stamp_fill(&msg->msg[3]);
+
+ // Add the enry at end
+ memcpy(g_sel_data[g_sel_hdr.end].msg, msg->msg, sizeof(sel_msg_t));
+
+ // Return the newly added record ID
+ *rec_id = g_sel_hdr.end+1;
+
+ if (file_store_sel_data(*rec_id, msg)) {
+ syslog(LOG_ALERT, "sel_add_entry: file_store_sel_data\n");
+ return -1;
+ }
+
+ // Increment the end pointer
+ if (++g_sel_hdr.end > SEL_INDEX_MAX) {
+ g_sel_hdr.end = SEL_INDEX_MIN;
+ }
+
+ // Update timestamp for add in header
+ time_stamp_fill(g_sel_hdr.ts_add.ts);
+
+ // Store the structure persistently
+ if (file_store_sel_hdr()) {
+ syslog(LOG_ALERT, "sel_add_entry: file_store_sel_hdr\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+// Erase the SEL completely
+// IPMI/Section 31.9
+// Note: To reduce wear/tear, instead of erasing, manipulating the metadata
+int
+sel_erase(int rsv_id) {
+ if (rsv_id != g_rsv_id) {
+ return -1;
+ }
+
+ // Erase SEL Logs
+ g_sel_hdr.begin = SEL_INDEX_MIN;
+ g_sel_hdr.end = SEL_INDEX_MIN;
+
+ // Update timestamp for erase in header
+ time_stamp_fill(g_sel_hdr.ts_erase.ts);
+
+ // Store the structure persistently
+ if (file_store_sel_hdr()) {
+ syslog(LOG_ALERT, "sel_erase: file_store_sel_hdr\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+// To get the erase status while erase happens
+// IPMI/Section 31.2
+// Note: Since we are not doing offline erasing, need not return in-progress state
+int
+sel_erase_status(int rsv_id, sel_erase_stat_t *status) {
+ if (rsv_id != g_rsv_id) {
+ return -1;
+ }
+
+ // Since we do not do any offline erasing, always return erase done
+ *status = SEL_ERASE_DONE;
+
+ return 0;
+}
+
+// Initialize SEL log file
+int
+sel_init(void) {
+ FILE *fp;
+ int i;
+
+ // Check if the file exists or not
+ if (access(SEL_LOG_FILE, F_OK) == 0) {
+ // Since file is present, fetch all the contents to cache
+ if (file_get_sel_hdr()) {
+ syslog(LOG_ALERT, "init_sel: file_get_sel_hdr\n");
+ return -1;
+ }
+
+ if (file_get_sel_data()) {
+ syslog(LOG_ALERT, "init_sel: file_get_sel_data\n");
+ return -1;
+ }
+
+ return 0;
+ }
+
+ // File not present, so create the file
+ fp = fopen(SEL_LOG_FILE, "w+");
+ if (fp == NULL) {
+ syslog(LOG_ALERT, "init_sel: fopen\n");
+ return -1;
+ }
+
+ fclose (fp);
+
+ // Populate SEL Header in to the file
+ g_sel_hdr.magic = SEL_HDR_MAGIC;
+ g_sel_hdr.version = SEL_HDR_VERSION;
+ g_sel_hdr.begin = SEL_INDEX_MIN;
+ g_sel_hdr.end = SEL_INDEX_MIN;
+ memset(g_sel_hdr.ts_add.ts, 0x0, 4);
+ memset(g_sel_hdr.ts_erase.ts, 0x0, 4);
+
+ if (file_store_sel_hdr()) {
+ syslog(LOG_ALERT, "init_sel: file_store_sel_hdr\n");
+ return -1;
+ }
+
+ // Populate SEL Data in to the file
+ for (i = 1; i <= SEL_RECORDS_MAX; i++) {
+ sel_msg_t msg = {0};
+ if (file_store_sel_data(i, &msg)) {
+ syslog(LOG_ALERT, "init_sel: file_store_sel_data\n");
+ return -1;
+ }
+ }
+
+ return 0;
+}
diff --git a/common/recipes-core/ipmid/files/sel.h b/common/recipes-core/ipmid/files/sel.h
new file mode 100644
index 0000000..3bb9a2f
--- /dev/null
+++ b/common/recipes-core/ipmid/files/sel.h
@@ -0,0 +1,51 @@
+/*
+ *
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ *
+ * 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.
+ */
+
+#ifndef __SEL_H__
+#define __SEL_H__
+
+#include "timestamp.h"
+
+enum {
+ IPMI_SEL_INIT_ERASE = 0xAA,
+ IPMI_SEL_ERASE_STAT = 0x00,
+};
+
+typedef enum {
+ SEL_ERASE_IN_PROG = 0x00,
+ SEL_ERASE_DONE = 0x01,
+} sel_erase_stat_t;
+
+typedef struct {
+ unsigned char msg[16];
+} sel_msg_t;
+
+void sel_ts_recent_add(time_stamp_t *ts);
+void sel_ts_recent_erase(time_stamp_t *ts);
+int sel_num_entries(void);
+int sel_free_space(void);
+int sel_rsv_id();
+int sel_get_entry(int read_rec_id, sel_msg_t *msg, int *next_rec_id);
+int sel_add_entry(sel_msg_t *msg, int *rec_id);
+int sel_erase(int rsv_id);
+int sel_erase_status(int rsv_id, sel_erase_stat_t *status);
+int sel_init(void);
+
+#endif /* __SEL_H__ */
diff --git a/common/recipes-core/ipmid/files/sensor.h b/common/recipes-core/ipmid/files/sensor.h
new file mode 100644
index 0000000..5d8c11a
--- /dev/null
+++ b/common/recipes-core/ipmid/files/sensor.h
@@ -0,0 +1,117 @@
+/*
+ *
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ *
+ * 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.
+ */
+
+#ifndef __SENSOR_H__
+#define __SENSOR_H__
+
+#include "timestamp.h"
+
+#define IANA_ID_SIZE 3
+#define SENSOR_STR_SIZE 16
+#define SENSOR_OEM_DATA_SIZE 56
+
+// Threshold Sensor Descriptor
+typedef struct {
+ unsigned char owner;
+ unsigned char lun;
+ unsigned char sensor_num;
+ unsigned char ent_id;
+ unsigned char ent_inst;
+ unsigned char sensor_init;
+ unsigned char sensor_caps;
+ unsigned char sensor_type;
+ unsigned char evt_read_type;
+ unsigned char lt_read_mask[2];
+ unsigned char ut_read_mask[2];
+ unsigned char set_thresh_mask[2];
+ unsigned char sensor_units1;
+ unsigned char sensor_units2;
+ unsigned char sensor_units3;
+ unsigned char linear;
+ unsigned char m_val;
+ unsigned char m_tolerance;
+ unsigned char b_val;
+ unsigned char b_accuracy;
+ unsigned char accuracy_dir;
+ unsigned char rb_exp;
+ unsigned char analog_flags;
+ unsigned char nominal;
+ unsigned char normal_max;
+ unsigned char normal_min;
+ unsigned char max_reading;
+ unsigned char min_reading;
+ unsigned char unr_thresh;
+ unsigned char uc_thresh;
+ unsigned char unc_thresh;
+ unsigned char lnr_thresh;
+ unsigned char lc_thresh;
+ unsigned char lnc_thresh;
+ unsigned char pos_hyst;
+ unsigned char neg_hyst;
+ unsigned char oem;
+ unsigned char str_type_len;
+ char str[SENSOR_STR_SIZE];
+} sensor_thresh_t;
+
+// Discrete Sensor Descriptor
+typedef struct {
+ unsigned char owner;
+ unsigned char lun;
+ unsigned char sensor_num;
+ unsigned char ent_id;
+ unsigned char ent_inst;
+ unsigned char sensor_init;
+ unsigned char sensor_caps;
+ unsigned char sensor_type;
+ unsigned char evt_read_type;
+ unsigned char assert_evt_mask[2];
+ unsigned char deassert_evt_mask[2];
+ unsigned char read_evt_mask[2];
+ unsigned char oem;
+ unsigned char str_type_len;
+ char str[SENSOR_STR_SIZE];
+} sensor_disc_t;
+
+// Mgmt. Controller Sensor Descriptor
+typedef struct {
+ unsigned char slave_addr;
+ unsigned char chan_no;
+ unsigned char pwr_state_init;
+ unsigned char dev_caps;
+ unsigned char ent_id;
+ unsigned char ent_inst;
+ unsigned char oem;
+ unsigned char str_type_len;
+ char str[SENSOR_STR_SIZE];
+} sensor_mgmt_t;
+
+// OEM type Sensor Descriptor
+typedef struct {
+ unsigned char mfr_id[IANA_ID_SIZE];
+ unsigned char oem_data[SENSOR_OEM_DATA_SIZE];
+} sensor_oem_t;
+
+void plat_sensor_mgmt_info(int *num, sensor_mgmt_t **p_sensor);
+void plat_sensor_disc_info(int *num, sensor_disc_t **p_sensor);
+void plat_sensor_thresh_info(int *num, sensor_thresh_t **p_sensor);
+void plat_sensor_oem_info(int *num, sensor_oem_t **p_sensor);
+int plat_sensor_init(void);
+
+#endif /* __SENSOR_H__ */
diff --git a/common/recipes-core/ipmid/files/timestamp.c b/common/recipes-core/ipmid/files/timestamp.c
new file mode 100644
index 0000000..11ac03e
--- /dev/null
+++ b/common/recipes-core/ipmid/files/timestamp.c
@@ -0,0 +1,46 @@
+/*
+ *
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * This file is a helper file to fill timestamps from platform
+ * used by SEL Logs, SDR records etc.
+ *
+ * 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.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <syslog.h>
+#include <string.h>
+#include <sys/time.h>
+#include <time.h>
+
+// Local helper function to fill time stamp
+void
+time_stamp_fill(unsigned char *ts) {
+ unsigned int time;
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+
+ time = tv.tv_sec;
+ ts[0] = time & 0xFF;
+ ts[1] = (time >> 8) & 0xFF;
+ ts[2] = (time >> 16) & 0xFF;
+ ts[3] = (time >> 24) & 0xFF;
+
+ return;
+}
diff --git a/common/recipes-core/ipmid/files/timestamp.h b/common/recipes-core/ipmid/files/timestamp.h
new file mode 100644
index 0000000..430dd23
--- /dev/null
+++ b/common/recipes-core/ipmid/files/timestamp.h
@@ -0,0 +1,30 @@
+/*
+ *
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ *
+ * 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.
+ */
+
+#ifndef __TIMESTAMP_H__
+#define __TIMESTAMP_H__
+
+typedef struct {
+ unsigned char ts[4];
+} time_stamp_t;
+
+void time_stamp_fill(unsigned char *ts);
+
+#endif /* __TIMESTAMP_H__ */
diff --git a/common/recipes-core/ipmid/ipmid_0.2.bb b/common/recipes-core/ipmid/ipmid_0.2.bb
new file mode 100644
index 0000000..14c8c7f
--- /dev/null
+++ b/common/recipes-core/ipmid/ipmid_0.2.bb
@@ -0,0 +1,42 @@
+# 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
+
+SUMMARY = "IPMI Daemon"
+DESCRIPTION = "Daemon to handle IPMI Messages."
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://ipmid.c;beginline=8;endline=20;md5=da35978751a9d71b73679307c4d296ec"
+
+
+SRC_URI = "file://Makefile \
+ file://ipmid.c \
+ file://timestamp.c \
+ file://timestamp.h \
+ file://sel.c \
+ file://sel.h \
+ file://sdr.c \
+ file://sdr.h \
+ file://sensor.h \
+ file://fruid.h \
+ "
+
+DEPENDS += " libpal "
+
+binfiles = "ipmid"
+
+pkgdir = "ipmid"
diff --git a/common/recipes-core/power-util/files/Makefile b/common/recipes-core/power-util/files/Makefile
new file mode 100644
index 0000000..97ee9d5
--- /dev/null
+++ b/common/recipes-core/power-util/files/Makefile
@@ -0,0 +1,11 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+all: power-util
+
+
+power-util: power-util.o
+ $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o power-util
diff --git a/common/recipes-core/power-util/files/power-util.c b/common/recipes-core/power-util/files/power-util.c
new file mode 100644
index 0000000..0fda9d6
--- /dev/null
+++ b/common/recipes-core/power-util/files/power-util.c
@@ -0,0 +1,295 @@
+/*
+ * power-util
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <stdint.h>
+#include <string.h>
+#include <getopt.h>
+#include <stdbool.h>
+#include <fcntl.h>
+#include <openbmc/pal.h>
+
+#define POWER_ON_STR "on"
+#define POWER_OFF_STR "off"
+
+const char *pwr_option_list = "status, graceful-shutdown, off, on, cycle, 12V-off,"
+ "12V-on, 12V-cycle";
+
+enum {
+ PWR_STATUS = 1,
+ PWR_GRACEFUL_SHUTDOWN,
+ PWR_OFF,
+ PWR_ON,
+ PWR_CYCLE,
+ PWR_12V_OFF,
+ PWR_12V_ON,
+ PWR_12V_CYCLE,
+ PWR_SLED_CYCLE
+};
+
+static int
+set_last_pwr_state(uint8_t fru, char * state) {
+
+ int ret;
+ char key[MAX_KEY_LEN] = {0};
+
+ sprintf(key, "pwr_server%d_last_state", (int) fru);
+
+ ret = pal_set_key_value(key, state);
+ if (ret < 0) {
+ syslog(LOG_ALERT, "set_last_pwr_state: pal_set_key_value failed for "
+ "fru %u", fru);
+ }
+ return ret;
+}
+
+static void
+print_usage() {
+ printf("Usage: power-util [ %s ] [ %s ]\nUsage: power-util sled-cycle\n",
+ pal_server_list, pwr_option_list);
+}
+
+static int
+get_power_opt(char *option, uint8_t *opt) {
+
+ if (!strcmp(option, "status")) {
+ *opt = PWR_STATUS;
+ } else if (!strcmp(option, "graceful-shutdown")) {
+ *opt = PWR_GRACEFUL_SHUTDOWN;
+ } else if (!strcmp(option, "off")) {
+ *opt = PWR_OFF;
+ } else if (!strcmp(option, "on")) {
+ *opt = PWR_ON;
+ } else if (!strcmp(option, "cycle")) {
+ *opt = PWR_CYCLE;
+ } else if (!strcmp(option, "12V-off")) {
+ *opt = PWR_12V_OFF;
+ } else if (!strcmp(option, "12V-on")) {
+ *opt = PWR_12V_ON;
+ } else if (!strcmp(option, "12V-cycle")) {
+ *opt = PWR_12V_CYCLE;
+ } else if (!strcmp(option, "sled-cycle")) {
+ *opt = PWR_SLED_CYCLE;
+ } else {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+power_util(uint8_t fru, uint8_t opt) {
+
+ int ret;
+ uint8_t status;
+
+ switch(opt) {
+ case PWR_STATUS:
+ ret = pal_get_server_power(fru, &status);
+ if (ret < 0) {
+ syslog(LOG_ALERT, "power_util: pal_get_server_power failed for fru %u\n", fru);
+ return ret;
+ }
+ printf("Power status for fru %u : %s\n", fru, status?"ON":"OFF");
+ break;
+
+ case PWR_GRACEFUL_SHUTDOWN:
+
+ printf("Shutting down fru %u gracefully...\n", fru);
+
+ ret = pal_set_server_power(fru, SERVER_GRACEFUL_SHUTDOWN);
+ if (ret < 0) {
+ syslog(LOG_ALERT, "power_util: pal_set_server_power failed for"
+ " fru %u", fru);
+ return ret;
+ } else if (ret == 1) {
+ printf("fru %u is already powered OFF...\n", fru);
+ return 0;
+ }
+
+ ret = set_last_pwr_state(fru, POWER_OFF_STR);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = pal_set_led(fru, LED_STATE_OFF);
+ if (ret < 0) {
+ syslog(LOG_ALERT, "power_util: pal_set_led failed for fru %u", fru);
+ return ret;
+ }
+ break;
+
+ case PWR_OFF:
+
+ printf("Powering fru %u to OFF state...\n", fru);
+
+ ret = pal_set_server_power(fru, SERVER_POWER_OFF);
+ if (ret < 0) {
+ syslog(LOG_ALERT, "power_util: pal_set_server_power failed for"
+ " fru %u", fru);
+ return ret;
+ } else if (ret == 1) {
+ printf("fru %u is already powered OFF...\n", fru);
+ return 0;
+ }
+
+ ret = set_last_pwr_state(fru, POWER_OFF_STR);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = pal_set_led(fru, LED_STATE_OFF);
+ if (ret < 0) {
+ syslog(LOG_ALERT, "power_util: pal_set_led failed for fru %u", fru);
+ return ret;
+ }
+ break;
+
+ case PWR_ON:
+
+ printf("Powering fru %u to ON state...\n", fru);
+
+ ret = pal_set_server_power(fru, SERVER_POWER_ON);
+ if (ret < 0) {
+ syslog(LOG_ALERT, "power_util: pal_set_server_power failed for"
+ " fru %u", fru);
+ return ret;
+ } else if (ret == 1) {
+ printf("fru %u is already powered ON...\n", fru);
+ return 0;
+ }
+
+ ret = set_last_pwr_state(fru, POWER_ON_STR);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = pal_set_led(fru, LED_STATE_ON);
+ if (ret < 0) {
+ syslog(LOG_ALERT, "power_util: pal_set_led failed for fru %u", fru);
+ return ret;
+ }
+ break;
+
+ case PWR_CYCLE:
+
+ printf("Power cycling fru %u...\n", fru);
+
+ ret = pal_set_server_power(fru, SERVER_POWER_CYCLE);
+ if (ret < 0) {
+ syslog(LOG_ALERT, "power_util: pal_set_server_power failed for"
+ " fru %u", fru);
+ return ret;
+ }
+
+ ret = set_last_pwr_state(fru, POWER_ON_STR);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = pal_set_led(fru, LED_STATE_ON);
+ if (ret < 0) {
+ syslog(LOG_ALERT, "power_util: pal_set_led failed for fru %u", fru);
+ return ret;
+ }
+ break;
+
+ case PWR_12V_OFF:
+ ret = 0; // TODO: Need to add the API to support this power state setting
+ break;
+
+ case PWR_12V_ON:
+ ret = 0; // TODO: Need to add the API to support this power state setting
+ break;
+
+ case PWR_12V_CYCLE:
+ ret = 0; // TODO: Need to add the API to support this power state setting
+ break;
+
+ case PWR_SLED_CYCLE:
+ pal_sled_cycle();
+ break;
+
+ default:
+ syslog(LOG_ALERT, "power_util: wrong option");
+
+ }
+
+ return ret;
+}
+
+int
+main(int argc, char **argv) {
+
+ int ret;
+
+ uint8_t fru, status, opt;
+ char *option;
+
+ /* Check for sled-cycle */
+ if (argc < 2 || argc > 3) {
+ print_usage();
+ exit (-1);
+ }
+
+ option = argc == 2 ? argv[1] : argv [2];
+
+ ret = get_power_opt(option, &opt);
+ /* If argc is 2, the option is sled-cycle */
+ if ((ret < 0) || (argc == 2 && opt != PWR_SLED_CYCLE)) {
+ printf("Wrong option: %s\n", option);
+ print_usage();
+ exit(-1);
+ }
+
+ if (argc > 2) {
+ ret = pal_get_fru_id(argv[1], &fru);
+ if (ret < 0) {
+ printf("Wrong fru: %s\n", argv[1]);
+ print_usage();
+ exit(-1);
+ }
+ } else {
+ fru = -1;
+ }
+
+ if (argc > 2) {
+ ret = pal_is_server_prsnt(fru, &status);
+ if (ret < 0) {
+ printf("pal_is_server_prsnt failed for fru: %d\n", fru);
+ print_usage();
+ exit(-1);
+ }
+ if (status == 0) {
+ printf("%s is empty!\n", argv[1]);
+ print_usage();
+ exit(-1);
+ }
+ }
+
+ ret = power_util(fru, opt);
+ if (ret < 0) {
+ print_usage();
+ return ret;
+ }
+}
diff --git a/common/recipes-core/power-util/power-util_0.1.bb b/common/recipes-core/power-util/power-util_0.1.bb
new file mode 100644
index 0000000..69ef2ad
--- /dev/null
+++ b/common/recipes-core/power-util/power-util_0.1.bb
@@ -0,0 +1,36 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+SUMMARY = "Power Utility"
+DESCRIPTION = "Utility for Power Policy and Management"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://power-util.c;beginline=4;endline=16;md5=b395943ba8a0717a83e62ca123a8d238"
+
+SRC_URI = "file://Makefile \
+ file://power-util.c \
+ "
+S = "${WORKDIR}"
+
+LDFLAGS =+ " -lpal "
+
+DEPENDS =+ " libpal "
+
+binfiles = "power-util"
+
+pkgdir = "power-util"
+
+do_install() {
+ dst="${D}/usr/local/fbpackages/${pkgdir}"
+ bin="${D}/usr/local/bin"
+ install -d $dst
+ install -d $bin
+ install -m 755 power-util ${dst}/power-util
+ ln -snf ../fbpackages/${pkgdir}/power-util ${bin}/power-util
+}
+
+FBPACKAGEDIR = "${prefix}/local/fbpackages"
+
+FILES_${PN} = "${FBPACKAGEDIR}/power-util ${prefix}/local/bin"
+
+INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
+INHIBIT_PACKAGE_STRIP = "1"
diff --git a/common/recipes-core/sensor-mon/files/Makefile b/common/recipes-core/sensor-mon/files/Makefile
new file mode 100644
index 0000000..68a9fe7
--- /dev/null
+++ b/common/recipes-core/sensor-mon/files/Makefile
@@ -0,0 +1,26 @@
+# 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
+
+all: sensord
+
+sensord: sensord.c
+ $(CC) $(CFLAGS) -D _XOPEN_SOURCE -pthread -lm -std=c99 -o $@ $^ $(LDFLAGS)
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o sensord
diff --git a/common/recipes-core/sensor-mon/files/sensord.c b/common/recipes-core/sensor-mon/files/sensord.c
new file mode 100644
index 0000000..1852af3
--- /dev/null
+++ b/common/recipes-core/sensor-mon/files/sensord.c
@@ -0,0 +1,1031 @@
+/*
+ * sensord
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <errno.h>
+#include <syslog.h>
+#include <stdint.h>
+#include <math.h>
+#include <string.h>
+#include <pthread.h>
+#include <sys/file.h>
+#include <facebook/bic.h>
+#include <openbmc/ipmi.h>
+#include <openbmc/sdr.h>
+#ifdef CONFIG_YOSEMITE
+#include <facebook/yosemite_sensor.h>
+#endif /* CONFIG_YOSEMITE */
+
+#define MAX_SENSOR_NUM 0xFF
+#define NORMAL_STATE 0x00
+
+#define SETBIT(x, y) (x | (1 << y))
+#define GETBIT(x, y) ((x & (1 << y)) > y)
+#define CLEARBIT(x, y) (x & (~(1 << y)))
+#define GETMASK(y) (1 << y)
+
+
+
+/* Enum for type of Upper and Lower threshold values */
+enum {
+ UCR_THRESH = 0x01,
+ UNC_THRESH,
+ UNR_THRESH,
+ LCR_THRESH,
+ LNC_THRESH,
+ LNR_THRESH,
+ POS_HYST,
+ NEG_HYST,
+};
+
+/* To hold the sensor info and calculated threshold values from the SDR */
+typedef struct {
+ uint8_t flag;
+ float ucr_thresh;
+ float unc_thresh;
+ float unr_thresh;
+ float lcr_thresh;
+ float lnc_thresh;
+ float lnr_thresh;
+ float pos_hyst;
+ float neg_hyst;
+ int curr_state;
+ char name[23];
+ char units[64];
+
+} thresh_sensor_t;
+
+/* Function pointer to read sensor current value */
+static int (*read_snr_val)(uint8_t, uint8_t, void *);
+
+#ifdef CONFIG_YOSEMITE
+
+// TODO: Change to 6 after adding SPB and NIC
+#define MAX_NUM_FRUS 4
+#define YOSEMITE_SDR_PATH "/tmp/sdr_%s.bin"
+
+static thresh_sensor_t snr_slot1[MAX_SENSOR_NUM] = {0};
+static thresh_sensor_t snr_slot2[MAX_SENSOR_NUM] = {0};
+static thresh_sensor_t snr_slot3[MAX_SENSOR_NUM] = {0};
+static thresh_sensor_t snr_slot4[MAX_SENSOR_NUM] = {0};
+static thresh_sensor_t snr_spb[MAX_SENSOR_NUM] = {0};
+static thresh_sensor_t snr_nic[MAX_SENSOR_NUM] = {0};
+
+static sensor_info_t sinfo_slot1[MAX_SENSOR_NUM] = {0};
+static sensor_info_t sinfo_slot2[MAX_SENSOR_NUM] = {0};
+static sensor_info_t sinfo_slot3[MAX_SENSOR_NUM] = {0};
+static sensor_info_t sinfo_slot4[MAX_SENSOR_NUM] = {0};
+static sensor_info_t sinfo_spb[MAX_SENSOR_NUM] = {0};
+static sensor_info_t sinfo_nic[MAX_SENSOR_NUM] = {0};
+#endif /* CONFIG_YOSEMITE */
+
+
+/*
+ * Returns the pointer to the struct holding all sensor info and
+ * calculated threshold values for the fru#
+ */
+static thresh_sensor_t *
+get_struct_thresh_sensor(uint8_t fru) {
+
+ thresh_sensor_t *snr;
+
+#ifdef CONFIG_YOSEMITE
+ switch (fru) {
+ case FRU_SLOT1:
+ snr = snr_slot1;
+ break;
+ case FRU_SLOT2:
+ snr = snr_slot2;
+ break;
+ case FRU_SLOT3:
+ snr = snr_slot3;
+ break;
+ case FRU_SLOT4:
+ snr = snr_slot4;
+ break;
+ case FRU_SPB:
+ snr = snr_spb;
+ break;
+ case FRU_NIC:
+ snr = snr_nic;
+ break;
+ default:
+ syslog(LOG_ALERT, "get_struct_thresh_sensor: Wrong FRU ID %d\n", fru);
+ return NULL;
+ }
+#endif /* CONFIG_YOSEMITE */
+
+ return snr;
+}
+
+
+/* Returns the all the SDRs for the particular fru# */
+static sensor_info_t *
+get_struct_sensor_info(uint8_t fru) {
+
+ sensor_info_t *sinfo;
+
+#ifdef CONFIG_YOSEMITE
+ switch (fru) {
+ case FRU_SLOT1:
+ sinfo = sinfo_slot1;
+ break;
+ case FRU_SLOT2:
+ sinfo = sinfo_slot2;
+ break;
+ case FRU_SLOT3:
+ sinfo = sinfo_slot3;
+ break;
+ case FRU_SLOT4:
+ sinfo = sinfo_slot4;
+ break;
+ case FRU_SPB:
+ sinfo = sinfo_spb;
+ break;
+ case FRU_NIC:
+ sinfo = sinfo_nic;
+ break;
+ default:
+ syslog(LOG_ALERT, "get_struct_sensor_info: Wrong FRU ID %d\n", fru);
+ return NULL;
+ }
+#endif /* CONFIG_YOSEMITE */
+
+ return sinfo;
+}
+
+
+/* Returns the SDR for a particular sensor of particular fru# */
+static sdr_full_t *
+get_struct_sdr(uint8_t fru, uint8_t snr_num) {
+
+ sdr_full_t *sdr;
+ sensor_info_t *sinfo;
+ sinfo = get_struct_sensor_info(fru);
+ if (sinfo == NULL) {
+ syslog(LOG_ALERT, "get_struct_sdr: get_struct_sensor_info failed\n");
+ return NULL;
+ }
+ sdr = &sinfo[snr_num].sdr;
+ return sdr;
+}
+
+/* Get the threshold values from the SDRs */
+static int
+get_sdr_thresh_val(uint8_t fru, uint8_t snr_num, uint8_t thresh, void *value) {
+
+ int ret;
+ uint8_t x;
+ uint8_t m_lsb, m_msb, m;
+ uint8_t b_lsb, b_msb, b;
+ int8_t b_exp, r_exp;
+ uint8_t thresh_val;
+ sdr_full_t *sdr;
+
+ sdr = get_struct_sdr(fru, snr_num);
+ if (sdr == NULL) {
+ syslog(LOG_ALERT, "get_sdr_thresh_val: get_struct_sdr failed\n");
+ return -1;
+ }
+
+ switch (thresh) {
+ case UCR_THRESH:
+ thresh_val = sdr->uc_thresh;
+ break;
+ case UNC_THRESH:
+ thresh_val = sdr->unc_thresh;
+ break;
+ case UNR_THRESH:
+ thresh_val = sdr->unr_thresh;
+ break;
+ case LCR_THRESH:
+ thresh_val = sdr->lc_thresh;
+ break;
+ case LNC_THRESH:
+ thresh_val = sdr->lnc_thresh;
+ break;
+ case LNR_THRESH:
+ thresh_val = sdr->lnr_thresh;
+ break;
+ case POS_HYST:
+ thresh_val = sdr->pos_hyst;
+ break;
+ case NEG_HYST:
+ thresh_val = sdr->neg_hyst;
+ break;
+ default:
+ syslog(LOG_ERR, "get_sdr_thresh_val: reading unknown threshold val");
+ return -1;
+ }
+
+ // y = (mx + b * 10^b_exp) * 10^r_exp
+ x = thresh_val;
+
+ m_lsb = sdr->m_val;
+ m_msb = sdr->m_tolerance >> 6;
+ m = (m_msb << 8) | m_lsb;
+
+ b_lsb = sdr->b_val;
+ b_msb = sdr->b_accuracy >> 6;
+ b = (b_msb << 8) | b_lsb;
+
+ // exponents are 2's complement 4-bit number
+ b_exp = sdr->rb_exp & 0xF;
+ if (b_exp > 7) {
+ b_exp = (~b_exp + 1) & 0xF;
+ b_exp = -b_exp;
+ }
+ r_exp = (sdr->rb_exp >> 4) & 0xF;
+ if (r_exp > 7) {
+ r_exp = (~r_exp + 1) & 0xF;
+ r_exp = -r_exp;
+ }
+
+ * (float *) value = ((m * x) + (b * pow(10, b_exp))) * (pow(10, r_exp));
+
+ return 0;
+}
+
+/*
+ * Populate all fields of thresh_sensor_t struct for a particular sensor.
+ * Incase the threshold value is 0 mask the check for that threshvold
+ * value in flag field.
+ */
+int
+init_snr_thresh(uint8_t fru, uint8_t snr_num, uint8_t flag) {
+
+ int value;
+ float fvalue;
+ uint8_t op, modifier;
+ thresh_sensor_t *snr;
+
+ sdr_full_t *sdr;
+
+ sdr = get_struct_sdr(fru, snr_num);
+ if (sdr == NULL) {
+ syslog(LOG_ALERT, "init_snr_name: get_struct_sdr failed\n");
+ return -1;
+ }
+
+ snr = get_struct_thresh_sensor(fru);
+ if (snr == NULL) {
+ syslog(LOG_ALERT, "init_snr_thresh: get_struct_thresh_sensor failed");
+ return -1;
+ }
+
+ snr[snr_num].flag = flag;
+ snr[snr_num].curr_state = NORMAL_STATE;
+
+ if (sdr_get_sensor_name(sdr, snr[snr_num].name)) {
+ syslog(LOG_ALERT, "sdr_get_sensor_name: FRU %d: num: 0x%X: reading name"
+ " from SDR failed.", fru, snr_num);
+ return -1;
+ }
+
+ // TODO: Add support for modifier (Mostly modifier is zero)
+ if (sdr_get_sensor_units(sdr, &op, &modifier, snr[snr_num].units)) {
+ syslog(LOG_ALERT, "sdr_get_sensor_units: FRU %d: num 0x%X: reading units"
+ " from SDR failed.", fru, snr_num);
+ return -1;
+ }
+
+ if (get_sdr_thresh_val(fru, snr_num, UCR_THRESH, &fvalue)) {
+ syslog(LOG_ERR,
+ "get_sdr_thresh_val: failed for FRU: %d, num: 0x%X, %-16s, UCR_THRESH",
+ fru, snr_num, snr[snr_num].name);
+ } else {
+ snr[snr_num].ucr_thresh = fvalue;
+ if (!(fvalue)) {
+ snr[snr_num].flag = CLEARBIT(snr[snr_num].flag, UCR_THRESH);
+ syslog(LOG_ALERT,
+ "FRU: %d, num: 0x%X, %-16s, UCR_THRESH check disabled val->%.2f",
+ fru, snr_num, snr[snr_num].name, fvalue);
+ }
+ }
+
+ if (get_sdr_thresh_val(fru, snr_num, UNC_THRESH, &fvalue)) {
+ syslog(LOG_ERR,
+ "get_sdr_thresh_val: failed for FRU: %d, num: 0x%X, %-16s, UNC_THRESH",
+ fru, snr_num, snr[snr_num].name);
+ } else {
+ snr[snr_num].unc_thresh = fvalue;
+ if (!(fvalue)) {
+ snr[snr_num].flag = CLEARBIT(snr[snr_num].flag, UNC_THRESH);
+ syslog(LOG_ALERT,
+ "FRU: %d, num: 0x%X, %-16s, UNC_THRESH check disabled val->%.2f",
+ fru, snr_num, snr[snr_num].name, fvalue);
+ }
+ }
+
+ if (get_sdr_thresh_val(fru, snr_num, UNR_THRESH, &fvalue)) {
+ syslog(LOG_ERR,
+ "get_sdr_thresh_val: failed for FRU: %d, num: 0x%X, %-16s, UNR_THRESH",
+ fru, snr_num, snr[snr_num].name);
+ } else {
+ snr[snr_num].unr_thresh = fvalue;
+ if (!(fvalue)) {
+ snr[snr_num].flag = CLEARBIT(snr[snr_num].flag, UNR_THRESH);
+ syslog(LOG_ALERT,
+ "FRU: %d, num: 0x%X, %-16s, UNR_THRESH check disabled val->%.2f",
+ fru, snr_num, snr[snr_num].name, fvalue);
+ }
+ }
+
+ if (get_sdr_thresh_val(fru, snr_num, LCR_THRESH, &fvalue)) {
+ syslog(LOG_ERR,
+ "get_sdr_thresh_val: failed for FRU: %d, num: 0x%X, %-16s, LCR_THRESH",
+ fru, snr_num, snr[snr_num].name);
+ } else {
+ snr[snr_num].lcr_thresh = fvalue;
+ if (!(fvalue)) {
+ snr[snr_num].flag = CLEARBIT(snr[snr_num].flag, LCR_THRESH);
+ syslog(LOG_ALERT,
+ "FRU: %d, num: 0x%X, %-16s, LCR_THRESH check disabled val->%.2f",
+ fru, snr_num, snr[snr_num].name, fvalue);
+ }
+ }
+
+ if (get_sdr_thresh_val(fru, snr_num, LNC_THRESH, &fvalue)) {
+ syslog(LOG_ERR,
+ "get_sdr_thresh_val: failed for FRU: %d, num: 0x%X, %-16s, LNC_THRESH",
+ fru, snr_num, snr[snr_num].name);
+ } else {
+ snr[snr_num].lnc_thresh = fvalue;
+ if (!(fvalue)) {
+ snr[snr_num].flag = CLEARBIT(snr[snr_num].flag, LNC_THRESH);
+ syslog(LOG_ALERT,
+ "FRU: %d, num: 0x%X, %-16s, LNC_THRESH check disabled val->%.2f",
+ fru, snr_num, snr[snr_num].name, fvalue);
+ }
+ }
+
+ if (get_sdr_thresh_val(fru, snr_num, LNR_THRESH, &fvalue)) {
+ syslog(LOG_ERR,
+ "get_sdr_thresh_val: failed for FRU: %d, num: 0x%X, %-16s, LNR_THRESH",
+ fru, snr_num, snr[snr_num].name);
+ } else {
+ snr[snr_num].lnr_thresh = fvalue;
+ if (!(fvalue)) {
+ snr[snr_num].flag = CLEARBIT(snr[snr_num].flag, LNR_THRESH);
+ syslog(LOG_ALERT,
+ "FRU: %d, num: 0x%X, %-16s, LNR_THRESH check disabled val->%.2f",
+ fru, snr_num, snr[snr_num].name, fvalue);
+ }
+ }
+
+ if (get_sdr_thresh_val(fru, snr_num, POS_HYST, &fvalue)) {
+ syslog(LOG_ERR, "get_sdr_thresh_val: failed for FRU: %d, num: 0x%X, %-16s, POS_HYST",
+ fru, snr_num, snr[snr_num].name);
+ } else
+ snr[snr_num].pos_hyst = fvalue;
+
+ if (get_sdr_thresh_val(fru, snr_num, NEG_HYST, &fvalue)) {
+ syslog(LOG_ERR, "get_sdr_thresh_val: failed for FRU: %d, num: 0x%X, %-16s, NEG_HYST",
+ fru, snr_num, snr[snr_num].name);
+ } else
+ snr[snr_num].neg_hyst = fvalue;
+
+ return 0;
+}
+
+#ifdef CONFIG_YOSEMITE
+/* Initialize all thresh_sensor_t structs for all the Yosemite sensors */
+static void
+init_yosemite_snr_thresh(uint8_t fru) {
+
+ int i;
+
+ switch (fru) {
+ case FRU_SLOT1:
+ case FRU_SLOT2:
+ case FRU_SLOT3:
+ case FRU_SLOT4:
+
+ for (i < 0; i < bic_sensor_cnt; i++) {
+ init_snr_thresh(fru, bic_sensor_list[i], GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
+ }
+ /*
+ init_snr_thresh(fru, BIC_SENSOR_MB_OUTLET_TEMP, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_VCCIN_VR_TEMP, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_VCC_GBE_VR_TEMP, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_1V05PCH_VR_TEMP, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_SOC_TEMP, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_MB_INLET_TEMP, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_PCH_TEMP, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_SOC_THERM_MARGIN, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_VDDR_VR_TEMP, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_VCC_GBE_VR_CURR, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_1V05_PCH_VR_CURR, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_VCCIN_VR_POUT, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_VCCIN_VR_CURR, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_VCCIN_VR_VOL,
+ GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_INA230_POWER, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_SOC_PACKAGE_PWR, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_SOC_TJMAX, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_VDDR_VR_POUT, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_VDDR_VR_CURR, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_VDDR_VR_VOL,
+ GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_VCC_SCSUS_VR_CURR, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_VCC_SCSUS_VR_VOL,
+ GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_VCC_SCSUS_VR_TEMP, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_VCC_SCSUS_VR_POUT, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_VCC_GBE_VR_POUT, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_VCC_GBE_VR_VOL,
+ GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_1V05_PCH_VR_VOL,
+ GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_SOC_DIMMA0_TEMP, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_SOC_DIMMA1_TEMP, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_SOC_DIMMB0_TEMP, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_SOC_DIMMB1_TEMP, GETMASK(UCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_P3V3_MB,
+ GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_P12V_MB,
+ GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_P1V05_PCH,
+ GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_P3V3_STBY_MB,
+ GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_P5V_STBY_MB,
+ GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_PV_BAT,
+ GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_PVDDR,
+ GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
+
+ init_snr_thresh(fru, BIC_SENSOR_PVCC_GBE,
+ GETMASK(UCR_THRESH) | GETMASK(LCR_THRESH));
+ // TODO: Add Support for Discrete sensors
+ // init_snr_thresh(fru, BIC_SENSOR_POST_ERR, //Event-only
+ // init_snr_thresh(fru, BIC_SENSOR_SYSTEM_STATUS, //Discrete
+ // init_snr_thresh(fru, BIC_SENSOR_SPS_FW_HLTH); //Event-only
+ // init_snr_thresh(fru, BIC_SENSOR_POWER_THRESH_EVENT, //Event-only
+ // init_snr_thresh(fru, BIC_SENSOR_MACHINE_CHK_ERR, //Event-only
+ // init_snr_thresh(fru, BIC_SENSOR_PCIE_ERR); //Event-only
+ // init_snr_thresh(fru, BIC_SENSOR_OTHER_IIO_ERR); //Event-only
+ // init_snr_thresh(fru, BIC_SENSOR_PROC_HOT_EXT); //Event-only
+ // init_snr_thresh(fru, BIC_SENSOR_POWER_ERR); //Event-only
+ // init_snr_thresh(fru, , ); //Event-only
+ // init_snr_thresh(fru, BIC_SENSOR_PROC_FAIL); //Discrete
+ // init_snr_thresh(fru, BIC_SENSOR_SYS_BOOT_STAT ); //Discrete
+ // init_snr_thresh(fru, BIC_SENSOR_VR_HOT); //Discrete
+ // init_snr_thresh(fru, BIC_SENSOR_CPU_DIMM_HOT ); //Discrete
+ // init_snr_thresh(fru, BIC_SENSOR_CAT_ERR, //Event-only
+
+ */
+
+ break;
+
+ case FRU_SPB:
+ // TODO: Add support for threshold calculation for SP sensors
+ /*
+ init_snr_thresh(fru, SP_SENSOR_INLET_TEMP, "SP_SENSOR_INLET_TEMP");
+ init_snr_thresh(fru, SP_SENSOR_OUTLET_TEMP, "SP_SENSOR_OUTLET_TEMP");
+ init_snr_thresh(fru, SP_SENSOR_MEZZ_TEMP, "SP_SENSOR_MEZZ_TEMP");
+ init_snr_thresh(fru, SP_SENSOR_FAN0_TACH, "SP_SENSOR_FAN0_TACH");
+ init_snr_thresh(fru, SP_SENSOR_FAN1_TACH, "SP_SENSOR_FAN1_TACH");
+ init_snr_thresh(fru, SP_SENSOR_AIR_FLOW, "SP_SENSOR_AIR_FLOW");
+ init_snr_thresh(fru, SP_SENSOR_P5V, "SP_SENSOR_P5V");
+ init_snr_thresh(fru, SP_SENSOR_P12V, "SP_SENSOR_P12V");
+ init_snr_thresh(fru, SP_SENSOR_P3V3_STBY, "SP_SENSOR_P3V3_STBY");
+ init_snr_thresh(fru, SP_SENSOR_P12V_SLOT0, "SP_SENSOR_P12V_SLOT0");
+ init_snr_thresh(fru, SP_SENSOR_P12V_SLOT1, "SP_SENSOR_P12V_SLOT1");
+ init_snr_thresh(fru, SP_SENSOR_P12V_SLOT2, "SP_SENSOR_P12V_SLOT2");
+ init_snr_thresh(fru, SP_SENSOR_P12V_SLOT3, "SP_SENSOR_P12V_SLOT3");
+ init_snr_thresh(fru, SP_SENSOR_P3V3, "SP_SENSOR_P3V3");
+ init_snr_thresh(fru, SP_SENSOR_HSC_IN_VOLT, "SP_SENSOR_HSC_IN_VOLT");
+ init_snr_thresh(fru, SP_SENSOR_HSC_OUT_CURR, "SP_SENSOR_HSC_OUT_CURR");
+ init_snr_thresh(fru, SP_SENSOR_HSC_TEMP, "SP_SENSOR_HSC_TEMP");
+ init_snr_thresh(fru, SP_SENSOR_HSC_IN_POWER, "SP_SENSOR_HSC_IN_POWER");
+ */
+ break;
+
+ case FRU_NIC:
+ // TODO: Add support for NIC sensor threshold, if any.
+ break;
+
+ default:
+ syslog(LOG_ALERT, "init_yosemite_snr_thresh: wrong FRU ID");
+ exit(-1);
+ }
+}
+#endif /* CONFIG_YOSEMITE */
+
+/* Wrapper function to initialize all the platform sensors */
+static void
+init_all_snr_thresh() {
+ int fru;
+
+ char path[64] = {0};
+ sensor_info_t *sinfo;
+
+
+#ifdef CONFIG_YOSEMITE
+ for (fru = FRU_SLOT1; fru < (FRU_SLOT1 + MAX_NUM_FRUS); fru++) {
+
+ if (get_fru_sdr_path(fru, path) < 0) {
+ syslog(LOG_ALERT, "yosemite_sdr_init: get_fru_sdr_path failed\n");
+ continue;
+ }
+#endif /* CONFIG_YOSEMITE */
+
+ sinfo = get_struct_sensor_info(fru);
+
+ if (sdr_init(path, sinfo) < 0)
+ syslog(LOG_ERR, "init_all_snr_thresh: sdr_init failed for FRU %d", fru);
+ }
+
+#ifdef CONFIG_YOSEMITE
+ for (fru = FRU_SLOT1; fru < (FRU_SLOT1 + MAX_NUM_FRUS); fru++) {
+ init_yosemite_snr_thresh(fru);
+ }
+#endif /* CONFIG_YOSEMITE */
+}
+
+
+
+
+static float
+get_snr_thresh_val(uint8_t fru, uint8_t snr_num, uint8_t thresh) {
+
+ float val;
+ thresh_sensor_t *snr;
+
+ snr = get_struct_thresh_sensor(fru);
+
+ switch (thresh) {
+ case UCR_THRESH:
+ val = snr[snr_num].ucr_thresh;
+ break;
+ case UNC_THRESH:
+ val = snr[snr_num].unc_thresh;
+ break;
+ case UNR_THRESH:
+ val = snr[snr_num].unr_thresh;
+ break;
+ case LCR_THRESH:
+ val = snr[snr_num].lcr_thresh;
+ break;
+ case LNC_THRESH:
+ val = snr[snr_num].lnc_thresh;
+ break;
+ case LNR_THRESH:
+ val = snr[snr_num].lnr_thresh;
+ break;
+ default:
+ syslog(LOG_ALERT, "get_snr_thresh_val: wrong thresh enum value");
+ exit(-1);
+ }
+
+ return val;
+}
+
+/*
+ * Check the curr sensor values against the threshold and
+ * if the curr val has deasserted, log it.
+ */
+static void
+check_thresh_deassert(uint8_t fru, uint8_t snr_num, uint8_t thresh,
+ float curr_val) {
+ uint8_t curr_state = 0;
+ float thresh_val;
+ char thresh_name[100];
+ thresh_sensor_t *snr;
+
+ snr = get_struct_thresh_sensor(fru);
+
+ if (!GETBIT(snr[snr_num].flag, thresh) ||
+ !GETBIT(snr[snr_num].curr_state, thresh))
+ return;
+
+ thresh_val = get_snr_thresh_val(fru, snr_num, thresh);
+
+ switch (thresh) {
+ case UNC_THRESH:
+ if (curr_val <= thresh_val) {
+ curr_state = ~(SETBIT(curr_state, UNR_THRESH) |
+ SETBIT(curr_state, UCR_THRESH) |
+ SETBIT(curr_state, UNC_THRESH));
+ sprintf(thresh_name, "Upper Non Critical");
+ }
+ break;
+
+ case UCR_THRESH:
+ if (curr_val <= thresh_val) {
+ curr_state = ~(SETBIT(curr_state, UCR_THRESH) |
+ SETBIT(curr_state, UNR_THRESH));
+ sprintf(thresh_name, "Upper Critical");
+ }
+ break;
+
+ case UNR_THRESH:
+ if (curr_val <= thresh_val) {
+ curr_state = ~(SETBIT(curr_state, UNR_THRESH));
+ sprintf(thresh_name, "Upper Non Recoverable");
+ }
+ break;
+
+ case LNC_THRESH:
+ if (curr_val >= thresh_val) {
+ curr_state = ~(SETBIT(curr_state, LNR_THRESH) |
+ SETBIT(curr_state, LCR_THRESH) |
+ SETBIT(curr_state, LNC_THRESH));
+ sprintf(thresh_name, "Lower Non Critical");
+ }
+ break;
+
+ case LCR_THRESH:
+ if (curr_val >= thresh_val) {
+ curr_state = ~(SETBIT(curr_state, LCR_THRESH) |
+ SETBIT(curr_state, LNR_THRESH));
+ sprintf(thresh_name, "Lower Critical");
+ }
+ break;
+
+ case LNR_THRESH:
+ if (curr_val >= thresh_val) {
+ curr_state = ~(SETBIT(curr_state, LNR_THRESH));
+ sprintf(thresh_name, "Lower Non Recoverable");
+ }
+ break;
+
+ default:
+ syslog(LOG_ALERT, "get_snr_thresh_val: wrong thresh enum value");
+ exit(-1);
+ }
+
+ if (curr_state) {
+ snr[snr_num].curr_state &= curr_state;
+ syslog(LOG_CRIT, "DEASSERT: %s threshold raised - FRU: %d, num: 0x%X,"
+ " snr: %-16s,",thresh_name, fru, snr_num, snr[snr_num].name);
+ syslog(LOG_CRIT, "curr_val: %.2f %s, thresh_val: %.2f %s cf: %u",
+ curr_val, snr[snr_num].units, thresh_val, snr[snr_num].units, snr[snr_num].curr_state);
+ }
+}
+
+
+/*
+ * Check the curr sensor values against the threshold and
+ * if the curr val has asserted, log it.
+ */
+static void
+check_thresh_assert(uint8_t fru, uint8_t snr_num, uint8_t thresh,
+ float curr_val) {
+ uint8_t curr_state = 0;
+ float thresh_val;
+ char thresh_name[100];
+ thresh_sensor_t *snr;
+
+ snr = get_struct_thresh_sensor(fru);
+
+ if (!GETBIT(snr[snr_num].flag, thresh) ||
+ GETBIT(snr[snr_num].curr_state, thresh))
+ return;
+
+ thresh_val = get_snr_thresh_val(fru, snr_num, thresh);
+
+ switch (thresh) {
+ case UNR_THRESH:
+ if (curr_val >= thresh_val) {
+ curr_state = (SETBIT(curr_state, UNR_THRESH) |
+ SETBIT(curr_state, UCR_THRESH) |
+ SETBIT(curr_state, UNC_THRESH));
+ sprintf(thresh_name, "Upper Non Recoverable");
+ }
+ break;
+
+ case UCR_THRESH:
+ if (curr_val >= thresh_val) {
+ curr_state = (SETBIT(curr_state, UCR_THRESH) |
+ SETBIT(curr_state, UNC_THRESH));
+ sprintf(thresh_name, "Upper Critical");
+ }
+ break;
+
+ case UNC_THRESH:
+ if (curr_val >= thresh_val) {
+ curr_state = (SETBIT(curr_state, UNC_THRESH));
+ sprintf(thresh_name, "Upper Non Critical");
+ }
+ break;
+
+ case LNR_THRESH:
+ if (curr_val <= thresh_val) {
+ curr_state = (SETBIT(curr_state, LNR_THRESH) |
+ SETBIT(curr_state, LCR_THRESH) |
+ SETBIT(curr_state, LNC_THRESH));
+ sprintf(thresh_name, "Lower Non Recoverable");
+ }
+ break;
+
+ case LCR_THRESH:
+ if (curr_val <= thresh_val) {
+ curr_state = (SETBIT(curr_state, LCR_THRESH) |
+ SETBIT(curr_state, LNC_THRESH));
+ sprintf(thresh_name, "Lower Critical");
+ }
+ break;
+
+ case LNC_THRESH:
+ if (curr_val <= thresh_val) {
+ curr_state = (SETBIT(curr_state, LNC_THRESH));
+ sprintf(thresh_name, "Lower Non Critical");
+ }
+ break;
+
+ default:
+ syslog(LOG_ALERT, "get_snr_thresh_val: wrong thresh enum value");
+ exit(-1);
+ }
+
+ if (curr_state) {
+ curr_state &= snr[snr_num].flag;
+ snr[snr_num].curr_state |= curr_state;
+ syslog(LOG_CRIT, "ASSERT: %s threshold raised - FRU: %d, num: 0x%X,"
+ " snr: %-16s,",thresh_name, fru, snr_num, snr[snr_num].name);
+ syslog(LOG_CRIT, "curr_val: %.2f %s, thresh_val: %.2f %s cf: %u",
+ curr_val, snr[snr_num].units, thresh_val, snr[snr_num].units, snr[snr_num].curr_state);
+ }
+}
+
+/*
+ * Starts monitoring all the sensors on a fru for all the threshold values.
+ * Each pthread runs this monitoring for a different fru.
+ */
+static void *
+snr_monitor(void *arg) {
+
+ uint8_t fru = *(uint8_t *) arg;
+ int f, ret, snr_num;
+ float normal_val, curr_val;
+ thresh_sensor_t *snr;
+
+#ifdef TESTING
+ float temp_thresh;
+ int cnt = 0;
+#endif /* TESTING */
+
+ snr = get_struct_thresh_sensor(fru);
+ if (snr == NULL) {
+ syslog(LOG_ALERT, "snr_monitor: get_struct_thresh_sensor failed");
+ exit(-1);
+ }
+
+ while(1) {
+
+#ifdef TESTING
+ cnt++;
+#endif /* TESTING */
+
+ for (snr_num = 0; snr_num < MAX_SENSOR_NUM; snr_num++) {
+ curr_val = 0;
+ if (snr[snr_num].flag) {
+ if (!(ret = read_snr_val(fru, snr_num, &curr_val))) {
+
+
+#ifdef TESTING
+ /*
+ * The curr_val crosses UCR and then return to a state
+ * where UNC < curr_val < UCR and then eventually back to normal.
+ */
+ if (cnt == 5 && snr_num == BIC_SENSOR_MB_INLET_TEMP) {
+ snr[snr_num].flag |= SETBIT(snr[snr_num].flag, UNC_THRESH);
+ temp_thresh = snr[snr_num].ucr_thresh;
+ snr[snr_num].ucr_thresh = 20.0;
+ snr[snr_num].unc_thresh = 10.0;
+ } else if (cnt == 8 && snr_num == BIC_SENSOR_MB_INLET_TEMP) {
+ snr[snr_num].ucr_thresh = temp_thresh;
+ } else if (cnt == 10 && snr_num == BIC_SENSOR_MB_INLET_TEMP) {
+ snr[snr_num].unc_thresh = 50.0;
+ } else if (cnt == 11 && snr_num == BIC_SENSOR_MB_INLET_TEMP) {
+ snr[snr_num].unc_thresh = 0.0;
+ snr[snr_num].flag &= CLEARBIT(snr[snr_num].flag, UNC_THRESH);
+
+ }
+#endif /* TESTING */
+
+#ifdef DEBUG
+ if (cnt == 2) {
+ syslog(LOG_INFO, "pthread %d, cnt: %d, num: 0x%X name: %-16s"
+ " units:%s", fru, cnt, snr_num, snr[snr_num].name,
+ snr[snr_num].units);
+ }
+#endif /* DEBUG */
+
+ check_thresh_assert(fru, snr_num, UNR_THRESH, curr_val);
+ check_thresh_assert(fru, snr_num, UCR_THRESH, curr_val);
+ check_thresh_assert(fru, snr_num, UNC_THRESH, curr_val);
+ check_thresh_assert(fru, snr_num, LNR_THRESH, curr_val);
+ check_thresh_assert(fru, snr_num, LCR_THRESH, curr_val);
+ check_thresh_assert(fru, snr_num, LNC_THRESH, curr_val);
+
+ check_thresh_deassert(fru, snr_num, UNC_THRESH, curr_val);
+ check_thresh_deassert(fru, snr_num, UCR_THRESH, curr_val);
+ check_thresh_deassert(fru, snr_num, UNR_THRESH, curr_val);
+ check_thresh_deassert(fru, snr_num, LNC_THRESH, curr_val);
+ check_thresh_deassert(fru, snr_num, LCR_THRESH, curr_val);
+ check_thresh_deassert(fru, snr_num, LNR_THRESH, curr_val);
+
+ } else {
+ /*
+ * Incase the read_snr_val failed for a sensor,
+ * disable all the threshold checks for that sensor
+ * after logging an approciate syslog message.
+ */
+ if (ret) {
+ syslog(LOG_ERR, "FRU: %d, num: 0x%X, snr:%-16s, read failed",
+ fru, snr_num, snr[snr_num].name);
+ syslog(LOG_ERR, "FRU: %d, num: 0x%X, snr:%-16s, check disabled",
+ fru, snr_num, snr[snr_num].name);
+ snr[snr_num].flag = 0;
+ //}
+ }
+ } /* read_snr_val return check */
+ } /* flag check */
+ } /* loop for all sensors */
+ sleep(5);
+ } /* while loop*/
+} /* function definition */
+
+
+/* Spawns a pthread for each fru to monitor all the sensors on it */
+static void
+run_sensord(int argc, char **argv) {
+ int i, arg;
+
+ pthread_t thread_snr[MAX_NUM_FRUS];
+ int fru[MAX_NUM_FRUS] = {0};
+
+ for (arg = 1; arg < argc; arg ++) {
+#ifdef CONFIG_YOSEMITE
+ if (!(strcmp(argv[arg], "slot1")))
+ fru[FRU_SLOT1 - 1] = FRU_SLOT1;
+ else if (!(strcmp(argv[arg], "slot2")))
+ fru[FRU_SLOT2 - 1] = FRU_SLOT2;
+ else if (!(strcmp(argv[arg], "slot3")))
+ fru[FRU_SLOT3 - 1] = FRU_SLOT3;
+ else if (!(strcmp(argv[arg], "slot4")))
+ fru[FRU_SLOT4 - 1] = FRU_SLOT4;
+ else if (!(strcmp(argv[arg], "spb")))
+ fru[FRU_SPB - 1] = FRU_SPB;
+ else if (!(strcmp(argv[arg], "nic")))
+ fru[FRU_NIC - 1] = FRU_NIC;
+ else {
+ syslog(LOG_ALERT, "Wrong argument: %s", argv[arg]);
+ exit(1);
+ }
+#endif /* CONFIG_YOSEMITE */
+
+ }
+
+ for (i = 0; i < MAX_NUM_FRUS; i++) {
+ if (fru[i]) {
+ if (pthread_create(&thread_snr[i], NULL, snr_monitor,
+ (void*) &fru[i]) < 0) {
+ syslog(LOG_ALERT, "pthread_create for FRU %d failed\n", fru[i]);
+ }
+#ifdef DEBUG
+ else {
+ syslog(LOG_ALERT, "pthread_create for FRU %d succeed\n", fru[i]);
+ }
+#endif /* DEBUG */
+ }
+ sleep(1);
+ }
+
+ for (i = 0; i < MAX_NUM_FRUS; i++) {
+ if (fru[i])
+ pthread_join(thread_snr[i], NULL);
+ }
+}
+
+
+#ifdef DEBUG
+void print_snr_thread(uint8_t fru, thresh_sensor_t *snr)
+{
+ int i;
+ float curr_val;
+
+ for (i = 1; i <= MAX_SENSOR_NUM; i++) {
+ if (snr[i].flag) {
+ curr_val = 0;
+ if(!(read_snr_val(fru, i, &curr_val))) {
+ printf("%-30s:\t%.2f %s\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\n",
+ snr[i].name, curr_val,snr[i].units,
+ snr[i].ucr_thresh,
+ snr[i].unc_thresh,
+ snr[i].lcr_thresh,
+ snr[i].lnr_thresh,
+ snr[i].pos_hyst,
+ snr[i].neg_hyst);
+ } else
+ printf("Reading failed: %-16s\n", snr[i].name);
+ }
+ }
+}
+#endif /* DEBUG */
+
+int
+main(int argc, void **argv) {
+ int dev, rc, pid_file;
+
+ if (argc < 2) {
+ syslog(LOG_ALERT, "Usage: sensord <options>");
+ printf("Usage: sensord <options>\n");
+#ifdef CONFIG_YOSEMITE
+ syslog(LOG_ALERT, "Options: [slot1 | slot2 | slot3 | slot4 | spb | nic]");
+ printf("Options: [slot1 | slot2 | slot3 | slot4 | spb | nic]\n");
+#endif /* CONFIG_YOSEMITE */
+ exit(1);
+ }
+
+ pid_file = open("/var/run/sensord.pid", O_CREAT | O_RDWR, 0666);
+ rc = flock(pid_file, LOCK_EX | LOCK_NB);
+ if(rc) {
+ if(EWOULDBLOCK == errno) {
+ printf("Another sensord instance is running...\n");
+ exit(-1);
+ }
+ } else {
+
+#ifdef CONFIG_YOSEMITE
+ read_snr_val = &yosemite_sensor_read;
+#endif /* CONFIG_YOSEMITE */
+
+ init_all_snr_thresh();
+
+#ifdef DEBUG
+ print_snr_thread(1, snr_slot1);
+ print_snr_thread(2, snr_slot2);
+ print_snr_thread(3, snr_slot3);
+ print_snr_thread(4, snr_slot4);
+#endif /* DEBUG */
+
+ daemon(0,1);
+ openlog("sensord", LOG_CONS, LOG_DAEMON);
+ syslog(LOG_INFO, "sensord: daemon started");
+ run_sensord(argc, (char **) argv);
+ }
+
+ return 0;
+}
diff --git a/common/recipes-core/sensor-mon/sensor-mon_0.1.bb b/common/recipes-core/sensor-mon/sensor-mon_0.1.bb
new file mode 100644
index 0000000..adbd4cb
--- /dev/null
+++ b/common/recipes-core/sensor-mon/sensor-mon_0.1.bb
@@ -0,0 +1,58 @@
+# 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
+
+SUMMARY = "Sensor Monitoring Daemon"
+DESCRIPTION = "Daemon for monitoring the sensors"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://sensord.c;beginline=4;endline=16;md5=b395943ba8a0717a83e62ca123a8d238"
+
+SRC_URI = "file://Makefile \
+ file://sensord.c \
+ "
+
+S = "${WORKDIR}"
+
+binfiles = "sensord \
+ "
+
+CFLAGS += " -lsdr "
+
+DEPENDS += " libsdr "
+
+pkgdir = "sensor-mon"
+
+do_install() {
+ dst="${D}/usr/local/fbpackages/${pkgdir}"
+ bin="${D}/usr/local/bin"
+ install -d $dst
+ install -d $bin
+ for f in ${binfiles}; do
+ install -m 755 $f ${dst}/$f
+ ln -snf ../fbpackages/${pkgdir}/$f ${bin}/$f
+ done
+}
+
+FBPACKAGEDIR = "${prefix}/local/fbpackages"
+
+FILES_${PN} = "${FBPACKAGEDIR}/sensor-mon ${prefix}/local/bin"
+
+# Inhibit complaints about .debug directories for the sensord binary:
+
+INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
+INHIBIT_PACKAGE_STRIP = "1"
diff --git a/common/recipes-core/sensor-util/files/Makefile b/common/recipes-core/sensor-util/files/Makefile
new file mode 100644
index 0000000..2d39a04
--- /dev/null
+++ b/common/recipes-core/sensor-util/files/Makefile
@@ -0,0 +1,11 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+all: sensor-util
+
+
+sensor-util: sensor-util.o
+ $(CC) $(CFLAGS) -lpal -lrt -lm -std=gnu99 -o $@ $^ $(LDFLAGS)
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o sensor-util
diff --git a/common/recipes-core/sensor-util/files/sensor-util.c b/common/recipes-core/sensor-util/files/sensor-util.c
new file mode 100644
index 0000000..eb38d65
--- /dev/null
+++ b/common/recipes-core/sensor-util/files/sensor-util.c
@@ -0,0 +1,173 @@
+/*
+ * yosemite-sensors
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <openbmc/pal.h>
+
+static int
+print_usage() {
+ printf("Usage: sensor-util [ %s ] <sensor num>\n"
+ "sensor num is optional.", pal_fru_list);
+}
+
+static void
+print_single_sensor_reading(uint8_t fru, uint8_t *sensor_list, int sensor_cnt, uint8_t num) {
+
+ int i;
+ float fvalue;
+ char name[24];
+ char units[64];
+ int ret = 0;
+
+ for (i = 0; i < sensor_cnt; i++) {
+
+ if (sensor_list[i] == num) {
+ ret = 1;
+ pal_get_sensor_name(fru, sensor_list[i], name);
+ pal_get_sensor_units(fru, sensor_list[i], units);
+
+ if (pal_sensor_read(fru, sensor_list[i], &fvalue) < 0) {
+
+ printf("pal_sensor_read failed: fru: %d num: 0x%X name: %-23s\n",
+ fru, sensor_list[i], name);
+ } else {
+ printf("%-23s: %.2f %s\n", name, fvalue, units);
+ }
+
+ break;
+ }
+ }
+
+ if (!ret) {
+ printf("Wrong sensor number!\n");
+ print_usage();
+ exit(-1);
+ }
+}
+
+static void
+print_sensor_reading(uint8_t fru, uint8_t *sensor_list, int sensor_cnt) {
+
+ int i;
+ float fvalue;
+ char name[24];
+ char units[64];
+
+ for (i = 0; i < sensor_cnt; i++) {
+
+ /* Clear the variable */
+ sprintf(name, "");
+ sprintf(units, "");
+
+ pal_get_sensor_name(fru, sensor_list[i], name);
+ pal_get_sensor_units(fru, sensor_list[i], units);
+
+ if (pal_sensor_read(fru, sensor_list[i], &fvalue) < 0) {
+
+ printf("pal_sensor_read failed: fru: %d num: 0x%X name: %-23s\n",
+ fru, sensor_list[i], name);
+ } else {
+ printf("%-23s: %.2f %s\n", name, fvalue, units);
+ }
+ }
+}
+
+int
+main(int argc, char **argv) {
+
+ int ret;
+ int sensor_cnt;
+ uint8_t *sensor_list;
+ uint8_t fru;
+ uint8_t num;
+
+ if (argc < 2 || argc > 3) {
+ print_usage();
+ exit(-1);
+ }
+
+ if (argc == 3) {
+ errno = 0;
+ num = (uint8_t) strtol(argv[2], NULL, 0);
+ if (errno) {
+ printf("Sensor number format incorrect.\n");
+ print_usage();
+ exit(-1);
+ }
+ }
+
+
+ ret = pal_get_fru_id(argv[1], &fru);
+ if (ret < 0) {
+ print_usage();
+ return ret;
+ }
+
+ if (fru == 0) {
+ fru = 1;
+ while (fru <= MAX_NUM_FRUS) {
+
+ if (fru == FRU_NIC) {
+ printf("\nsensor-util does not support nic\n");
+ exit(-1);
+ }
+
+ ret = pal_get_fru_sensor_list(fru, &sensor_list, &sensor_cnt);
+ if (ret < 0) {
+ return ret;
+ }
+
+ if (num) {
+ print_single_sensor_reading(fru, sensor_list, sensor_cnt, num);
+ } else {
+ print_sensor_reading(fru, sensor_list, sensor_cnt);
+ }
+
+ fru++;
+ printf("\n");
+ }
+ } else {
+
+ if (fru == FRU_NIC) {
+ printf("\nsensor-util does not support nic\n");
+ //exit(-1);
+ }
+
+ ret = pal_get_fru_sensor_list(fru, &sensor_list, &sensor_cnt);
+ if (ret < 0) {
+ return ret;
+ }
+
+ if (num) {
+ print_single_sensor_reading(fru, sensor_list, sensor_cnt, num);
+ } else {
+ print_sensor_reading(fru, sensor_list, sensor_cnt);
+ }
+ }
+
+ return 0;
+}
diff --git a/common/recipes-core/sensor-util/sensor-util_0.1.bb b/common/recipes-core/sensor-util/sensor-util_0.1.bb
new file mode 100644
index 0000000..227ec53
--- /dev/null
+++ b/common/recipes-core/sensor-util/sensor-util_0.1.bb
@@ -0,0 +1,34 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+SUMMARY = "Sensor Utility"
+DESCRIPTION = "Util for reading various sensors"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://sensor-util.c;beginline=4;endline=16;md5=b395943ba8a0717a83e62ca123a8d238"
+
+SRC_URI = "file://Makefile \
+ file://sensor-util.c \
+ "
+S = "${WORKDIR}"
+
+binfiles = "sensor-util"
+
+DEPENDS =+ " libpal "
+
+pkgdir = "sensor-util"
+
+do_install() {
+ dst="${D}/usr/local/fbpackages/${pkgdir}"
+ bin="${D}/usr/local/bin"
+ install -d $dst
+ install -d $bin
+ install -m 755 sensor-util ${dst}/sensor-util
+ ln -snf ../fbpackages/${pkgdir}/sensor-util ${bin}/sensor-util
+}
+
+FBPACKAGEDIR = "${prefix}/local/fbpackages"
+
+FILES_${PN} = "${FBPACKAGEDIR}/sensor-util ${prefix}/local/bin"
+
+INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
+INHIBIT_PACKAGE_STRIP = "1"
diff --git a/common/recipes-core/watchdog-ctrl/watchdog-ctrl_0.1.bb b/common/recipes-core/watchdog-ctrl/watchdog-ctrl_0.1.bb
index 00cf0f9..14c0fee 100644
--- a/common/recipes-core/watchdog-ctrl/watchdog-ctrl_0.1.bb
+++ b/common/recipes-core/watchdog-ctrl/watchdog-ctrl_0.1.bb
@@ -1,4 +1,19 @@
# 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
SUMMARY = "Watchdog control utilities."
DESCRIPTION = "The utilities to control system watchdog."
SECTION = "base"
diff --git a/common/recipes-lib/fruid/files/Makefile b/common/recipes-lib/fruid/files/Makefile
new file mode 100644
index 0000000..225d5f7
--- /dev/null
+++ b/common/recipes-lib/fruid/files/Makefile
@@ -0,0 +1,27 @@
+# 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
+
+lib: libfruid.so
+
+libfruid.so: fruid.c
+ $(CC) $(CFLAGS) -fPIC -c -o fruid.o fruid.c
+ $(CC) -shared -o libfruid.so fruid.o -lc
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o libfruid.so
diff --git a/common/recipes-lib/fruid/files/fruid.c b/common/recipes-lib/fruid/files/fruid.c
new file mode 100644
index 0000000..dc71ac8
--- /dev/null
+++ b/common/recipes-lib/fruid/files/fruid.c
@@ -0,0 +1,682 @@
+/*
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <syslog.h>
+#include <time.h>
+#include "fruid.h"
+
+#define FIELD_TYPE(x) ((x & (0x03 << 6)) >> 6)
+#define FIELD_LEN(x) (x & ~(0x03 << 6))
+#define FIELD_EMPTY "N/A"
+
+/* Unix time difference between 1970 and 1996. */
+#define UNIX_TIMESTAMP_1996 820454400
+
+/* Array for BCD Plus definition. */
+const char bcd_plus_array[] = "0123456789 -.XXX";
+
+/* Array for 6-Bit ASCII definition. */
+const char * ascii_6bit[4] = {
+ " !\"#$%&'()*+,-./",
+ "0123456789:;<=>?",
+ "@ABCDEFGHIJKLMNO",
+ "PQRSTUVWXYZ[\\]^_"
+};
+
+/*
+ * calculate_time - calculate time from the unix time stamp stored
+ *
+ * @mfg_time : Unix timestamp since 1996
+ *
+ * returns char * for mfg_time_str
+ * returns NULL for memory allocation failure
+ */
+static char * calculate_time(uint8_t * mfg_time)
+{
+ int len;
+ struct tm * local;
+ time_t unix_time = 0;
+ unix_time = ((mfg_time[2] << 16) + (mfg_time[1] << 8) + mfg_time[0]) * 60;
+ unix_time += UNIX_TIMESTAMP_1996;
+
+ local = localtime(&unix_time);
+ char * str = asctime(local);
+
+ len = strlen(str);
+
+ char * mfg_time_str = (char *) malloc(len);
+ if (!mfg_time_str) {
+ syslog(LOG_ALERT, "fruid: malloc: memory allocation failed\n");
+ return NULL;
+ }
+
+ memset(mfg_time_str, 0, len);
+
+ memcpy(mfg_time_str, str, len);
+
+ mfg_time_str[len - 1] = '\0';
+
+ return mfg_time_str;
+}
+
+/*
+ * verify_chksum - verify the zero checksum of the data
+ *
+ * @area : offset of the area
+ * @len : len of the area in bytes
+ * @chksum_read : stored checksum in the data.
+ *
+ * returns 0 if chksum is verified
+ * returns -1 if there exist a mismatch
+ */
+static int verify_chksum(uint8_t * area, uint8_t len, uint8_t chksum_read)
+{
+ int i;
+ uint8_t chksum = 0;
+
+ for (i = 0; i < len - 1; i++)
+ chksum += area[i];
+
+ /* Zero checksum calculation */
+ chksum = ~(chksum) + 1;
+
+ return (chksum == chksum_read) ? 0 : -1;
+}
+
+/*
+ * get_chassis_type - get the Chassis type
+ *
+ * @type_hex : type stored in the data
+ *
+ * returns char ptr for chassis type string
+ * returns NULL if type not in the list
+ */
+static char * get_chassis_type(uint8_t type_hex)
+{
+ int type, ret;
+ char type_int[4];
+
+ ret = sprintf(type_int, "%u", type_hex);
+ type = atoi(type_int) - 1;
+
+ /* If the type is not in the list defined.*/
+ if (type > FRUID_CHASSIS_TYPECODE_MAX || type < FRUID_CHASSIS_TYPECODE_MIN) {
+ syslog(LOG_INFO, "fruid: chassis area: invalid chassis type\n");
+ return NULL;
+ }
+
+ char * type_str = (char *) malloc(strlen(fruid_chassis_type[type]));
+ if (!type_str) {
+ syslog(LOG_ALERT, "fruid: malloc: memory allocation failed\n");
+ return NULL;
+ }
+
+ memcpy(type_str, fruid_chassis_type[type], strlen(fruid_chassis_type[type]));
+
+ return type_str;
+}
+
+/*
+ * _fruid_area_field_read - read the field data
+ *
+ * @offset : offset of the field
+ *
+ * returns char ptr for the field data string
+ */
+static char * _fruid_area_field_read(uint8_t *offset)
+{
+ int field_type, field_len, field_len_eff;
+ int idx, idx_eff, val;
+ char * field;
+
+ /* Bits 7:6 */
+ field_type = FIELD_TYPE(offset[0]);
+ /* Bits 5:0 */
+ field_len = FIELD_LEN(offset[0]);
+
+ /* Calculate the effective length of the field data based on type stored. */
+ switch (field_type) {
+
+ case TYPE_BINARY:
+ /* TODO: Need to add support to read data stored in binary type. */
+ field_len_eff = 1;
+ break;
+
+ case TYPE_ASCII_6BIT:
+ /*
+ * Every 3 bytes have four 6-bit packed values
+ * + 6-bit values from the remaining field bytes.
+ */
+ field_len_eff = (field_len / 3) * 4 + (field_len % 3);
+ break;
+
+ case TYPE_BCD_PLUS:
+ case TYPE_ASCII_8BIT:
+ field_len_eff = field_len;
+ break;
+ }
+
+ /* If field data is zero, store 'N/A' for that field. */
+ field_len_eff > 0 ? (field = (char *) malloc(field_len_eff + 1)) :
+ (field = (char *) malloc(strlen(FIELD_EMPTY)));
+ if (!field) {
+ syslog(LOG_ALERT, "fruid: malloc: memory allocation failed\n");
+ return NULL;
+ }
+
+ memset(field, 0, field_len + 1);
+
+ if (field_len_eff < 1) {
+ strcpy(field, FIELD_EMPTY);
+ return field;
+ }
+
+ /* Retrieve field data depending on the type it was stored. */
+ switch (field_type) {
+ case TYPE_BINARY:
+ /* TODO: Need to add support to read data stored in binary type. */
+ break;
+
+ case TYPE_BCD_PLUS:
+
+ idx = 0;
+ while (idx != field_len) {
+ field[idx] = bcd_plus_array[offset[idx + 1] & 0x0F];
+ idx++;
+ }
+ field[idx] = '\0';
+ break;
+
+ case TYPE_ASCII_6BIT:
+
+ idx_eff = 0, idx = 1;
+
+ while (field_len > 0) {
+
+ /* 6-Bits => Bits 5:0 of the first byte */
+ val = offset[idx] & 0x3F;
+ field[idx_eff++] = ascii_6bit[(val & 0xF0) >> 4][val & 0x0F];
+ field_len--;
+
+ if (field_len > 0) {
+ /* 6-Bits => Bits 3:0 of second byte + Bits 7:6 of first byte. */
+ val = ((offset[idx] & 0xC0) >> 6) |
+ ((offset[idx + 1] & 0x0F) << 2);
+ field[idx_eff++] = ascii_6bit[(val & 0xF0) >> 4][val & 0x0F];
+ field_len--;
+ }
+
+ if (field_len > 0) {
+ /* 6-Bits => Bits 1:0 of third byte + Bits 7:4 of second byte. */
+ val = ((offset[idx + 1] & 0xF0) >> 4) |
+ ((offset[idx + 2] & 0x03) << 4);
+ field[idx_eff++] = ascii_6bit[(val & 0xF0) >> 4][val & 0x0F];
+
+ /* 6-Bits => Bits 7:2 of third byte. */
+ val = ((offset[idx + 2] & 0xFC) >> 2);
+ field[idx_eff++] = ascii_6bit[(val & 0xF0) >> 4][val & 0x0F];
+
+ field_len--;
+ idx += 3;
+ }
+ }
+ /* Add Null terminator */
+ field[idx_eff] = '\0';
+ break;
+
+ case TYPE_ASCII_8BIT:
+
+ memcpy(field, offset + 1, field_len);
+ /* Add Null terminator */
+ field[field_len] = '\0';
+ break;
+ }
+
+ return field;
+}
+
+/* Free all the memory allocated for fruid information */
+void free_fruid_info(fruid_info_t * fruid)
+{
+ if (fruid->chassis.flag) {
+ free(fruid->chassis.type_str);
+ free(fruid->chassis.part);
+ free(fruid->chassis.serial);
+ free(fruid->chassis.custom);
+ }
+
+ if (fruid->board.flag) {
+ free(fruid->board.mfg_time_str);
+ free(fruid->board.mfg);
+ free(fruid->board.name);
+ free(fruid->board.serial);
+ free(fruid->board.part);
+ free(fruid->board.fruid);
+ }
+
+ if (fruid->product.flag) {
+ free(fruid->board.custom);
+ free(fruid->product.mfg);
+ free(fruid->product.name);
+ free(fruid->product.part);
+ free(fruid->product.version);
+ free(fruid->product.serial);
+ free(fruid->product.asset_tag);
+ free(fruid->product.fruid);
+ free(fruid->product.custom);
+ }
+}
+
+/* Initialize the fruid information struct */
+static void init_fruid_info(fruid_info_t * fruid)
+{
+ fruid->chassis.flag = 0;
+ fruid->board.flag = 0;
+ fruid->product.flag = 0;
+ fruid->chassis.type_str = NULL;
+ fruid->chassis.part = NULL;
+ fruid->chassis.serial = NULL;
+ fruid->chassis.custom = NULL;
+ fruid->board.mfg_time_str = NULL;
+ fruid->board.mfg = NULL;
+ fruid->board.name = NULL;
+ fruid->board.serial = NULL;
+ fruid->board.part = NULL;
+ fruid->board.fruid = NULL;
+ fruid->board.custom = NULL;
+ fruid->product.mfg = NULL;
+ fruid->product.name = NULL;
+ fruid->product.part = NULL;
+ fruid->product.version = NULL;
+ fruid->product.serial = NULL;
+ fruid->product.asset_tag = NULL;
+ fruid->product.fruid = NULL;
+ fruid->product.custom = NULL;
+}
+
+/* Parse the Product area data */
+int parse_fruid_area_product(uint8_t * product,
+ fruid_area_product_t * fruid_product)
+{
+ int ret, index;
+
+ index = 0;
+
+ /* Reset the struct to zero */
+ memset(fruid_product, 0, sizeof(fruid_area_product_t));
+
+ /* Check if the format version is as per IPMI FRUID v1.0 format spec */
+ fruid_product->format_ver = product[index++];
+ if (fruid_product->format_ver != FRUID_FORMAT_VER) {
+ syslog(LOG_ERR, "fruid: product_area: format version not supported");
+ return EPROTONOSUPPORT;
+ }
+
+ fruid_product->area_len = product[index++] * FRUID_AREA_LEN_MULTIPLIER;
+ fruid_product->lang_code = product[index++];
+
+ fruid_product->chksum = product[fruid_product->area_len - 1];
+ ret = verify_chksum((uint8_t *) product,
+ fruid_product->area_len, fruid_product->chksum);
+
+ if (ret) {
+ syslog(LOG_ERR, "fruid: product_area: chksum not verified.");
+ return EBADF;
+ }
+
+ fruid_product->mfg = _fruid_area_field_read(&product[index]);
+ if (fruid_product->mfg == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(product[index]) + 1;
+
+ fruid_product->name = _fruid_area_field_read(&product[index]);
+ if (fruid_product->name == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(product[index]) + 1;
+
+ fruid_product->part = _fruid_area_field_read(&product[index]);
+ if (fruid_product->part == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(product[index]) + 1;
+
+ fruid_product->version = _fruid_area_field_read(&product[index]);
+ if (fruid_product->version == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(product[index]) + 1;
+
+ fruid_product->serial = _fruid_area_field_read(&product[index]);
+ if (fruid_product->serial == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(product[index]) + 1;
+
+ fruid_product->asset_tag = _fruid_area_field_read(&product[index]);
+ if (fruid_product->asset_tag == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(product[index]) + 1;
+
+ fruid_product->fruid = _fruid_area_field_read(&product[index]);
+ if (fruid_product->fruid == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(product[index]) + 1;
+
+ fruid_product->custom = _fruid_area_field_read(&product[index]);
+ if (fruid_product->custom == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(product[index]) + 1;
+
+ return 0;
+}
+
+/* Parse the Board area data */
+int parse_fruid_area_board(uint8_t * board,
+ fruid_area_board_t * fruid_board)
+{
+ int ret, index, i;
+ time_t unix_time;
+
+ index = 0;
+
+ /* Reset the struct to zero */
+ memset(fruid_board, 0, sizeof(fruid_area_board_t));
+
+ /* Check if the format version is as per IPMI FRUID v1.0 format spec */
+ fruid_board->format_ver = board[index++];
+ if (fruid_board->format_ver != FRUID_FORMAT_VER) {
+ syslog(LOG_ERR, "fruid: board_area: format version not supported");
+ return EPROTONOSUPPORT;
+ }
+ fruid_board->area_len = board[index++] * FRUID_AREA_LEN_MULTIPLIER;
+ fruid_board->lang_code = board[index++];
+
+ fruid_board->chksum = board[fruid_board->area_len - 1];
+ ret = verify_chksum((uint8_t *) board,
+ fruid_board->area_len, fruid_board->chksum);
+
+ if (ret) {
+ syslog(LOG_ERR, "fruid: board_area: chksum not verified.");
+ return EBADF;
+ }
+
+ for (i = 0; i < 3; i++) {
+ fruid_board->mfg_time[i] = board[index++];
+ }
+
+ fruid_board->mfg_time_str = calculate_time(fruid_board->mfg_time);
+ if (fruid_board->mfg_time_str == NULL)
+ return ENOMEM;
+
+ fruid_board->mfg = _fruid_area_field_read(&board[index]);
+ if (fruid_board->mfg == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(board[index]) + 1;
+
+ fruid_board->name = _fruid_area_field_read(&board[index]);
+ if (fruid_board->name == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(board[index]) + 1;
+
+ fruid_board->serial = _fruid_area_field_read(&board[index]);
+ if (fruid_board->serial == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(board[index]) + 1;
+
+ fruid_board->part = _fruid_area_field_read(&board[index]);
+ if (fruid_board->part == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(board[index]) + 1;
+
+ fruid_board->fruid = _fruid_area_field_read(&board[index]);
+ if (fruid_board->fruid == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(board[index]) + 1;
+
+ fruid_board->custom = _fruid_area_field_read(&board[index]);
+ if (fruid_board->custom == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(board[index]) + 1;
+
+ return 0;
+}
+
+/* Parse the Chassis area data */
+int parse_fruid_area_chassis(uint8_t * chassis,
+ fruid_area_chassis_t * fruid_chassis)
+{
+ int ret, index;
+
+ index = 0;
+
+ /* Reset the struct to zero */
+ memset(fruid_chassis, 0, sizeof(fruid_area_chassis_t));
+
+ /* Check if the format version is as per IPMI FRUID v1.0 format spec */
+ fruid_chassis->format_ver = chassis[index++];
+ if (fruid_chassis->format_ver != FRUID_FORMAT_VER) {
+ syslog(LOG_ERR, "fruid: chassis_area: format version not supported");
+ return EPROTONOSUPPORT;
+ }
+
+ fruid_chassis->area_len = chassis[index++] * FRUID_AREA_LEN_MULTIPLIER;
+ fruid_chassis->type = chassis[index++];
+
+ fruid_chassis->chksum = chassis[fruid_chassis->area_len - 1];
+ ret = verify_chksum((uint8_t *) chassis,
+ fruid_chassis->area_len, fruid_chassis->chksum);
+ if (ret) {
+ syslog(LOG_ERR, "fruid: chassis_area: chksum not verified.");
+ return EBADF;
+ }
+
+ fruid_chassis->type_str = get_chassis_type(fruid_chassis->type);
+ if (fruid_chassis->type_str == NULL)
+ return ENOMSG;
+
+ fruid_chassis->part = _fruid_area_field_read(&chassis[index]);
+ if (fruid_chassis->part == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(chassis[index]) + 1;
+
+ fruid_chassis->serial = _fruid_area_field_read(&chassis[index]);
+ if (fruid_chassis->serial == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(chassis[index]) + 1;
+
+ fruid_chassis->custom = _fruid_area_field_read(&chassis[index]);
+ if (fruid_chassis->custom == NULL)
+ return ENOMEM;
+ index += FIELD_LEN(chassis[index]) + 1;
+
+ return 0;
+}
+
+/* Calculate the area offsets and populate the fruid_eeprom_t struct */
+void set_fruid_eeprom_offsets(uint8_t * eeprom, fruid_header_t * header,
+ fruid_eeprom_t * fruid_eeprom)
+{
+ fruid_eeprom->header = eeprom + 0x00;
+
+ header->offset_area.chassis ? (fruid_eeprom->chassis = eeprom + \
+ (header->offset_area.chassis * FRUID_OFFSET_MULTIPLIER)) : \
+ (fruid_eeprom->chassis = NULL);
+
+ header->offset_area.board ? (fruid_eeprom->board = eeprom + \
+ (header->offset_area.board * FRUID_OFFSET_MULTIPLIER)) : \
+ (fruid_eeprom->board = NULL);
+
+ header->offset_area.product ? (fruid_eeprom->product = eeprom + \
+ (header->offset_area.product * FRUID_OFFSET_MULTIPLIER)) : \
+ (fruid_eeprom->product = NULL);
+
+ header->offset_area.multirecord ? (fruid_eeprom->multirecord = eeprom + \
+ (header->offset_area.multirecord * FRUID_OFFSET_MULTIPLIER)) : \
+ (fruid_eeprom->multirecord = NULL);
+}
+
+/* Populate the common header struct */
+int parse_fruid_header(uint8_t * eeprom, fruid_header_t * header)
+{
+ int ret;
+
+ memcpy((uint8_t *)header, (uint8_t *)eeprom, sizeof(fruid_header_t));
+ ret = verify_chksum((uint8_t *) header,
+ sizeof(fruid_header_t), header->chksum);
+ if (ret) {
+ syslog(LOG_ERR, "fruid: common_header: chksum not verified.");
+ return EBADF;
+ }
+
+ return ret;
+}
+
+/* Parse the eeprom dump and populate the fruid info in struct */
+int populate_fruid_info(fruid_eeprom_t * fruid_eeprom, fruid_info_t * fruid)
+{
+ int ret;
+
+ /* Initial all the required fruid structures */
+ fruid_area_chassis_t fruid_chassis;
+ fruid_area_board_t fruid_board;
+ fruid_area_product_t fruid_product;
+
+ /* If Chassis area is present, parse and print it */
+ if (fruid_eeprom->chassis) {
+ ret = parse_fruid_area_chassis(fruid_eeprom->chassis, &fruid_chassis);
+ if (!ret) {
+ fruid->chassis.flag = 1;
+ fruid->chassis.type_str = fruid_chassis.type_str;
+ fruid->chassis.part = fruid_chassis.part;
+ fruid->chassis.serial = fruid_chassis.serial;
+ fruid->chassis.custom = fruid_chassis.custom;
+ } else
+ return ret;
+ }
+
+ /* If Board area is present, parse and print it */
+ if (fruid_eeprom->board) {
+ ret = parse_fruid_area_board(fruid_eeprom->board, &fruid_board);
+ if (!ret) {
+ fruid->board.flag = 1;
+ fruid->board.mfg_time_str = fruid_board.mfg_time_str;
+ fruid->board.mfg = fruid_board.mfg;
+ fruid->board.name = fruid_board.name;
+ fruid->board.serial = fruid_board.serial;
+ fruid->board.part = fruid_board.part;
+ fruid->board.fruid = fruid_board.fruid;
+ fruid->board.custom = fruid_board.custom;
+ } else
+ return ret;
+ }
+
+ /* If Product area is present, parse and print it */
+ if (fruid_eeprom->product) {
+ ret = parse_fruid_area_product(fruid_eeprom->product, &fruid_product);
+ if (!ret) {
+ fruid->product.flag = 1;
+ fruid->product.mfg = fruid_product.mfg;
+ fruid->product.name = fruid_product.name;
+ fruid->product.part = fruid_product.part;
+ fruid->product.version = fruid_product.version;
+ fruid->product.serial = fruid_product.serial;
+ fruid->product.asset_tag = fruid_product.asset_tag;
+ fruid->product.fruid = fruid_product.fruid;
+ fruid->product.custom = fruid_product.custom;
+ } else
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * fruid_parse - To parse the bin file (eeprom) and populate
+ * the fruid information in the struct
+ * @bin : Eeprom binary file
+ * @fruid : ptr to the struct that holds the fruid information
+ *
+ * returns 0 on success
+ * returns non-zero errno value on error
+ */
+int fruid_parse(const char * bin, fruid_info_t * fruid)
+{
+ int fruid_len, ret;
+ FILE *fruid_fd;
+ uint8_t * eeprom;
+
+ /* Initial all the required fruid structures */
+ fruid_header_t fruid_header;
+ fruid_eeprom_t fruid_eeprom;
+
+ memset(&fruid_header, 0, sizeof(fruid_header_t));
+ memset(&fruid_eeprom, 0, sizeof(fruid_eeprom_t));
+
+ /* Reset parser return value */
+ ret = 0;
+
+ /* Open the FRUID binary file */
+ fruid_fd = fopen(bin, "rb");
+ if (!fruid_fd) {
+ syslog(LOG_ERR, "fruid: unable to open the file");
+ return ENOENT;
+ }
+
+ /* Get the size of the binary file */
+ fseek(fruid_fd, 0, SEEK_END);
+ fruid_len = (uint32_t) ftell(fruid_fd);
+
+ fseek(fruid_fd, 0, SEEK_SET);
+
+ eeprom = (uint8_t *) malloc(fruid_len);
+ if (!eeprom) {
+ syslog(LOG_ALERT, "fruid: malloc: memory allocation failed\n");
+ return ENOMEM;
+ }
+
+ /* Read the binary file */
+ fread(eeprom, sizeof(uint8_t), fruid_len, fruid_fd);
+
+ /* Close the FRUID binary file */
+ fclose(fruid_fd);
+
+ /* Parse the common header data */
+ ret = parse_fruid_header(eeprom, &fruid_header);
+ if (ret) {
+ /* Free the eeprom malloc'ed memory */
+ free(eeprom);
+ return ret;
+ }
+
+ /* Calculate all the area offsets */
+ set_fruid_eeprom_offsets(eeprom, &fruid_header, &fruid_eeprom);
+
+ init_fruid_info(fruid);
+ /* Parse the eeprom and populate the fruid information */
+ ret = populate_fruid_info(&fruid_eeprom, fruid);
+ if (ret) {
+ /* Free the malloced memory for the fruid information */
+ free_fruid_info(fruid);
+ }
+
+ /* Free the eeprom malloced memory */
+ free(eeprom);
+
+ return ret;
+}
diff --git a/common/recipes-lib/fruid/files/fruid.h b/common/recipes-lib/fruid/files/fruid.h
new file mode 100644
index 0000000..713658d
--- /dev/null
+++ b/common/recipes-lib/fruid/files/fruid.h
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef __FRUID_H__
+#define __FRUID_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <openbmc/ipmi.h>
+
+#define FRUID_FORMAT_VER 0x01
+#define FRUID_OFFSET_MULTIPLIER 8
+#define FRUID_AREA_LEN_MULTIPLIER 8
+
+#define FRUID_OFFSET_AREA_INTERNAL 0
+#define FRUID_OFFSET_AREA_CHASSIS 1
+#define FRUID_OFFSET_AREA_BOARD 2
+#define FRUID_OFFSET_AREA_PRODUCT 3
+#define FRUID_OFFSET_AREA_MULTIRECORD 4
+
+#define FRUID_CHASSIS_TYPECODE_MIN 1
+#define FRUID_CHASSIS_TYPECODE_MAX 32
+
+/* To hold the common header information. */
+typedef struct fruid_header_t {
+ uint8_t format_ver : 4;
+ struct {
+ uint8_t internal;
+ uint8_t chassis;
+ uint8_t board;
+ uint8_t product;
+ uint8_t multirecord;
+ } offset_area;
+ uint8_t pad;
+ uint8_t chksum;
+} fruid_header_t;
+
+/* To hold the Chassis area information. */
+typedef struct fruid_area_chassis_t {
+ uint8_t format_ver : 4;
+ uint8_t area_len;
+ uint8_t type;
+ char * type_str;
+ char * part;
+ char * serial;
+ char * custom;
+ uint8_t chksum;
+} fruid_area_chassis_t;
+
+/* To hold the Board area information. */
+typedef struct fruid_area_board_t {
+ uint8_t format_ver : 4;
+ uint8_t area_len;
+ uint8_t lang_code;
+ uint8_t mfg_time[3];
+ char * mfg_time_str;
+ char * mfg;
+ char * name;
+ char * serial;
+ char * part;
+ char * fruid;
+ char * custom;
+ uint8_t chksum;
+} fruid_area_board_t;
+
+/* To hold the Product area information. */
+typedef struct fruid_area_product_t {
+ uint8_t format_ver : 4;
+ uint8_t area_len;
+ uint8_t lang_code;
+ char * mfg;
+ char * name;
+ char * part;
+ char * version;
+ char * serial;
+ char * asset_tag;
+ char * fruid;
+ char * custom;
+ uint8_t chksum;
+} fruid_area_product_t;
+
+/* To hold the Multirecord area information. */
+typedef struct fruid_area_multirecord_t {
+ uint8_t format_ver : 4;
+ uint8_t area_len;
+ /* TODO: Add more fields to support Multirecord area. */
+} fruid_area_multirecord_t;
+
+/* To hold all the fruid information */
+typedef struct fruid_info_t {
+ struct {
+ uint8_t flag;
+ char * type_str;
+ char * part;
+ char * serial;
+ char * custom;
+ } chassis;
+ struct {
+ uint8_t flag;
+ char * mfg_time_str;
+ char * mfg;
+ char * name;
+ char * serial;
+ char * part;
+ char * fruid;
+ char * custom;
+ } board;
+ struct {
+ uint8_t flag;
+ char * mfg;
+ char * name;
+ char * part;
+ char * version;
+ char * serial;
+ char * asset_tag;
+ char * fruid;
+ char * custom;
+ } product;
+} fruid_info_t;
+
+/* To hold the different area offsets. */
+typedef struct fruid_eeprom_t {
+ uint8_t * header;
+ uint8_t * chassis;
+ uint8_t * board;
+ uint8_t * product;
+ uint8_t * multirecord;
+} fruid_eeprom_t;
+
+/* List of all the Chassis types. */
+const char * fruid_chassis_type [] = {
+ "Other", /* 0x01 */
+ "Unknown", /* 0x02 */
+ "Desktop", /* 0x03 */
+ "Low Profile Desktop", /* 0x04 */
+ "Pizza Box", /* 0x05 */
+ "Mini Tower", /* 0x06 */
+ "Tower", /* 0x07 */
+ "Portable", /* 0x08 */
+ "Laptop", /* 0x09 */
+ "Notebook", /* 0x0A */
+ "Hand Held", /* 0x0B */
+ "Docking Station", /* 0x0C */
+ "All in One", /* 0x0D */
+ "Sub Notebook", /* 0x0E */
+ "Space-saving", /* 0x0F */
+ "Lunch Box", /* 0x10 */
+ "Main Server Chassis", /* 0x11 */
+ "Expansion Chassis", /* 0x12 */
+ "SubChassis", /* 0x13 */
+ "Bus Expansion Chassis", /* 0x14 */
+ "Peripheral Chassis", /* 0x15 */
+ "RAID Chassis", /* 0x16 */
+ "Rack Mount Chassis", /* 0x17 */
+ "Sealed-case PC", /* 0x18 */
+ "Multi-system Chassis", /* 0x19 */
+ "Compact PCI", /* 0x1A */
+ "Advanced TCA", /* 0x1B */
+ "Blade", /* 0x1C */
+ "Blade Enclosure", /* 0x1D */
+ "Tablet", /* 0x1E */
+ "Convertible", /* 0x1F */
+ "Detachable" /* 0x20 */
+};
+
+int fruid_parse(const char * bin, fruid_info_t * fruid);
+void free_fruid_info(fruid_info_t * fruid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __FRUID_H__ */
diff --git a/common/recipes-lib/fruid/libfruid_0.1.bb b/common/recipes-lib/fruid/libfruid_0.1.bb
new file mode 100644
index 0000000..7984d3b
--- /dev/null
+++ b/common/recipes-lib/fruid/libfruid_0.1.bb
@@ -0,0 +1,43 @@
+# 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
+
+SUMMARY = "IPMI FRUID Library"
+DESCRIPTION = "library for ipmi fruid"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://fruid.c;beginline=4;endline=16;md5=da35978751a9d71b73679307c4d296ec"
+
+SRC_URI = "file://Makefile \
+ file://fruid.c \
+ file://fruid.h \
+ "
+
+S = "${WORKDIR}"
+
+DEPENDS += " libipmi "
+
+do_install() {
+ install -d ${D}${libdir}
+ install -m 0644 libfruid.so ${D}${libdir}/libfruid.so
+
+ install -d ${D}${includedir}/openbmc
+ install -m 0644 fruid.h ${D}${includedir}/openbmc/fruid.h
+}
+
+FILES_${PN} = "${libdir}/libfruid.so"
+FILES_${PN}-dev = "${includedir}/openbmc/fruid.h"
diff --git a/common/recipes-lib/gpio/files/src/Makefile b/common/recipes-lib/gpio/files/src/Makefile
new file mode 100644
index 0000000..0b605fc
--- /dev/null
+++ b/common/recipes-lib/gpio/files/src/Makefile
@@ -0,0 +1,27 @@
+# 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
+
+lib: libgpio.so
+
+libgpio.so: gpio.c
+ $(CC) $(CFLAGS) -fPIC -c -o gpio.o gpio.c
+ $(CC) -shared -o libgpio.so gpio.o -lc
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o libgpio.so
diff --git a/common/recipes-lib/gpio/files/src/gpio.c b/common/recipes-lib/gpio/files/src/gpio.c
new file mode 100644
index 0000000..9c1f7a2
--- /dev/null
+++ b/common/recipes-lib/gpio/files/src/gpio.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+//#define DEBUG
+//#define VERBOSE
+
+#include "gpio.h"
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/errno.h>
+
+#include <openbmc/log.h>
+
+void gpio_init_default(gpio_st *g) {
+ g->gs_gpio = -1;
+ g->gs_fd = -1;
+}
+
+int gpio_open(gpio_st *g, int gpio)
+{
+ char buf[128];
+ int rc;
+
+ snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%u/value", gpio);
+ rc = open(buf, O_RDWR);
+ if (rc == -1) {
+ rc = errno;
+ LOG_ERR(rc, "Failed to open %s", buf);
+ return -rc;
+ }
+ g->gs_fd = rc;
+ g->gs_gpio = gpio;
+ return 0;
+}
+
+void gpio_close(gpio_st *g)
+{
+ if (g && g->gs_fd != -1) {
+ close(g->gs_fd);
+ }
+ gpio_init_default(g);
+}
+
+gpio_value_en gpio_read(gpio_st *g)
+{
+ char buf[32] = {0};
+ gpio_value_en v;
+ lseek(g->gs_fd, 0, SEEK_SET);
+ read(g->gs_fd, buf, sizeof(buf));
+ v = atoi(buf) ? GPIO_VALUE_HIGH : GPIO_VALUE_LOW;
+ LOG_VER("read gpio=%d value=%d %d", g->gs_gpio, atoi(buf), v);
+ return v;
+}
+
+void gpio_write(gpio_st *g, gpio_value_en v)
+{
+ lseek(g->gs_fd, 0, SEEK_SET);
+ write(g->gs_fd, (v == GPIO_VALUE_HIGH) ? "1" : "0", 1);
+ LOG_VER("write gpio=%d value=%d", g->gs_gpio, v);
+}
+
+int gpio_change_direction(gpio_st *g, gpio_direction_en dir)
+{
+ char buf[128];
+ char *val;
+ int fd = -1;
+ int rc = 0;
+
+ snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%u/direction", g->gs_gpio);
+ fd = open(buf, O_WRONLY);
+ if (fd == -1) {
+ rc = errno;
+ LOG_ERR(rc, "Failed to open %s", buf);
+ return -rc;
+ }
+
+ val = (dir == GPIO_DIRECTION_IN) ? "in" : "out";
+ write(fd, val, strlen(val));
+
+ LOG_VER("change gpio=%d direction=%s", g->gs_gpio, val);
+
+ out:
+ if (fd != -1) {
+ close(fd);
+ }
+ return -rc;
+}
diff --git a/common/recipes-lib/gpio/files/src/gpio.h b/common/recipes-lib/gpio/files/src/gpio.h
new file mode 100644
index 0000000..3303986
--- /dev/null
+++ b/common/recipes-lib/gpio/files/src/gpio.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+#ifndef GPIO_H
+#define GPIO_H
+
+typedef struct {
+ int gs_gpio;
+ int gs_fd;
+} gpio_st;
+
+typedef enum {
+ GPIO_DIRECTION_IN,
+ GPIO_DIRECTION_OUT,
+} gpio_direction_en;
+
+typedef enum {
+ GPIO_VALUE_LOW = 0,
+ GPIO_VALUE_HIGH = 1,
+} gpio_value_en;
+
+int gpio_open(gpio_st* g, int gpio);
+void gpio_close(gpio_st *g);
+gpio_value_en gpio_read(gpio_st *g);
+void gpio_write(gpio_st *g, gpio_value_en v);
+int gpio_change_direction(gpio_st *g, gpio_direction_en dir);
+
+#endif
diff --git a/common/recipes-lib/gpio/libgpio_0.1.bb b/common/recipes-lib/gpio/libgpio_0.1.bb
new file mode 100644
index 0000000..cd32ac0
--- /dev/null
+++ b/common/recipes-lib/gpio/libgpio_0.1.bb
@@ -0,0 +1,40 @@
+# 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
+SUMMARY = "GPIO access library"
+DESCRIPTION = "library to access GPIO"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://gpio.c;beginline=4;endline=16;md5=da35978751a9d71b73679307c4d296ec"
+
+SRC_URI = "file://src \
+ "
+
+DEPENDS += "liblog"
+
+S = "${WORKDIR}/src"
+
+do_install() {
+ install -d ${D}${libdir}
+ install -m 0644 libgpio.so ${D}${libdir}/libgpio.so
+
+ install -d ${D}${includedir}/openbmc
+ install -m 0644 gpio.h ${D}${includedir}/openbmc/gpio.h
+}
+
+FILES_${PN} = "${libdir}/libgpio.so"
+FILES_${PN}-dev = "${includedir}/openbmc/gpio.h"
diff --git a/common/recipes-lib/ipmb/files/Makefile b/common/recipes-lib/ipmb/files/Makefile
new file mode 100644
index 0000000..c09b325
--- /dev/null
+++ b/common/recipes-lib/ipmb/files/Makefile
@@ -0,0 +1,11 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+lib: libipmb.so
+
+libipmb.so: ipmb.c
+ $(CC) $(CFLAGS) -fPIC -c -o ipmb.o ipmb.c
+ $(CC) -shared -o libipmb.so ipmb.o -lc
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o libipmb.so
diff --git a/common/recipes-lib/ipmb/files/ipmb.c b/common/recipes-lib/ipmb/files/ipmb.c
new file mode 100644
index 0000000..731eeba
--- /dev/null
+++ b/common/recipes-lib/ipmb/files/ipmb.c
@@ -0,0 +1,82 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * This file contains code to support IPMI2.0 Specificaton available @
+ * http://www.intel.com/content/www/us/en/servers/ipmi/ipmi-specifications.html
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <errno.h>
+#include <string.h>
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include "ipmb.h"
+
+/*
+ * Function to handle IPMB messages
+ */
+void
+lib_ipmb_handle(unsigned char bus_id,
+ unsigned char *request, unsigned char req_len,
+ unsigned char *response, unsigned char *res_len) {
+
+ int s, t, len;
+ struct sockaddr_un remote;
+ char sock_path[64] = {0};
+
+ sprintf(sock_path, "%s_%d", SOCK_PATH_IPMB, bus_id);
+
+ // TODO: Need to update to reuse the socket instead of creating new
+ if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+ syslog(LOG_ALERT, "lib_ipmb_handle: socket() failed\n");
+ return;
+ }
+
+ remote.sun_family = AF_UNIX;
+ strcpy(remote.sun_path, sock_path);
+ len = strlen(remote.sun_path) + sizeof(remote.sun_family);
+
+ if (connect(s, (struct sockaddr *)&remote, len) == -1) {
+ syslog(LOG_ALERT, "ipmb_handle: connect() failed\n");
+ goto clean_exit;
+ }
+
+ if (send(s, request, req_len, 0) == -1) {
+ syslog(LOG_ALERT, "ipmb_handle: send() failed\n");
+ goto clean_exit;
+ }
+
+ if ((t=recv(s, response, MAX_IPMB_RES_LEN, 0)) > 0) {
+ *res_len = t;
+ } else {
+ if (t < 0) {
+ syslog(LOG_ALERT, "lib_ipmb_handle: recv() failed\n");
+ } else {
+ printf("Server closed connection\n");
+ }
+ }
+
+clean_exit:
+ close(s);
+
+ return;
+}
diff --git a/common/recipes-lib/ipmb/files/ipmb.h b/common/recipes-lib/ipmb/files/ipmb.h
new file mode 100644
index 0000000..d9bc16b
--- /dev/null
+++ b/common/recipes-lib/ipmb/files/ipmb.h
@@ -0,0 +1,75 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ *
+ * 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.
+ */
+
+#ifndef __IPMB_H__
+#define __IPMB_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SOCK_PATH_IPMB "/tmp/ipmb_socket"
+
+#define BMC_SLAVE_ADDR 0x10
+#define BRIDGE_SLAVE_ADDR 0x20
+#define ZERO_CKSUM_CONST 0x100
+
+// rqSA, rsSA, rqSeq, hdrCksum, dataCksum
+#define IPMB_HDR_SIZE 5
+
+// rqSA, NetFn, hdrCksum
+#define IPMB_DATA_OFFSET 3
+
+// Slot#0 is on I2C Bus1
+#define IPMB_BUS_SLOT0 1
+
+#define TIMEOUT_IPMI 4
+#define MAX_IPMB_RES_LEN 255
+
+typedef struct _ipmb_req_t {
+ uint8_t res_slave_addr;
+ uint8_t netfn_lun;
+ uint8_t hdr_cksum;
+ uint8_t req_slave_addr;
+ uint8_t seq_lun;
+ uint8_t cmd;
+ uint8_t data[];
+} ipmb_req_t;
+
+typedef struct _ipmb_res_t {
+ uint8_t req_slave_addr;
+ uint8_t netfn_lun;
+ uint8_t hdr_cksum;
+ uint8_t res_slave_addr;
+ uint8_t seq_lun;
+ uint8_t cmd;
+ uint8_t cc;
+ uint8_t data[];
+} ipmb_res_t;
+
+void lib_ipmb_handle(unsigned char bus_id,
+ unsigned char *request, unsigned char req_len,
+ unsigned char *response, unsigned char *res_len);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* __IPMB_H__ */
diff --git a/common/recipes-lib/ipmb/libipmb_0.1.bb b/common/recipes-lib/ipmb/libipmb_0.1.bb
new file mode 100644
index 0000000..81eed9c
--- /dev/null
+++ b/common/recipes-lib/ipmb/libipmb_0.1.bb
@@ -0,0 +1,26 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+SUMMARY = "IPMB Client Library"
+DESCRIPTION = "library for IPMB Client"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://ipmb.c;beginline=8;endline=20;md5=da35978751a9d71b73679307c4d296ec"
+
+
+SRC_URI = "file://Makefile \
+ file://ipmb.c \
+ file://ipmb.h \
+ "
+
+S = "${WORKDIR}"
+
+do_install() {
+ install -d ${D}${libdir}
+ install -m 0644 libipmb.so ${D}${libdir}/libipmb.so
+
+ install -d ${D}${includedir}/openbmc
+ install -m 0644 ipmb.h ${D}${includedir}/openbmc/ipmb.h
+}
+
+FILES_${PN} = "${libdir}/libipmb.so"
+FILES_${PN}-dev = "${includedir}/openbmc/ipmb.h"
diff --git a/common/recipes-lib/ipmi/files/Makefile b/common/recipes-lib/ipmi/files/Makefile
new file mode 100644
index 0000000..369819c
--- /dev/null
+++ b/common/recipes-lib/ipmi/files/Makefile
@@ -0,0 +1,27 @@
+# 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
+
+lib: libipmi.so
+
+libipmi.so: ipmi.c
+ $(CC) $(CFLAGS) -fPIC -c -o ipmi.o ipmi.c
+ $(CC) -shared -o libipmi.so ipmi.o -lc
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o libipmi.so
diff --git a/common/recipes-lib/ipmi/files/ipmi.c b/common/recipes-lib/ipmi/files/ipmi.c
new file mode 100644
index 0000000..3579eca
--- /dev/null
+++ b/common/recipes-lib/ipmi/files/ipmi.c
@@ -0,0 +1,80 @@
+/*
+ *
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * This file contains code to support IPMI2.0 Specificaton available @
+ * http://www.intel.com/content/www/us/en/servers/ipmi/ipmi-specifications.html
+ *
+ * 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.
+ */
+
+#include "ipmi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#define MAX_IPMI_RES_LEN 100
+
+/*
+ * Function to handle IPMI messages
+ */
+void
+lib_ipmi_handle(unsigned char *request, unsigned char req_len,
+ unsigned char *response, unsigned char *res_len) {
+
+ int s, t, len;
+ struct sockaddr_un remote;
+
+ // TODO: Need to update to reuse the socket instead of creating new
+ if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+ syslog(LOG_ALERT, "lib_ipmi_handle: socket() failed\n");
+ return;
+ }
+
+ remote.sun_family = AF_UNIX;
+ strcpy(remote.sun_path, SOCK_PATH_IPMI);
+ len = strlen(remote.sun_path) + sizeof(remote.sun_family);
+
+ if (connect(s, (struct sockaddr *)&remote, len) == -1) {
+ syslog(LOG_ALERT, "lib_ipmi_handle: connect() failed\n");
+ return;
+ }
+
+ if (send(s, request, req_len, 0) == -1) {
+ syslog(LOG_ALERT, "lib_ipmi_handle: send() failed\n");
+ return;
+ }
+
+ if ((t=recv(s, response, MAX_IPMI_RES_LEN, 0)) > 0) {
+ *res_len = t;
+ } else {
+ if (t < 0) {
+ syslog(LOG_ALERT, "lib_ipmi_handle: recv() failed\n");
+ } else {
+ printf("Server closed connection");
+ }
+
+ return;
+ }
+
+ close(s);
+
+ return;
+}
diff --git a/common/recipes-lib/ipmi/files/ipmi.h b/common/recipes-lib/ipmi/files/ipmi.h
new file mode 100644
index 0000000..2ae7f1c
--- /dev/null
+++ b/common/recipes-lib/ipmi/files/ipmi.h
@@ -0,0 +1,453 @@
+/*
+ *
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ *
+ * 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.
+ */
+
+#ifndef __IPMI_H__
+#define __IPMI_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#define SOCK_PATH_IPMI "/tmp/ipmi_socket"
+
+#define IPMI_SEL_VERSION 0x51
+#define IPMI_SDR_VERSION 0x51
+
+#define MAX_NUM_DIMMS 4
+
+#define SIZE_AUTH_ENABLES 5
+#define SIZE_IP_ADDR 4
+#define SIZE_MAC_ADDR 6
+#define SIZE_NET_MASK 4
+#define SIZE_IP_HDR 3
+#define SIZE_RMCP_PORT 2
+#define SIZE_COMMUNITY_STR 18
+#define SIZE_DEST_TYPE 4
+#define SIZE_DEST_ADDR 18
+#define SIZE_TIME_STAMP 4
+
+#define SIZE_PROC_FREQ 2
+#define SIZE_DIMM_SPEED 2
+#define SIZE_DIMM_SIZE 2
+
+#define SIZE_SYSFW_VER 17
+#define SIZE_SYS_NAME 17
+#define SIZE_OS_NAME 17
+#define SIZE_OS_VER 17
+#define SIZE_BMC_URL 17
+#define SIZE_OS_HV_URL 17
+
+#define SIZE_SEL_REC 16
+
+#define BIC_INTF_HDR_SIZE 3
+
+#define LUN_OFFSET 2
+
+//NetFn, Cmd
+#define IPMI_REQ_HDR_SIZE 2
+
+// NetFn, Cmd, CC
+#define IPMI_RESP_HDR_SIZE 3
+
+#define MAX_IPMI_MSG_SIZE 100
+
+// Type Definition
+#define TYPE_BINARY 0
+#define TYPE_BCD_PLUS 1
+#define TYPE_ASCII_6BIT 2
+#define TYPE_ASCII_8BIT 3
+
+// IPMI request Structure (IPMI/Section 9.2)
+typedef struct
+{
+ unsigned char netfn_lun;
+ unsigned char cmd;
+ unsigned char data[];
+} ipmi_req_t;
+
+// IPMI Multi Node request Structure
+// Supports additional member to identify the node#
+typedef struct
+{
+ unsigned char payload_id;
+ unsigned char netfn_lun;
+ unsigned char cmd;
+ unsigned char data[];
+} ipmi_mn_req_t;
+
+// IPMI response Structure (IPMI/Section 9.3)
+typedef struct
+{
+ unsigned char netfn_lun;
+ unsigned char cmd;
+ unsigned char cc;
+ unsigned char data[];
+} ipmi_res_t;
+
+// IPMI/Spec Table 20-2
+typedef struct _ipmi_dev_id_t {
+ uint8_t dev_id;
+ uint8_t dev_rev;
+ uint8_t fw_rev1;
+ uint8_t fw_rev2;
+ uint8_t ipmi_ver;
+ uint8_t dev_support;
+ uint8_t mfg_id[3];
+ uint8_t prod_id[2];
+ uint8_t aux_fw_rev[4];
+} ipmi_dev_id_t;
+
+
+typedef struct _ipmi_fruid_info_t {
+ uint8_t size_lsb;
+ uint8_t size_msb;
+ uint8_t bytes_words;
+} ipmi_fruid_info_t;
+
+#pragma pack(push, 1)
+
+// Full Sensor SDR record; IPMI/Section 43.1
+typedef struct {
+ // Sensor Record Header
+ unsigned char rec_id[2];
+ unsigned char ver;
+ unsigned char type;
+ unsigned char len;
+ // Record Key Bytes
+ unsigned char owner;
+ unsigned char lun;
+ unsigned char sensor_num;
+ // Record Body Bytes
+ unsigned char ent_id;
+ unsigned char ent_inst;
+ unsigned char sensor_init;
+ unsigned char sensor_caps;
+ unsigned char sensor_type;
+ unsigned char evt_read_type;
+ union {
+ unsigned char assert_evt_mask[2];
+ unsigned char lt_read_mask[2];
+ };
+ union {
+ unsigned char deassert_evt_mask[2];
+ unsigned char ut_read_mask[2];
+ };
+ union {
+ unsigned char read_evt_mask[2];
+ unsigned char set_thresh_mask[2];
+ };
+ unsigned char sensor_units1;
+ unsigned char sensor_units2;
+ unsigned char sensor_units3;
+ unsigned char linear;
+ unsigned char m_val;
+ unsigned char m_tolerance;
+ unsigned char b_val;
+ unsigned char b_accuracy;
+ unsigned char accuracy_dir;
+ unsigned char rb_exp;
+ unsigned char analog_flags;
+ unsigned char nominal;
+ unsigned char normal_max;
+ unsigned char normal_min;
+ unsigned char max_reading;
+ unsigned char min_reading;
+ unsigned char unr_thresh;
+ unsigned char uc_thresh;
+ unsigned char unc_thresh;
+ unsigned char lnr_thresh;
+ unsigned char lc_thresh;
+ unsigned char lnc_thresh;
+ unsigned char pos_hyst;
+ unsigned char neg_hyst;
+ unsigned char rsvd[2];
+ unsigned char oem;
+ unsigned char str_type_len;
+ char str[16];
+} sdr_full_t;
+
+typedef struct _ipmi_sel_sdr_info_t {
+ uint8_t ver;
+ uint16_t rec_count;
+ uint16_t free_space;
+ uint8_t add_ts[4];
+ uint8_t erase_ts[4];
+ uint8_t oper;
+} ipmi_sel_sdr_info_t;
+
+typedef struct _ipmi_sel_sdr_req_t {
+ uint16_t rsv_id;
+ uint16_t rec_id;
+ uint8_t offset;
+ uint8_t nbytes;
+} ipmi_sel_sdr_req_t;
+
+typedef struct _ipmi_sel_sdr_res_t {
+ uint16_t next_rec_id;
+ uint8_t data[];
+} ipmi_sel_sdr_res_t;
+
+#pragma pack(pop)
+
+// LAN Configuration Structure (IPMI/Table 23.4)
+typedef struct
+{
+ unsigned char set_in_prog;
+ unsigned char auth_support;
+ unsigned char auth_enables[SIZE_AUTH_ENABLES];
+ unsigned char ip_addr[SIZE_IP_ADDR];
+ unsigned char ip_src;
+ unsigned char mac_addr[SIZE_MAC_ADDR];
+ unsigned char net_mask[SIZE_NET_MASK];
+ unsigned char ip_hdr[SIZE_IP_HDR];
+ unsigned char pri_rmcp_port[SIZE_RMCP_PORT];
+ unsigned char sec_rmcp_port[SIZE_RMCP_PORT];
+ unsigned char arp_ctrl;
+ unsigned char garp_interval;
+ unsigned char df_gw_ip_addr[SIZE_IP_ADDR];
+ unsigned char df_gw_mac_addr[SIZE_MAC_ADDR];
+ unsigned char back_gw_ip_addr[SIZE_IP_ADDR];
+ unsigned char back_gw_mac_addr[SIZE_MAC_ADDR];
+ unsigned char community_str[SIZE_COMMUNITY_STR];
+ unsigned char no_of_dest;
+ unsigned char dest_type[SIZE_DEST_TYPE];
+ unsigned char dest_addr[SIZE_DEST_ADDR];
+} lan_config_t;
+
+// Structure to store Processor Information
+typedef struct
+{
+ unsigned char type;
+ unsigned char freq[SIZE_PROC_FREQ];
+} proc_info_t;
+
+// Structure to store DIMM Information
+typedef struct
+{
+ unsigned char type;
+ unsigned char speed[SIZE_DIMM_SPEED];
+ unsigned char size[SIZE_DIMM_SIZE];
+} dimm_info_t;
+
+
+// Structure for System Info Params (IPMI/Section 22.14a)
+typedef struct
+{
+ unsigned char set_in_prog;
+ unsigned char sysfw_ver[SIZE_SYSFW_VER];
+ unsigned char sys_name[SIZE_SYS_NAME];
+ unsigned char pri_os_name[SIZE_OS_NAME];
+ unsigned char present_os_name[SIZE_OS_NAME];
+ unsigned char present_os_ver[SIZE_OS_VER];
+ unsigned char bmc_url[SIZE_BMC_URL];
+ unsigned char os_hv_url[SIZE_OS_HV_URL];
+} sys_info_param_t;
+
+// Structure for Sensor Reading (IPMI/Section 35.14)
+typedef struct
+{
+ uint8_t value;
+ uint8_t flags;
+ uint8_t status;
+ uint8_t ext_status;
+} ipmi_sensor_reading_t;
+
+// Network Function Codes (IPMI/Section 5.1)
+enum
+{
+ NETFN_CHASSIS_REQ = 0x00,
+ NETFN_CHASSIS_RES,
+ NETFN_BRIDGE_REQ,
+ NETFN_BRIDGE_RES,
+ NETFN_SENSOR_REQ,
+ NETFN_SENSOR_RES,
+ NETFN_APP_REQ,
+ NETFN_APP_RES,
+ NETFN_FIRMWARE_REQ,
+ NETFN_FIRMWARE_RES,
+ NETFN_STORAGE_REQ,
+ NETFN_STORAGE_RES,
+ NETFN_TRANSPORT_REQ,
+ NETFN_TRANSPORT_RES,
+ NETFN_OEM_REQ = 0x30,
+ NETFN_OEM_RES = 0x31,
+ NETFN_OEM_1S_REQ = 0x38,
+ NETFN_OEM_1S_RES = 0x39,
+};
+
+// Chassis Command Codes (IPMI/Table H-1)
+enum
+{
+ CMD_CHASSIS_GET_STATUS = 0x01,
+ CMD_CHASSIS_GET_BOOT_OPTIONS = 0x09,
+};
+
+
+// Application Command Codes (IPMI/Table H-1)
+enum
+{
+ CMD_APP_GET_DEVICE_ID = 0x01,
+ CMD_APP_GET_SELFTEST_RESULTS = 0x04,
+ CMD_APP_GET_DEVICE_GUID = 0x08,
+ CMD_APP_RESET_WDT = 0x22,
+ CMD_APP_SET_WDT = 0x24,
+ CMD_APP_GET_WDT = 0x25,
+ CMD_APP_GET_GLOBAL_ENABLES = 0x2F,
+ CMD_APP_GET_SYSTEM_GUID = 0x37,
+ CMD_APP_SET_SYS_INFO_PARAMS = 0x58,
+ CMD_APP_GET_SYS_INFO_PARAMS = 0x59,
+};
+
+// Storage Command Codes (IPMI/Table H-1)
+enum
+{
+ CMD_STORAGE_GET_FRUID_INFO = 0x10,
+ CMD_STORAGE_READ_FRUID_DATA = 0x11,
+ CMD_STORAGE_GET_SDR_INFO = 0x20,
+ CMD_STORAGE_RSV_SDR = 0x22,
+ CMD_STORAGE_GET_SDR = 0x23,
+ CMD_STORAGE_GET_SEL_INFO = 0x40,
+ CMD_STORAGE_RSV_SEL = 0x42,
+ CMD_STORAGE_GET_SEL = 0x43,
+ CMD_STORAGE_ADD_SEL = 0x44,
+ CMD_STORAGE_CLR_SEL = 0x47,
+ CMD_STORAGE_GET_SEL_TIME = 0x48,
+ CMD_STORAGE_GET_SEL_UTC = 0x5C,
+};
+
+// Sensor Command Codes (IPMI/Table H-1)
+enum
+{
+ CMD_SENSOR_GET_SENSOR_READING = 0x2D,
+};
+
+// Transport Command Codes (IPMI/Table H-1)
+enum
+{
+ CMD_TRANSPORT_SET_LAN_CONFIG = 0x01,
+ CMD_TRANSPORT_GET_LAN_CONFIG = 0x02,
+};
+
+// OEM Command Codes (Quanta/FB defined commands)
+enum
+{
+ CMD_OEM_SET_PROC_INFO = 0x1A,
+ CMD_OEM_SET_DIMM_INFO = 0x1C,
+ CMD_OEM_SET_POST_START = 0x73,
+ CMD_OEM_SET_POST_END = 0x74,
+};
+
+// OEM 1S Command Codes (Quanta/FB defined commands)
+enum
+{
+ CMD_OEM_1S_MSG_IN = 0x1,
+ CMD_OEM_1S_GET_GPIO = 0x3,
+ CMD_OEM_1S_GET_GPIO_CONFIG = 0x5,
+ CMD_OEM_1S_SET_GPIO_CONFIG = 0x6,
+ CMD_OEM_1S_INTR = 0x7,
+ CMD_OEM_1S_POST_BUF = 0x8,
+ CMD_OEM_1S_GET_CONFIG = 0xE,
+ CMD_OEM_1S_PLAT_DISC = 0xF,
+ CMD_OEM_1S_SET_CONFIG = 0x10,
+ CMD_OEM_1S_BIC_RESET = 0x11,
+ CMD_OEM_1S_GET_POST_BUF = 0x12,
+ CMD_OEM_1S_BIC_UPDATE_MODE = 0x13,
+};
+
+
+// IPMI command Completion Codes (IPMI/Section 5.2)
+enum
+{
+ CC_SUCCESS = 0x00,
+ CC_INVALID_PARAM = 0x80,
+ CC_SEL_ERASE_PROG = 0x81,
+ CC_INVALID_CMD = 0xC1,
+ CC_PARAM_OUT_OF_RANGE = 0xC9,
+ CC_UNSPECIFIED_ERROR = 0xFF,
+};
+
+// LAN Configuration parameters (IPMI/Table 23-4)
+enum
+{
+ LAN_PARAM_SET_IN_PROG,
+ LAN_PARAM_AUTH_SUPPORT,
+ LAN_PARAM_AUTH_ENABLES,
+ LAN_PARAM_IP_ADDR,
+ LAN_PARAM_IP_SRC,
+ LAN_PARAM_MAC_ADDR,
+ LAN_PARAM_NET_MASK,
+ LAN_PARAM_IP_HDR,
+ LAN_PARAM_PRI_RMCP_PORT,
+ LAN_PARAM_SEC_RMCP_PORT,
+ LAN_PARAM_ARP_CTRL,
+ LAN_PARAM_GARP_INTERVAL,
+ LAN_PARAM_DF_GW_IP_ADDR,
+ LAN_PARAM_DF_GW_MAC_ADDR,
+ LAN_PARAM_BACK_GW_IP_ADDR,
+ LAN_PARAM_BACK_GW_MAC_ADDR,
+ LAN_PARAM_COMMUNITY_STR,
+ LAN_PARAM_NO_OF_DEST,
+ LAN_PARAM_DEST_TYPE,
+ LAN_PARAM_DEST_ADDR,
+};
+
+// Boot Option Parameters (IPMI/Table 28-14)
+enum
+{
+ PARAM_SET_IN_PROG = 0x00,
+ PARAM_SVC_PART_SELECT,
+ PARAM_SVC_PART_SCAN,
+ PARAM_BOOT_FLAG_CLR,
+ PARAM_BOOT_INFO_ACK,
+ PARAM_BOOT_FLAGS,
+ PARAM_BOOT_INIT_INFO,
+};
+
+//System Info Parameters (IPMI/Table 22-16c)
+enum
+{
+ SYS_INFO_PARAM_SET_IN_PROG,
+ SYS_INFO_PARAM_SYSFW_VER,
+ SYS_INFO_PARAM_SYS_NAME,
+ SYS_INFO_PARAM_PRI_OS_NAME,
+ SYS_INFO_PARAM_PRESENT_OS_NAME,
+ SYS_INFO_PARAM_PRESENT_OS_VER,
+ SYS_INFO_PARAM_BMC_URL,
+ SYS_INFO_PARAM_OS_HV_URL,
+};
+
+// Bridge-IC interface on which this command initiated
+enum
+{
+ BIC_INTF_ME = 0x01,
+ BIC_INTF_SOL = 0x02,
+ BIC_INTF_KCS = 0x03,
+};
+
+void lib_ipmi_handle(unsigned char *request, unsigned char req_len,
+ unsigned char *response, unsigned char *res_len);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* __IPMI_H__ */
diff --git a/common/recipes-lib/ipmi/libipmi_0.2.bb b/common/recipes-lib/ipmi/libipmi_0.2.bb
new file mode 100644
index 0000000..c5bca76
--- /dev/null
+++ b/common/recipes-lib/ipmi/libipmi_0.2.bb
@@ -0,0 +1,41 @@
+# 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
+SUMMARY = "IPMI Client Library"
+DESCRIPTION = "library for IPMI Client"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://ipmi.c;beginline=8;endline=20;md5=da35978751a9d71b73679307c4d296ec"
+
+
+SRC_URI = "file://Makefile \
+ file://ipmi.c \
+ file://ipmi.h \
+ "
+
+S = "${WORKDIR}"
+
+do_install() {
+ install -d ${D}${libdir}
+ install -m 0644 libipmi.so ${D}${libdir}/libipmi.so
+
+ install -d ${D}${includedir}/openbmc
+ install -m 0644 ipmi.h ${D}${includedir}/openbmc/ipmi.h
+}
+
+FILES_${PN} = "${libdir}/libipmi.so"
+FILES_${PN}-dev = "${includedir}/openbmc/ipmi.h"
diff --git a/common/recipes-lib/log/files/src/log.h b/common/recipes-lib/log/files/src/log.h
new file mode 100644
index 0000000..a69d69e
--- /dev/null
+++ b/common/recipes-lib/log/files/src/log.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+#ifndef LOG_H
+#define LOG_H
+
+#include <stdio.h>
+#include <string.h>
+
+//#define DEBUG
+//#define VERBOSE
+
+#define _LOG(dst, fmt, ...) do { \
+ fprintf(dst, "%s:%d " fmt "\n", \
+ __FUNCTION__, __LINE__, ##__VA_ARGS__); \
+ fflush(dst); \
+} while(0)
+
+#define LOG_ERR(err, fmt, ...) do { \
+ char buf[128]; \
+ strerror_r(err, buf, sizeof(buf)); \
+ _LOG(stderr, "ERROR " fmt ": %s", ##__VA_ARGS__, buf); \
+} while(0)
+
+#define LOG_INFO(fmt, ...) do { \
+ _LOG(stdout, fmt, ##__VA_ARGS__); \
+} while(0)
+
+#ifdef DEBUG
+#define LOG_DBG(fmt, ...) do { \
+ _LOG(stdout, fmt, ##__VA_ARGS__); \
+} while(0)
+#else
+#define LOG_DBG(fmt, ...)
+#endif
+
+#ifdef VERBOSE
+#define LOG_VER(fmt, ...) do { \
+ _LOG(stdout, fmt, ##__VA_ARGS__); \
+} while(0)
+#else
+#define LOG_VER(fmt, ...)
+#endif
+
+#endif
diff --git a/common/recipes-lib/log/liblog_0.1.bb b/common/recipes-lib/log/liblog_0.1.bb
new file mode 100644
index 0000000..8034c0d
--- /dev/null
+++ b/common/recipes-lib/log/liblog_0.1.bb
@@ -0,0 +1,36 @@
+# 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
+
+SUMMARY = "Log util functions"
+DESCRIPTION = "some macros to log"
+SECTION = "dev"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://log.h;beginline=4;endline=16;md5=da35978751a9d71b73679307c4d296ec"
+
+SRC_URI += "file://src \
+ "
+
+S = "${WORKDIR}/src"
+
+do_install() {
+ # common lib and include files
+ install -d ${D}${includedir}/openbmc
+ install -m 0644 log.h ${D}${includedir}/openbmc/log.h
+}
+
+FILES_${PN}-dev = "${includedir}/openbmc/log.h"
diff --git a/common/recipes-lib/sdr/files/Makefile b/common/recipes-lib/sdr/files/Makefile
new file mode 100644
index 0000000..11fe3ee
--- /dev/null
+++ b/common/recipes-lib/sdr/files/Makefile
@@ -0,0 +1,11 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+lib: libsdr.so
+
+libsdr.so: sdr.c
+ $(CC) $(CFLAGS) -fPIC -c -o sdr.o sdr.c
+ $(CC) -lm -shared -o libsdr.so sdr.o -lc
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o libsdr.so
diff --git a/common/recipes-lib/sdr/files/sdr.c b/common/recipes-lib/sdr/files/sdr.c
new file mode 100644
index 0000000..208b10f
--- /dev/null
+++ b/common/recipes-lib/sdr/files/sdr.c
@@ -0,0 +1,210 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * This file contains code to support IPMI2.0 Specificaton available @
+ * http://www.intel.com/content/www/us/en/servers/ipmi/ipmi-specifications.html
+ *
+ * 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.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <math.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <syslog.h>
+#include "sdr.h"
+
+#define FIELD_RATE_UNIT(x) ((x & (0x07 << 3)) >> 3)
+#define FIELD_OP(x) ((x & (0x03 << 1)) >> 1)
+#define FIELD_PERCENTAGE(x) (x & 0x01)
+
+#define FIELD_TYPE(x) ((x & (0x03 << 6)) >> 6)
+#define FIELD_LEN(x) (x & 0xF)
+
+/* Array for BCD Plus definition. */
+const char bcd_plus_array[] = "0123456789 -.XXX";
+
+/* Array for 6-Bit ASCII definition. */
+const char * ascii_6bit[4] = {
+ " !\"#$%&'()*+,-./",
+ "0123456789:;<=>?",
+ "@ABCDEFGHIJKLMNO",
+ "PQRSTUVWXYZ[\\]^_"
+};
+
+/* Get the units of the sensor from the SDR */
+int
+sdr_get_sensor_units(sdr_full_t *sdr, uint8_t *op, uint8_t *modifier,
+ char *units) {
+
+ uint8_t percent;
+ uint8_t rate_idx;
+ uint8_t base_idx;
+
+ /* Bits 5:3 */
+ rate_idx = FIELD_RATE_UNIT(sdr->sensor_units1);
+
+ /* Bits 2:1 */
+ *op = FIELD_OP(sdr->sensor_units1);
+
+ /* Bit 0 */
+ percent = FIELD_PERCENTAGE(sdr->sensor_units1);
+
+ base_idx = sdr->sensor_units2;
+
+ if (*op == 0x0 || *op == 0x3)
+ *modifier = 0;
+ else
+ *modifier = sdr->sensor_units3;
+
+ if (percent) {
+ sprintf(units, "%");
+ } else {
+ if (base_idx > 0 && base_idx <= MAX_SENSOR_BASE_UNIT) {
+ if (rate_idx > 0 && rate_idx < MAX_SENSOR_RATE_UNIT) {
+ sprintf(units, "%s %s", sensor_base_units[base_idx],
+ sensor_rate_units[rate_idx]);
+ } else {
+ sprintf(units, "%s", sensor_base_units[base_idx]);
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+/* Get the name of the sensor from the SDR */
+int
+sdr_get_sensor_name(sdr_full_t *sdr, char *name) {
+ int field_type, field_len;
+ int idx, idx_eff, val;
+ char *str;
+
+ /* Bits 7:6 */
+ field_type = FIELD_TYPE(sdr->str_type_len);
+ /* Bits 4:0 */
+ field_len = FIELD_LEN(sdr->str_type_len) + 1;
+
+ str = sdr->str;
+
+ /* Case: length is zero */
+ if (field_len == 1) {
+ syslog(LOG_ALERT, "get_sensor_name: str length is 0\n");
+ // TODO: Fix this hack later
+ sprintf(name, "%s", str);
+ return -1;
+ }
+
+ /* Retrieve field data depending on the type it was stored. */
+ switch (field_type) {
+ case TYPE_BINARY:
+ /* TODO: Need to add support to read data stored in binary type. */
+ break;
+
+ case TYPE_BCD_PLUS:
+
+ idx = 0;
+ while (idx != field_len) {
+ name[idx] = bcd_plus_array[str[idx] & 0x0F];
+ idx++;
+ }
+ name[idx] = '\0';
+ break;
+
+ case TYPE_ASCII_6BIT:
+
+ idx_eff = idx = 0;
+
+ while (field_len > 0) {
+
+ /* 6-Bits => Bits 5:0 of the first byte */
+ val = str[idx] & 0x3F;
+ name[idx_eff++] = ascii_6bit[(val & 0xF0) >> 4][val & 0x0F];
+ field_len--;
+
+ if (field_len > 0) {
+ /* 6-Bits => Bits 3:0 of second byte + Bits 7:6 of first byte. */
+ val = ((str[idx] & 0xC0) >> 6) |
+ ((str[idx + 1] & 0x0F) << 2);
+ name[idx_eff++] = ascii_6bit[(val & 0xF0) >> 4][val & 0x0F];
+ field_len--;
+ }
+
+ if (field_len > 0) {
+ /* 6-Bits => Bits 1:0 of third byte + Bits 7:4 of second byte. */
+ val = ((str[idx + 1] & 0xF0) >> 4) |
+ ((str[idx + 2] & 0x03) << 4);
+ name[idx_eff++] = ascii_6bit[(val & 0xF0) >> 4][val & 0x0F];
+
+ /* 6-Bits => Bits 7:2 of third byte. */
+ val = ((str[idx + 2] & 0xFC) >> 2);
+ name[idx_eff++] = ascii_6bit[(val & 0xF0) >> 4][val & 0x0F];
+
+ field_len--;
+ idx += 3;
+ }
+ }
+ /* Add Null terminator */
+ name[idx_eff] = '\0';
+ break;
+
+ case TYPE_ASCII_8BIT:
+ snprintf(name, field_len, str);
+ /* Add Null terminator */
+ name[field_len] = '\0';
+ break;
+ }
+
+ return 0;
+}
+
+/* Populates all sensor_info_t struct using the path to SDR dump */
+int
+sdr_init(char *path, sensor_info_t *sinfo) {
+ int fd;
+ uint8_t buf[MAX_SDR_LEN] = {0};
+ uint8_t bytes_rd = 0;
+ uint8_t snr_num = 0;
+ sdr_full_t *sdr;
+
+ while (access(path, F_OK) == -1) {
+ sleep(5);
+ }
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0) {
+ syslog(LOG_ERR, "sdr_init: open failed for %s\n", path);
+ return -1;
+ }
+
+ while ((bytes_rd = read(fd, buf, sizeof(sdr_full_t))) > 0) {
+ if (bytes_rd != sizeof(sdr_full_t)) {
+ syslog(LOG_ERR, "sdr_init: read returns %d bytes\n", bytes_rd);
+ return -1;
+ }
+
+ sdr = (sdr_full_t *) buf;
+ snr_num = sdr->sensor_num;
+ sinfo[snr_num].valid = true;
+ memcpy(&sinfo[snr_num].sdr, sdr, sizeof(sdr_full_t));
+ }
+
+ return 0;
+}
+
diff --git a/common/recipes-lib/sdr/files/sdr.h b/common/recipes-lib/sdr/files/sdr.h
new file mode 100644
index 0000000..c474fb1
--- /dev/null
+++ b/common/recipes-lib/sdr/files/sdr.h
@@ -0,0 +1,163 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ *
+ * 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.
+ */
+
+#ifndef __SDR_H__
+#define __SDR_H__
+
+#include <stdbool.h>
+#include <openbmc/ipmi.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAX_SDR_LEN 64
+
+
+#define MAX_SENSOR_RATE_UNIT 7
+#define MAX_SENSOR_BASE_UNIT 92
+
+typedef struct _sensor_info_t {
+ bool valid;
+ sdr_full_t sdr;
+} sensor_info_t;
+
+/* List of all the Sensor Rate Units types. */
+const char * sensor_rate_units[] = {
+ "", /* 0x00 */
+ "per \xC2\xB5s", /* 0x01 */
+ "per ms", /* 0x02 */
+ "per s", /* 0x03 */
+ "per min", /* 0x04 */
+ "per hour", /* 0x05 */
+ "per day", /* 0x06 */
+ "reserved", /* 0x07 */
+};
+
+
+/* List of all the Sensor Base Units types. */
+const char * sensor_base_units[] = {
+ "", /* 000 */
+ "C", /* 001 */
+ "F", /* 002 */
+ "K", /* 003 */
+ "Volts", /* 004 */
+ "Amps", /* 005 */
+ "Watts", /* 006 */
+ "Joules", /* 007 */
+ "Coulombs", /* 008 */
+ "VA", /* 009 */
+ "Nits", /* 010 */
+ "lumen", /* 011 */
+ "lux", /* 012 */
+ "Candela", /* 013 */
+ "kPa", /* 014 */
+ "PSI", /* 015 */
+ "Newton", /* 016 */
+ "CFM", /* 017 */
+ "RPM", /* 018 */
+ "Hz", /* 019 */
+ "\xC2\xB5s", /* 020 */
+ "ms", /* 021 */
+ "sec", /* 022 */
+ "min", /* 023 */
+ "hour", /* 024 */
+ "day", /* 025 */
+ "week", /* 026 */
+ "mil", /* 027 */
+ "inches", /* 028 */
+ "feet", /* 029 */
+ "cu in", /* 030 */
+ "cu feet", /* 031 */
+ "mm", /* 032 */
+ "cm", /* 033 */
+ "m", /* 034 */
+ "cu cm", /* 035 */
+ "cu m", /* 036 */
+ "liters", /* 037 */
+ "fluid ounce", /* 038 */
+ "radians", /* 039 */
+ "steradians", /* 040 */
+ "revolutions", /* 041 */
+ "cycles", /* 042 */
+ "gravities", /* 043 */
+ "ounce", /* 044 */
+ "pound", /* 045 */
+ "ft-lb", /* 046 */
+ "oz-in", /* 047 */
+ "gauss", /* 048 */
+ "gilberts", /* 049 */
+ "henry", /* 050 */
+ "millihenry", /* 051 */
+ "farad", /* 052 */
+ "microfarad", /* 053 */
+ "ohms", /* 054 */
+ "siemens", /* 055 */
+ "mole", /* 056 */
+ "becquerel", /* 057 */
+ "PPM", /* 058 */
+ "reserved", /* 059 */
+ "Db", /* 060 */
+ "DbA", /* 061 */
+ "DbC", /* 062 */
+ "gray", /* 063 */
+ "sievert", /* 064 */
+ "color temp deg K", /* 065 */
+ "bit", /* 066 */
+ "kilobit", /* 067 */
+ "megabit", /* 068 */
+ "gigabit", /* 069 */
+ "B", /* 070 */
+ "KB", /* 071 */
+ "MB", /* 072 */
+ "GB", /* 073 */
+ "word", /* 074 */
+ "dword", /* 075 */
+ "qword", /* 076 */
+ "line", /* 077 */
+ "hit", /* 078 */
+ "miss", /* 079 */
+ "retry", /* 080 */
+ "reset", /* 081 */
+ "overflow", /* 082 */
+ "underrun", /* 083 */
+ "collision", /* 084 */
+ "packets", /* 085 */
+ "messages", /* 086 */
+ "characters", /* 087 */
+ "error", /* 088 */
+ "correctable error", /* 089 */
+ "uncorrectable error", /* 090 */
+ "fatal error", /* 091 */
+ "grams", /* 092 */
+ "", /* 093 */
+};
+
+int sdr_init(char *path, sensor_info_t *sinfo);
+
+int sdr_get_sensor_units(sdr_full_t *sdr, uint8_t *op, uint8_t *modifier,
+ char *units);
+int sdr_get_sensor_name(sdr_full_t *sdr, char *name);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* __SDR_H__ */
diff --git a/common/recipes-lib/sdr/libsdr_0.1.bb b/common/recipes-lib/sdr/libsdr_0.1.bb
new file mode 100644
index 0000000..958e0c6
--- /dev/null
+++ b/common/recipes-lib/sdr/libsdr_0.1.bb
@@ -0,0 +1,30 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+SUMMARY = "SDR Library"
+DESCRIPTION = "library for extracting information from SDR"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+
+
+LIC_FILES_CHKSUM = "file://sdr.c;beginline=8;endline=20;md5=da35978751a9d71b73679307c4d296ec"
+
+
+SRC_URI = "file://Makefile \
+ file://sdr.c \
+ file://sdr.h \
+ "
+
+S = "${WORKDIR}"
+
+DEPENDS += " libipmi "
+
+do_install() {
+ install -d ${D}${libdir}
+ install -m 0644 libsdr.so ${D}${libdir}/libsdr.so
+
+ install -d ${D}${includedir}/openbmc
+ install -m 0644 sdr.h ${D}${includedir}/openbmc/sdr.h
+}
+
+FILES_${PN} = "${libdir}/libsdr.so"
+FILES_${PN}-dev = "${includedir}/openbmc/sdr.h"
diff --git a/common/recipes-rest/rest-api/files/node.py b/common/recipes-rest/rest-api/files/node.py
new file mode 100644
index 0000000..41e0a3e
--- /dev/null
+++ b/common/recipes-rest/rest-api/files/node.py
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+#
+# 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
+#
+
+# Class Definition for Resource
+
+class node:
+ def __init__(self, info = None, actions = None):
+ if info == None:
+ self.info = {}
+ else:
+ self.info = info
+
+ if actions == None:
+ self.actions = []
+ else:
+ self.actions = actions
+
+ def getInformation(self):
+ return self.info
+
+ def getActions(self):
+ return self.actions
+
+ def doAction(self, action):
+ result = { "result": 'failure', "reason": 'not supported'}
diff --git a/common/recipes-rest/rest-api/files/node_api.py b/common/recipes-rest/rest-api/files/node_api.py
new file mode 100644
index 0000000..ca5cc5c
--- /dev/null
+++ b/common/recipes-rest/rest-api/files/node_api.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+#
+# 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
+#
+
+from node import node
+from pal import *
+
+def get_node_api():
+
+ name = pal_get_platform_name()
+ info = {
+ "Description": name + " RESTful API Entry",
+ }
+
+ return node(info)
diff --git a/common/recipes-rest/rest-api/files/node_bmc.py b/common/recipes-rest/rest-api/files/node_bmc.py
new file mode 100644
index 0000000..14b51e7
--- /dev/null
+++ b/common/recipes-rest/rest-api/files/node_bmc.py
@@ -0,0 +1,95 @@
+#!/usr/bin/env python
+#
+# 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
+#
+
+
+from subprocess import *
+import re
+from node import node
+from pal import *
+
+class bmcNode(node):
+ def __init__(self, info = None, actions = None):
+ if info == None:
+ self.info = {}
+ else:
+ self.info = info
+ if actions == None:
+ self.actions = []
+ else:
+ self.actions = actions
+
+ def getInformation(self):
+ # Get Platform Name
+ name = pal_get_platform_name()
+
+ # Get BMC Reset Reason
+ wdt_counter = Popen('devmem 0x1e785010', \
+ shell=True, stdout=PIPE).stdout.read()
+ wdt_counter = int(wdt_counter, 0)
+
+ wdt_counter &= 0xff00
+
+ if wdt_counter:
+ por_flag = 0
+ else:
+ por_flag = 1
+
+ if por_flag:
+ reset_reason = "Power ON Reset"
+ else:
+ reset_reason = "User Initiated Reset or WDT Reset"
+
+ # Get BMC's Up Time
+ uptime = Popen('uptime', \
+ shell=True, stdout=PIPE).stdout.read()
+
+ # Get Usage information
+ data = Popen('top -b n1', \
+ shell=True, stdout=PIPE).stdout.read()
+ adata = data.split('\n')
+ mem_usage = adata[0]
+ cpu_usage = adata[1]
+
+ # Get OpenBMC version
+ version = ""
+ data = Popen('cat /etc/issue', \
+ shell=True, stdout=PIPE).stdout.read()
+ #Version might start with 'v'(wedge) or 'V'(Yosemite)
+ if name == 'Yosemite':
+ ver = re.search(r'V([\w\d._-]*)\s', data)
+ else:
+ ver = re.search(r'v([\w\d._-]*)\s', data)
+ if ver:
+ version = ver.group(1)
+
+
+ info = {
+ "Description": name + " BMC",
+ "Reset Reason": reset_reason,
+ "Uptime": uptime,
+ "Memory Usage": mem_usage,
+ "CPU Usage": cpu_usage,
+ "OpenBMC Version": version,
+ }
+
+ return info;
+
+def get_node_bmc():
+ return bmcNode()
diff --git a/common/recipes-rest/rest-api/files/node_config.py b/common/recipes-rest/rest-api/files/node_config.py
new file mode 100644
index 0000000..d37cc25
--- /dev/null
+++ b/common/recipes-rest/rest-api/files/node_config.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+#
+# 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
+#
+
+
+import os
+from subprocess import *
+from node import node
+from pal import *
+
+class configNode(node):
+ def __init__(self, name = None, actions = None):
+ self.name = name
+
+ if actions == None:
+ self.actions = []
+ else:
+ self.actions = actions
+
+ def getInformation(self):
+ result = {}
+ cmd = '/usr/local/bin/cfg-util dump-all'
+ data = Popen(cmd, shell=True, stdout=PIPE).stdout.read()
+ sdata = data.split('\n');
+ for line in sdata:
+ # skip lines that does not start with name
+ if line.startswith(self.name):
+ kv = line.split(':')
+ result[kv[0].strip()] = kv[1].strip()
+ return result
+
+ def doAction(self, data):
+ res = "success"
+ # Get the list of parameters to be updated
+ params = data["update"]
+ for key in params.keys():
+ # update only if the key starts with the name
+ if key.startswith(self.name):
+ ret = pal_set_key_value(key, params[key])
+ if ret:
+ res = "failure"
+
+ result = {"result": res}
+
+ return result
+
+def get_node_config(name):
+ actions = ["update"]
+ return configNode(name = name, actions = actions)
diff --git a/common/recipes-rest/rest-api/files/node_fruid.py b/common/recipes-rest/rest-api/files/node_fruid.py
new file mode 100644
index 0000000..d7a1dc3
--- /dev/null
+++ b/common/recipes-rest/rest-api/files/node_fruid.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+#
+# 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
+#
+
+from subprocess import *
+from node import node
+
+class fruidNode(node):
+ def __init__(self, name, info = None, actions = None):
+ self.name = name
+
+ if info == None:
+ self.info = {}
+ else:
+ self.info = info
+ if actions == None:
+ self.actions = []
+ else:
+ self.actions = actions
+
+ def getInformation(self):
+ result = {}
+ cmd = '/usr/local/bin/fruid-util ' + self.name
+ data = Popen(cmd, shell=True, stdout=PIPE).stdout.read()
+ sdata = data.split('\n')
+ for line in sdata:
+ # skip lines with --- or startin with FRU
+ if line.find("FRU") != -1:
+ continue
+ if line.find("-----") != -1:
+ continue
+
+ kv = line.split(':')
+ if (len(kv) < 2):
+ continue
+
+ result[kv[0].strip()] = kv[1].strip()
+
+ return result
+
+def get_node_fruid(name):
+ return fruidNode(name)
diff --git a/common/recipes-rest/rest-api/files/node_sensors.py b/common/recipes-rest/rest-api/files/node_sensors.py
new file mode 100644
index 0000000..0e7ffc1
--- /dev/null
+++ b/common/recipes-rest/rest-api/files/node_sensors.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python
+#
+# 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
+#
+
+from subprocess import *
+import json
+import os
+import re
+from node import node
+
+class sensorsNode(node):
+ def __init__(self, name, info = None, actions = None):
+ self.name = name
+ if info == None:
+ self.info = {}
+ else:
+ self.info = info
+ if actions == None:
+ self.actions = []
+ else:
+ self.actions = actions
+
+ def getInformation(self):
+ result = {}
+ cmd = '/usr/local/bin/sensor-util ' + self.name
+ data = Popen(cmd, shell=True, stdout=PIPE).stdout.read()
+ sdata = data.split('\n')
+ for line in sdata:
+ # skip lines with " or startin with FRU
+ if line.find("bic_read_sensor_wrapper") != -1:
+ continue
+ if line.find("failed") != -1:
+ continue
+
+ kv = line.split(':')
+ if (len(kv) < 2):
+ continue
+
+ result[kv[0].strip()] = kv[1].strip()
+
+ return result
+
+def get_node_sensors(name):
+ return sensorsNode(name)
diff --git a/common/recipes-rest/rest-api/files/node_server.py b/common/recipes-rest/rest-api/files/node_server.py
new file mode 100644
index 0000000..57a5c42
--- /dev/null
+++ b/common/recipes-rest/rest-api/files/node_server.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+#
+# 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
+#
+
+
+import os
+from subprocess import *
+from node import node
+from pal import *
+
+class serverNode(node):
+ def __init__(self, num = None, info = None, actions = None):
+ self.num = num
+
+ if info == None:
+ self.info = {}
+ else:
+ self.info = info
+ if actions == None:
+ self.actions = []
+ else:
+ self.actions = actions
+
+ def getInformation(self):
+ ret = pal_get_server_power(self.num)
+ if ret == 0:
+ status = 'power-off'
+ elif ret == 1:
+ status = 'power-on'
+ else:
+ status = 'error'
+
+ info = { "status": status }
+
+ return info
+
+ def doAction(self, data):
+ if pal_set_server_power(self.num, data["action"]) == -1:
+ res = 'failure'
+ else:
+ res = 'success'
+
+ result = { "result": res }
+
+ return result
+
+def get_node_server(num):
+ actions = ["power-on",
+ "power-off",
+ "power-cycle",
+ "graceful-shutdown"
+ ]
+ return serverNode(num = num, actions = actions)
diff --git a/common/recipes-rest/rest-api/files/node_spb.py b/common/recipes-rest/rest-api/files/node_spb.py
new file mode 100644
index 0000000..a9fe4e6
--- /dev/null
+++ b/common/recipes-rest/rest-api/files/node_spb.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+#
+# 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
+#
+from node import node
+from pal import *
+
+class spbNode(node):
+ def __init__(self, info = None, actions = None):
+ if info == None:
+ self.info = {}
+ else:
+ self.info = info
+
+ if actions == None:
+ self.actions = []
+ else:
+ self.actions = actions
+
+ def doAction(self, data):
+ if pal_sled_cycle(data["action"]) == -1:
+ res = 'failure'
+ else:
+ res = 'success'
+
+ result = { "result": res }
+
+ return result
+
+def get_node_spb():
+ name = pal_get_platform_name()
+ info = {
+ "Description": name + " Side Plane",
+ }
+
+ actions = [ "sled-cycle" ]
+ return spbNode(info, actions)
diff --git a/common/recipes-rest/rest-api/files/pal.py b/common/recipes-rest/rest-api/files/pal.py
new file mode 100644
index 0000000..8faef30
--- /dev/null
+++ b/common/recipes-rest/rest-api/files/pal.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+#
+# 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
+#
+
+from ctypes import *
+
+lpal_hndl = CDLL("libpal.so")
+
+def pal_get_platform_name():
+ name = create_string_buffer(16)
+ ret = lpal_hndl.pal_get_platform_name(name)
+ if ret:
+ return None
+ else:
+ return name.value
+
+def pal_get_num_slots():
+ num = c_ubyte()
+ p_num = pointer(num)
+ ret = lpal_hndl.pal_get_num_slots(p_num)
+ if ret:
+ return None
+ else:
+ return num.value
+
+def pal_is_server_prsnt(slot_id):
+ status = c_ubyte()
+ p_status = pointer(status)
+ ret = lpal_hndl.pal_is_server_prsnt(slot_id, p_status)
+ if ret:
+ return None
+ else:
+ return status.value
+
+def pal_get_server_power(slot_id):
+ status = c_ubyte()
+ p_status = pointer(status)
+ ret = lpal_hndl.pal_get_server_power(slot_id, p_status)
+ if ret:
+ return None
+ else:
+ return status.value
+
+def pal_set_server_power(slot_id, command):
+ cmd = c_ubyte()
+ if command == 'power-off':
+ cmd.value = 0
+ elif command == 'power-on':
+ cmd.value = 1
+ elif command == 'power-cycle':
+ cmd.value = 2
+ elif command == 'graceful-shutdown':
+ cmd.value = 3
+ ret = lpal_hndl.pal_set_server_power(slot_id, cmd)
+ if ret:
+ return -1
+ else:
+ return 0
+
+def pal_sled_cycle(command):
+ if command != 'sled-cycle':
+ return -1
+
+ ret = lpal_hndl.pal_sled_cycle()
+ if ret:
+ return -1
+ else:
+ return 0
+
+def pal_set_key_value(key, value):
+ pkey = create_string_buffer(key)
+ pvalue = create_string_buffer(value)
+
+ ret = lpal_hndl.pal_set_key_value(pkey, pvalue)
+ if ret:
+ return -1;
+ else:
+ return 0;
diff --git a/common/recipes-rest/rest-api/files/rest.py b/common/recipes-rest/rest-api/files/rest.py
new file mode 100644
index 0000000..0a90d54
--- /dev/null
+++ b/common/recipes-rest/rest-api/files/rest.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python
+#
+# 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
+#
+
+from ctypes import *
+from bottle import route, run, template, request, response, ServerAdapter
+from bottle import abort
+from wsgiref.simple_server import make_server, WSGIRequestHandler, WSGIServer
+import json
+import ssl
+import socket
+import os
+from tree import tree
+from node import node
+from plat_tree import init_plat_tree
+
+CONSTANTS = {
+ 'certificate': '/usr/lib/ssl/certs/rest_server.pem',
+}
+
+root = init_plat_tree()
+
+# Generic router for incoming requests
+@route('/<path:path>', method='ANY')
+def url_router(path):
+ token = path.split('/')
+ # Find the Node
+ r = root
+ for t in token:
+ r = r.getChildByName(t)
+ if r == None:
+ return r
+ c = r.data
+
+ # Handle GET request
+ if request.method == 'GET':
+ # Gather info/actions directly from respective node
+ info = c.getInformation()
+ actions = c.getActions()
+
+ # Create list of resources from tree structure
+ resources = []
+ ca = r.getChildren()
+ for t in ca:
+ resources.append(t.name)
+ result = {'Information': info,
+ 'Actions': actions,
+ 'Resources': resources }
+
+ return result
+
+ # Handle POST request
+ if request.method == 'POST':
+ return c.doAction(json.load(request.body))
+
+ return None
+
+run(host = "::", port = 8080)
+
+# TODO: Test the https connection with proper certificates
+# SSL Wrapper for Rest API
+class SSLWSGIRefServer(ServerAdapter):
+ def run(self, handler):
+ if self.quiet:
+ class QuietHandler(WSGIRequestHandler):
+ def log_request(*args, **kw): pass
+ self.options['handler_class'] = QuietHandler
+
+ # IPv6 Support
+ server_cls = self.options.get('server_class', WSGIServer)
+
+ if ':' in self.host:
+ if getattr(server_cls, 'address_family') == socket.AF_INET:
+ class server_cls(server_cls):
+ address_family = socket.AF_INET6
+
+ srv = make_server(self.host, self.port, handler,
+ server_class=server_cls, **self.options)
+ srv.socket = ssl.wrap_socket (
+ srv.socket,
+ certfile=CONSTANTS['certificate'],
+ server_side=True)
+ srv.serve_forever()
+
+# Use SSL if the certificate exists. Otherwise, run without SSL.
+if os.access(CONSTANTS['certificate'], os.R_OK):
+ run(server=SSLWSGIRefServer(host="::", port=8443))
+else:
+ run(host = "::", port = 8080)
diff --git a/common/recipes-rest/rest-api/files/tree.py b/common/recipes-rest/rest-api/files/tree.py
new file mode 100644
index 0000000..ca81510
--- /dev/null
+++ b/common/recipes-rest/rest-api/files/tree.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+#
+# 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
+#
+
+# Class Definition for Tree
+
+class tree:
+ def __init__(self, name, data = None):
+ self.name = name
+ self.data = data
+ self.children = []
+
+ def addChild(self, child):
+ self.children.append(child)
+
+ def addChildren(self, children):
+ for child in children:
+ self.children.append(child)
+
+ def getChildren(self):
+ return self.children
+
+ def getChildByName(self, name):
+ if self.name == name:
+ return self
+
+ for child in self.children:
+ if child.name == name:
+ return child
+ return None
diff --git a/common/recipes-rest/rest-api/rest-api_0.2.bb b/common/recipes-rest/rest-api/rest-api_0.2.bb
new file mode 100644
index 0000000..1956cb2
--- /dev/null
+++ b/common/recipes-rest/rest-api/rest-api_0.2.bb
@@ -0,0 +1,36 @@
+# 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
+SUMMARY = "Rest API Daemon"
+DESCRIPTION = "Daemon to handle RESTful interface."
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://rest.py;beginline=5;endline=18;md5=0b1ee7d6f844d472fa306b2fee2167e0"
+
+
+SRC_URI = "file://rest.py \
+ file://node.py \
+ file://tree.py \
+ file://pal.py \
+ "
+DEPENDS += "libpal"
+
+
+binfiles = "rest.py node.py tree.py pal.py"
+
+pkgdir = "rest-api"
+RDEPENDS_${PN} += "libpal"
diff --git a/common/recipes-utils/bitbang/bitbang_0.1.bb b/common/recipes-utils/bitbang/bitbang_0.1.bb
new file mode 100644
index 0000000..16fdbd3
--- /dev/null
+++ b/common/recipes-utils/bitbang/bitbang_0.1.bb
@@ -0,0 +1,37 @@
+# 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
+SUMMARY = "Device driver using GPIO bitbang"
+DESCRIPTION = "Various device driver using GPIO bitbang"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://bitbang.c;beginline=4;endline=16;md5=da35978751a9d71b73679307c4d296ec"
+
+SRC_URI = "file://src \
+ "
+
+DEPENDS += "openbmc-utils libgpio"
+
+S = "${WORKDIR}/src"
+
+do_install() {
+ install -d ${D}${bindir}
+ install -m 755 spi-bb ${D}${bindir}/spi-bb
+ install -m 755 mdio-bb ${D}${bindir}/mdio-bb
+}
+
+FILES_${PN} = "${bindir}"
diff --git a/common/recipes-utils/bitbang/files/src/Makefile b/common/recipes-utils/bitbang/files/src/Makefile
new file mode 100644
index 0000000..24e4220
--- /dev/null
+++ b/common/recipes-utils/bitbang/files/src/Makefile
@@ -0,0 +1,29 @@
+# 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
+
+all: spi-bb mdio-bb
+
+spi-bb: spi_bb.o bitbang.o
+ $(CC) -o $@ $^ $(LDFLAGS) -lgpio
+
+mdio-bb: mdio_bb.o bitbang.o
+ $(CC) -o $@ $^ $(LDFLAGS) -lgpio
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o spi-bb mdio-bb
diff --git a/common/recipes-utils/bitbang/files/src/bitbang.c b/common/recipes-utils/bitbang/files/src/bitbang.c
new file mode 100644
index 0000000..1318f42
--- /dev/null
+++ b/common/recipes-utils/bitbang/files/src/bitbang.c
@@ -0,0 +1,236 @@
+/*
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+//#define DEBUG
+//#define VERBOSE
+
+#include "bitbang.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <openbmc/log.h>
+
+#define NANOSEC_IN_SEC (1000 * 1000 * 1000)
+
+#define BITBANG_FREQ_MAX (500 * 1000 * 1000) /* 500M Hz */
+#define BITBANG_FREQ_DEFAULT (1 * 1000 * 1000) /* 1M Hz */
+
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+
+struct bitbang_handle {
+ bitbang_init_st bbh_init;
+ uint32_t bbh_half_clk; /* ns per clock cycle */
+};
+
+void bitbang_init_default(bitbang_init_st *init)
+{
+ memset(init, sizeof(*init), 0);
+ init->bbi_clk_start = BITBANG_PIN_HIGH;
+ init->bbi_data_out = BITBANG_CLK_EDGE_FALLING;
+ init->bbi_data_in = BITBANG_CLK_EDGE_RISING;
+ init->bbi_freq = BITBANG_FREQ_DEFAULT;
+}
+
+bitbang_handle_st* bitbang_open(const bitbang_init_st *init)
+{
+ bitbang_handle_st *hdl;
+
+ if (!init || !init->bbi_pin_f
+ || !init->bbi_freq || init->bbi_freq > BITBANG_FREQ_MAX) {
+ LOG_ERR(EINVAL, "Invalid init structure");
+ return NULL;
+ }
+
+ hdl = calloc(1, sizeof(*hdl));
+ if (!hdl) {
+ return NULL;
+ }
+
+ hdl->bbh_init = *init;
+ hdl->bbh_half_clk = NANOSEC_IN_SEC / init->bbi_freq / 2;
+
+ LOG_DBG("Bitbang open with initial %s, data out at %s, data in at %s, "
+ "freq at %uHz, half clk %uns",
+ (init->bbi_clk_start == BITBANG_PIN_LOW) ? "LOW" : "HIGH",
+ (init->bbi_data_out == BITBANG_CLK_EDGE_RISING)
+ ? "RISING" : "FALLING",
+ (init->bbi_data_in == BITBANG_CLK_EDGE_RISING)
+ ? "RISING" : "FALLING",
+ init->bbi_freq, hdl->bbh_half_clk);
+
+ return hdl;
+}
+
+void bitbang_close(bitbang_handle_st *hdl)
+{
+ free(hdl);
+}
+
+/*
+ * The threshold (ns) to use spin instead of nanosleep().
+ * Before adding the high resolution timer support, either spin or nanosleep()
+ * will not bring the process wakeup within 10ms. It turns out the system time
+ * update is also controlled by HZ (100).
+ * After I added the high resolution timer support, the spin works as the
+ * system time is updated more frequently. However, nanosleep() solution is
+ * still noticable slower comparing with spin. There could be some kernel
+ * scheduling tweak missing. Did not get time on that yet.
+ * For now, use 10ms as the threshold to determine if spin or nanosleep()
+ * is used.
+ */
+#define BITBANG_SPIN_THRESHOLD (10 * 1000 * 1000)
+
+static int sleep_ns(uint32_t clk)
+{
+ struct timespec req, rem;
+ int rc = 0;
+ if (clk <= BITBANG_SPIN_THRESHOLD) {
+ struct timespec orig;
+ rc = clock_gettime(CLOCK_MONOTONIC, &req);
+ orig = req;
+ while (!rc && clk) {
+ uint32_t tmp;
+ rc = clock_gettime(CLOCK_MONOTONIC, &rem);
+ tmp = (rem.tv_sec - req.tv_sec) * NANOSEC_IN_SEC;
+ if (rem.tv_nsec >= req.tv_nsec) {
+ tmp += rem.tv_nsec - req.tv_nsec;
+ } else {
+ tmp -= req.tv_nsec - rem.tv_nsec;
+ }
+ if (tmp >= clk) {
+ break;
+ }
+ clk -= tmp;
+ req = rem;
+ }
+ } else {
+ req.tv_sec = 0;
+ req.tv_nsec = clk;
+ while ((rc = nanosleep(&req, &rem)) == -1 && errno == EINTR) {
+ req = rem;
+ }
+ }
+ if (rc == -1) {
+ rc = errno;
+ LOG_ERR(rc, "Failed to sleep %u nanoseconds", clk);
+ }
+ return rc;
+}
+
+int bitbang_io(const bitbang_handle_st *hdl, bitbang_io_st *io)
+{
+ int rc = 0;
+ uint32_t clk = hdl->bbh_half_clk;
+ const struct {
+ bitbang_pin_value_en value;
+ bitbang_clk_edge_en edge;
+ } clks[] = {
+ {BITBANG_PIN_HIGH, BITBANG_CLK_EDGE_FALLING},
+ {BITBANG_PIN_LOW, BITBANG_CLK_EDGE_RISING},
+ };
+ int clk_idx;
+ int n_clk = 0;
+ int n_bits = 0;
+ const uint8_t *dout = io->bbio_dout;
+ uint8_t *din = io->bbio_din;
+ int bit_pos = 7;
+ bitbang_pin_func pin_f = hdl->bbh_init.bbi_pin_f;
+ void *context = hdl->bbh_init.bbi_context;
+
+ if ((io->bbio_in_bits == 0 && io->bbio_din)
+ || (io->bbio_in_bits > 0 && !io->bbio_din)) {
+ rc = EINVAL;
+ LOG_ERR(rc, "Incorrect in bits and in buffer");
+ goto out;
+ }
+
+ if ((io->bbio_out_bits == 0 && io->bbio_dout)
+ || (io->bbio_out_bits > 0 && !io->bbio_dout)) {
+ rc = EINVAL;
+ LOG_ERR(rc, "Incorrect out bits and out buffer");
+ goto out;
+ }
+
+ if (io->bbio_in_bits == 0 && io->bbio_out_bits == 0) {
+ rc = EINVAL;
+ LOG_ERR(rc, "Both in and out bits are 0");
+ goto out;
+ }
+
+ if (hdl->bbh_init.bbi_clk_start == BITBANG_PIN_HIGH) {
+ clk_idx = 0;
+ } else {
+ clk_idx = 1;
+ }
+
+ /* set the CLK pin start position */
+ pin_f(BITBANG_CLK_PIN, clks[clk_idx].value, context);
+
+ /* clear the first byte of din */
+ if (din && io->bbio_in_bits) {
+ memset(din, 0, (io->bbio_in_bits + 7) / 8);
+ }
+
+ do {
+ if ((rc = sleep_ns(clk))) {
+ goto out;
+ }
+
+ /* output first */
+ if (hdl->bbh_init.bbi_data_out == clks[clk_idx].edge) {
+ if (dout && n_bits < io->bbio_out_bits) {
+ pin_f(BITBANG_DATA_OUT, (*dout >> bit_pos) & 0x1, context);
+ }
+ }
+
+ /* then, input */
+ if (hdl->bbh_init.bbi_data_in == clks[clk_idx].edge) {
+ if (din && n_bits < io->bbio_in_bits) {
+ *din |= (pin_f(BITBANG_DATA_IN, 0, context) & 0x1) << bit_pos;
+ }
+ }
+
+ if (++n_clk % 2 == 0) {
+ /* one bit for every 2 half clks */
+ n_bits ++;
+ if (bit_pos == 0) {
+ if (dout) {
+ dout++;
+ }
+ if (din) {
+ din++;
+ }
+ bit_pos = 7;
+ } else {
+ bit_pos --;
+ }
+ }
+ clk_idx = 1 - clk_idx;
+ pin_f(BITBANG_CLK_PIN, clks[clk_idx].value, context);
+ } while (n_bits < MAX(io->bbio_in_bits, io->bbio_out_bits));
+
+ out:
+
+ return -rc;
+}
diff --git a/common/recipes-utils/bitbang/files/src/bitbang.h b/common/recipes-utils/bitbang/files/src/bitbang.h
new file mode 100644
index 0000000..0f21a49
--- /dev/null
+++ b/common/recipes-utils/bitbang/files/src/bitbang.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+#ifndef BITBANG_H
+#define BITBANG_H
+
+#include <stdint.h>
+
+typedef enum {
+ BITBANG_CLK_PIN,
+ BITBANG_DATA_IN,
+ BITBANG_DATA_OUT,
+} bitbang_pin_type_en;
+
+typedef enum {
+ BITBANG_PIN_LOW = 0,
+ BITBANG_PIN_HIGH = 1,
+} bitbang_pin_value_en;
+
+typedef enum {
+ BITBANG_CLK_EDGE_RISING,
+ BITBANG_CLK_EDGE_FALLING,
+} bitbang_clk_edge_en;
+
+typedef bitbang_pin_value_en (* bitbang_pin_func)(
+ bitbang_pin_type_en pin, bitbang_pin_value_en value, void *context);
+
+typedef struct {
+ bitbang_pin_value_en bbi_clk_start;
+ bitbang_clk_edge_en bbi_data_out;
+ bitbang_clk_edge_en bbi_data_in;
+ uint32_t bbi_freq;
+ bitbang_pin_func bbi_pin_f;
+ void *bbi_context;
+} bitbang_init_st;
+
+typedef struct bitbang_handle bitbang_handle_st;
+
+void bitbang_init_default(bitbang_init_st *init);
+bitbang_handle_st* bitbang_open(const bitbang_init_st *init);
+void bitbang_close(bitbang_handle_st *hdl);
+
+typedef struct {
+ uint32_t bbio_in_bits;
+ uint32_t bbio_out_bits;
+ uint8_t *bbio_dout;
+ uint8_t *bbio_din;
+} bitbang_io_st;
+
+int bitbang_io(const bitbang_handle_st *hdl, bitbang_io_st *io);
+
+#endif
diff --git a/common/recipes-utils/bitbang/files/src/mdio_bb.c b/common/recipes-utils/bitbang/files/src/mdio_bb.c
new file mode 100644
index 0000000..9137e17
--- /dev/null
+++ b/common/recipes-utils/bitbang/files/src/mdio_bb.c
@@ -0,0 +1,335 @@
+/*
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+//#define DEBUG
+//#define VERBOSE
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <openbmc/log.h>
+#include <openbmc/gpio.h>
+
+#include "bitbang.h"
+
+typedef struct {
+ gpio_st m_mdc;
+ gpio_st m_mdio;
+} mdio_context_st;
+
+/*
+ * 32b preamble, 2b start of frame, 2b operation code,
+ * 5b phy addr, 5b register addr, 2b turnaround, 16b data
+ */
+#define N_BITS (32 + 2 + 2 + 5 + 5 + 2 + 16)
+#define N_BYTES (N_BITS + 7 / 8)
+
+#define START_OF_FRAME 0x1
+#define OP_READ 0x2
+#define OP_WRITE 0x1
+#define TURNAROUND 0x2 /* TA for write, for read, phy sends out TA */
+
+void usage()
+{
+ fprintf(stderr,
+ "Usage:\n"
+ "mdio-bb: -c <GPIO for MDC> [-C <HIGH|low>]\n"
+ " -d <GPIO for MDIO> [-O <rising|FALLING>]\n"
+ " [-I <RISING|falling>] [-p] [-b]\n"
+ " <read|write> <phy address> <register address>\n"
+ " [value to write]\n");
+}
+
+bitbang_pin_value_en mdio_pin_f(
+ bitbang_pin_type_en pin, bitbang_pin_value_en value, void *context)
+{
+ mdio_context_st *ctx = (mdio_context_st *)context;
+ gpio_st *gpio;
+ bitbang_pin_value_en res;
+
+ switch (pin) {
+ case BITBANG_CLK_PIN:
+ gpio = &ctx->m_mdc;
+ break;
+ case BITBANG_DATA_IN:
+ case BITBANG_DATA_OUT:
+ gpio = &ctx->m_mdio;
+ break;
+ }
+ if (pin == BITBANG_DATA_IN) {
+ res = gpio_read(gpio) ? BITBANG_PIN_HIGH : BITBANG_PIN_LOW;
+ } else {
+ res = value;
+ gpio_write(gpio, ((res == BITBANG_PIN_HIGH)
+ ? GPIO_VALUE_HIGH : GPIO_VALUE_LOW));
+ }
+ return res;
+}
+
+int main(int argc, char* const argv[])
+{
+ int opt;
+ int mdc = -1, mdio = -1;
+ bitbang_pin_value_en mdc_start = BITBANG_PIN_HIGH;
+ bitbang_clk_edge_en out_edge = BITBANG_CLK_EDGE_FALLING;
+ bitbang_clk_edge_en in_edge = BITBANG_CLK_EDGE_RISING;
+ int is_write;
+ uint32_t phy_addr;
+ uint32_t reg_addr;
+ uint32_t data; /* data to write/read*/
+ uint8_t buf[N_BYTES];
+ uint8_t *buf_p;
+ mdio_context_st ctx;
+ bitbang_init_st init;
+ bitbang_handle_st *hdl = NULL;
+ bitbang_io_st io;
+ int n_bits;
+ int i;
+ int rc = 0;
+ int preamble = 0;
+ int binary = 0;
+
+ while ((opt = getopt(argc, argv, "bc:C:d:D:p")) != -1) {
+ switch (opt) {
+ case 'b':
+ binary = 1;
+ break;
+ case 'c':
+ mdc = atoi(optarg);
+ break;
+ case 'C':
+ if (!strcasecmp(optarg, "high")) {
+ mdc_start = BITBANG_PIN_HIGH;
+ } else if (!strcasecmp(optarg, "low")) {
+ mdc_start = BITBANG_PIN_LOW;
+ } else {
+ usage();
+ exit(-1);
+ }
+ break;
+ case 'd':
+ mdio = atoi(optarg);
+ break;
+ case 'I':
+ if (!strcasecmp(optarg, "rising")) {
+ in_edge = BITBANG_CLK_EDGE_RISING;
+ } if (!strcasecmp(optarg, "falling")) {
+ in_edge = BITBANG_CLK_EDGE_FALLING;
+ } else {
+ usage();
+ exit(-1);
+ }
+ break;
+ case 'O':
+ if (!strcasecmp(optarg, "rising")) {
+ out_edge = BITBANG_CLK_EDGE_RISING;
+ } if (!strcasecmp(optarg, "falling")) {
+ out_edge = BITBANG_CLK_EDGE_FALLING;
+ } else {
+ usage();
+ exit(-1);
+ }
+ break;
+ case 'p':
+ preamble = 1;
+ break;
+ default:
+ usage();
+ exit(-1);
+ }
+ }
+
+ if (mdc < 0 || mdio < 0) {
+ usage();
+ exit(-1);
+ }
+
+ if (optind + 2 >= argc) {
+ usage();
+ exit(-1);
+ }
+
+ /* read or write */
+ if (!strcasecmp(argv[optind], "read")) {
+ is_write = 0;
+ } else if (!strcasecmp(argv[optind], "write")) {
+ is_write = 1;
+ } else {
+ usage();
+ exit(-1);
+ }
+
+ /* phy address, 5 bits only, so must be <= 0x1f */
+ phy_addr = strtoul(argv[optind + 1], NULL, 0);
+ if (phy_addr > 0x1f) {
+ usage();
+ exit(-1);
+ }
+
+ /* register address, 5 bits only, so must be <= 0x1f */
+ reg_addr = strtoul(argv[optind + 2], NULL, 0);
+ if (reg_addr > 0x1f) {
+ usage();
+ exit(-1);
+ }
+
+ /* data */
+ if (is_write) {
+ if ((!binary && (optind + 4 != argc)) ||
+ (binary && (optind + 3 != argc))) {
+ usage();
+ exit(-1);
+ }
+ if (binary) {
+ uint16_t temp = 0;
+ if (fread(&temp, sizeof(temp), 1, stdin) != 1) {
+ usage();
+ exit(-1);
+ }
+ data = htons(temp);
+ } else {
+ data = strtoul(argv[optind + 3], NULL, 0);
+ }
+ if (data > 0xFFFF) {
+ usage();
+ exit(-1);
+ }
+ } else {
+ if ((!binary && (optind + 3 != argc)) ||
+ (binary && (optind + 2 != argc))) {
+ usage();
+ exit(-1);
+ }
+ }
+
+ /* open all gpio */
+ memset(&ctx, sizeof(ctx), 0);
+ gpio_init_default(&ctx.m_mdc);
+ gpio_init_default(&ctx.m_mdio);
+ if (gpio_open(&ctx.m_mdc, mdc) || gpio_open(&ctx.m_mdio, mdio)) {
+ goto out;
+ }
+
+ if (gpio_change_direction(&ctx.m_mdc, GPIO_DIRECTION_OUT)
+ || gpio_change_direction(&ctx.m_mdio, GPIO_DIRECTION_OUT)) {
+ goto out;
+ }
+
+ bitbang_init_default(&init);
+ init.bbi_clk_start = mdc_start;
+ init.bbi_data_out = out_edge;
+ init.bbi_data_in = in_edge;
+ init.bbi_freq = 1000 * 1000; /* 1M Hz */
+ init.bbi_pin_f = mdio_pin_f;
+ init.bbi_context = &ctx;
+ hdl = bitbang_open(&init);
+ if (!hdl) {
+ goto out;
+ }
+
+ if (is_write) {
+ buf[0] = (data >> 8) & 0xFF;
+ buf[1] = data & 0xFF;
+ io.bbio_out_bits = 16;
+ io.bbio_dout = buf;
+ io.bbio_in_bits = 0;
+ io.bbio_din = NULL;
+ } else {
+ io.bbio_in_bits = 16;
+ io.bbio_din = buf;
+ io.bbio_out_bits = 0;
+ io.bbio_dout = NULL;
+ }
+
+ /* preamble, 32b */
+ buf_p = buf;
+ n_bits = 0;
+ if (preamble) {
+ /* 32 bit of 1 for preamble */
+ for (i = 0; i < 4; i++) {
+ *buf_p++ = 0xFF;
+ }
+ n_bits += 32;
+ }
+
+ /*
+ * MDIO transaction header is:
+ * 2b START, 2b OPER CODE, 5b PHY ADDR, 5b register addr, 2b TURNROUND
+ */
+ *buf_p++ = (START_OF_FRAME << 6) | (((is_write) ? OP_WRITE : OP_READ) << 4)
+ | ((phy_addr >> 1) & 0xF);
+ *buf_p++ = ((phy_addr & 0x1) << 7) | ((reg_addr & 0x1F) << 2) | TURNAROUND;
+ if (is_write) {
+ *buf_p++ = (data >> 8) & 0xFF;
+ *buf_p++ = data & 0xFF;
+ /* total # of bits is transaction header + 2 bytes to write */
+ n_bits += 2 + 2 + 5 + 5 + 2 + 16;
+ } else {
+ /* for read, master does not send TR, so, n_bits should not include TR */
+ n_bits += 2 + 2 + 5 + 5;
+ }
+
+ memset(&io, sizeof(io), 0);
+ io.bbio_out_bits = n_bits;
+ io.bbio_dout = buf;
+ io.bbio_in_bits = 0;
+ io.bbio_din = NULL;
+
+ rc = bitbang_io(hdl, &io);
+ if (rc != 0) {
+ goto out;
+ }
+
+ /* for read, need to do another io for (2b TR + 16b data) reading */
+ if (!is_write) {
+ /* first, change the MDIO to input */
+ gpio_change_direction(&ctx.m_mdio, GPIO_DIRECTION_IN);
+ /* then, run the clock for read */
+ memset(&io, sizeof(io), 0);
+ io.bbio_out_bits = 0;
+ io.bbio_dout = NULL;;
+ io.bbio_in_bits = 18;
+ io.bbio_din = buf;
+
+ rc = bitbang_io(hdl, &io);
+ if (rc != 0) {
+ goto out;
+ }
+
+ data = ((buf[0] << 2) | (buf[1] >> 6)) & 0xFF;
+ data <<= 8;
+ data |= ((buf[1] << 2) | (buf[2] >> 6)) & 0xFF;
+ }
+
+ if (binary) {
+ if (!is_write) {
+ uint16_t temp = ntohs(data);
+ fwrite(&temp, sizeof(temp), 1, stdout);
+ }
+ } else {
+ printf("%s: 0x%02x\n", (is_write) ? "Wrote" : "Read", data);
+ }
+
+ out:
+ if (hdl) {
+ bitbang_close(hdl);
+ }
+ gpio_close(&ctx.m_mdc);
+ gpio_close(&ctx.m_mdio);
+
+ return 0;
+}
diff --git a/common/recipes-utils/bitbang/files/src/spi_bb.c b/common/recipes-utils/bitbang/files/src/spi_bb.c
new file mode 100644
index 0000000..2125877
--- /dev/null
+++ b/common/recipes-utils/bitbang/files/src/spi_bb.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+//#define DEBUG
+//#define VERBOSE
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <openbmc/gpio.h>
+#include <openbmc/log.h>
+
+#include "bitbang.h"
+
+void usage()
+{
+ fprintf(stderr,
+ "Usage:\n"
+ "spi-bb: -s <GPIO for CS> [-S <HIGH|low>]\n"
+ " -c <GPIO for CLK> [-C <HIGH|low>]\n"
+ " -o <GPIO for MOSI> [-O <rising|FALLING>]\n"
+ " -i <GPIO for MISO> [-I <RISING|falling>]\n"
+ " [-b]\n"
+ " < [-r <number of bits to read>]\n"
+ " [-w <number of bits to write> <byte 1> [... byte N]>\n\n"
+ "Note: If both '-r' and '-w' are provided, 'write' will be performed\n"
+ " before 'read'.\n");
+}
+
+typedef struct {
+ gpio_st sc_clk;
+ gpio_st sc_mosi;
+ gpio_st sc_miso;
+} spi_context_st;
+
+bitbang_pin_value_en spi_pin_f(
+ bitbang_pin_type_en pin, bitbang_pin_value_en value, void *context)
+{
+ spi_context_st *ctx = (spi_context_st *)context;
+ gpio_st *gpio;
+ bitbang_pin_value_en res;
+
+ switch (pin) {
+ case BITBANG_CLK_PIN:
+ gpio = &ctx->sc_clk;
+ break;
+ case BITBANG_DATA_IN:
+ gpio = &ctx->sc_miso;
+ break;
+ case BITBANG_DATA_OUT:
+ gpio = &ctx->sc_mosi;
+ break;
+ }
+ if (pin == BITBANG_DATA_IN) {
+ res = gpio_read(gpio) ? BITBANG_PIN_HIGH : BITBANG_PIN_LOW;
+ } else {
+ res = value;
+ gpio_write(gpio, ((res == BITBANG_PIN_HIGH)
+ ? GPIO_VALUE_HIGH : GPIO_VALUE_LOW));
+ }
+ return res;
+}
+
+int main(int argc, char * const argv[])
+{
+ bitbang_init_st init;
+ bitbang_handle_st *hdl = NULL;
+ int cs = -1, clk = -1, in = -1, out = -1;
+ gpio_st cs_gpio;
+ int opt;
+ int is_write = 0;
+ int is_read = 0;
+ int read_bits = 0;
+ int write_bits = 0;
+ int read_bytes = 0;
+ int write_bytes = 0;
+ int i;
+ uint8_t *read_buf = NULL;;
+ uint8_t *write_buf = NULL;;
+ bitbang_clk_edge_en dout_edge = BITBANG_CLK_EDGE_FALLING;
+ bitbang_clk_edge_en din_edge = BITBANG_CLK_EDGE_RISING;
+ bitbang_pin_value_en clk_start = BITBANG_PIN_HIGH;
+ bitbang_pin_value_en cs_value = BITBANG_PIN_HIGH;
+ spi_context_st ctx;
+ bitbang_io_st io;
+ int rc = 0;
+ int binary = 0;
+
+ memset(&ctx, sizeof(ctx), 0);
+ gpio_init_default(&ctx.sc_clk);
+ gpio_init_default(&ctx.sc_mosi);
+ gpio_init_default(&ctx.sc_miso);
+ gpio_init_default(&cs_gpio);
+
+ while ((opt = getopt(argc, argv, "bs:S:c:C:o:O:i:I:w:r:")) != -1) {
+ switch (opt) {
+ case 'b':
+ binary = 1;
+ break;
+ case 's':
+ cs = atoi(optarg);
+ break;
+ case 'S':
+ if (!strcmp(optarg, "high")) {
+ cs_value = BITBANG_PIN_HIGH;
+ } else if (!strcmp(optarg, "low")) {
+ cs_value = BITBANG_PIN_LOW;
+ } else {
+ usage();
+ exit(-1);
+ }
+ break;
+ case 'c':
+ clk = atoi(optarg);
+ break;
+ case 'C':
+ if (!strcasecmp(optarg, "high")) {
+ clk_start = BITBANG_PIN_HIGH;
+ } else if (!strcasecmp(optarg, "low")) {
+ clk_start = BITBANG_PIN_LOW;
+ } else {
+ usage();
+ exit(-1);
+ }
+ break;
+ case 'o':
+ out = atoi(optarg);
+ break;
+ case 'O':
+ if (!strcasecmp(optarg, "rising")) {
+ dout_edge = BITBANG_CLK_EDGE_RISING;
+ } else if (!strcasecmp(optarg, "falling")) {
+ dout_edge = BITBANG_CLK_EDGE_FALLING;
+ } else {
+ usage();
+ exit(-1);
+ }
+ break;
+ case 'i':
+ in = atoi(optarg);
+ break;
+ case 'I':
+ if (!strcasecmp(optarg, "rising")) {
+ din_edge = BITBANG_CLK_EDGE_RISING;
+ } else if (!strcasecmp(optarg, "falling")) {
+ din_edge = BITBANG_CLK_EDGE_FALLING;
+ } else {
+ usage();
+ exit(-1);
+ }
+ break;
+ case 'w':
+ is_write = 1;
+ write_bits = atoi(optarg);
+ if (write_bits <= 0) {
+ usage();
+ exit(-1);
+ }
+ break;
+ case 'r':
+ is_read = 1;
+ read_bits = atoi(optarg);
+ if (read_bits <= 0) {
+ usage();
+ exit(-1);
+ }
+ break;
+ default:
+ usage();
+ exit(-1);
+ }
+ }
+
+ if (clk < 0 || in < 0 || out < 0) {
+ usage();
+ exit(-1);
+ }
+
+ if ((!is_read && !is_write)) {
+ usage();
+ exit(-1);
+ }
+
+ write_bytes = ((write_bits + 7) / 8);
+ if (write_bytes) {
+ write_buf = calloc(write_bytes, sizeof(uint8_t));
+ if (!write_buf) {
+ goto out;
+ }
+ if (binary) {
+ size_t written_bytes;
+ written_bytes = fread(write_buf, sizeof(*write_buf), write_bytes, stdin);
+ if( written_bytes != write_bytes ) {
+ goto out;
+ }
+ } else {
+ for (i = 0; i < write_bytes && i + optind < argc; i++) {
+ write_buf[i] = strtoul(argv[i + optind], NULL, 0);
+ }
+ }
+ }
+
+ read_bytes = ((read_bits + 7) / 8);
+ if (read_bytes) {
+ read_buf = calloc(read_bytes, sizeof(uint8_t));
+ if (!read_buf) {
+ goto out;
+ }
+ }
+
+ if (gpio_open(&ctx.sc_clk, clk) || gpio_open(&ctx.sc_miso, in)
+ || gpio_open(&ctx.sc_mosi, out)) {
+ goto out;
+ }
+
+ /* change GPIO directions, only MISO is input, all others are output */
+ if (gpio_change_direction(&ctx.sc_clk, GPIO_DIRECTION_OUT)
+ || gpio_change_direction(&ctx.sc_miso, GPIO_DIRECTION_IN)
+ || gpio_change_direction(&ctx.sc_mosi, GPIO_DIRECTION_OUT)) {
+ goto out;
+ }
+
+ if (cs != -1) {
+ if (gpio_open(&cs_gpio, cs)) {
+ goto out;
+ }
+ if (gpio_change_direction(&cs_gpio, GPIO_DIRECTION_OUT)) {
+ goto out;
+ }
+ }
+
+ bitbang_init_default(&init);
+ init.bbi_clk_start = clk_start;
+ init.bbi_data_out = dout_edge;
+ init.bbi_data_in = din_edge;
+ init.bbi_freq = 1000 * 1000; /* 1M Hz */
+ init.bbi_pin_f = spi_pin_f;
+ init.bbi_context = &ctx;
+
+ hdl = bitbang_open(&init);
+ if (!hdl) {
+ goto out;
+ }
+
+ if (cs != -1) {
+ /* have chip select */
+ gpio_write(&cs_gpio, ((cs_value == BITBANG_PIN_HIGH)
+ ? GPIO_VALUE_HIGH : GPIO_VALUE_LOW));
+ }
+
+ memset(&io, sizeof(io), 0);
+ io.bbio_in_bits = read_bits;
+ io.bbio_din = read_buf;
+ io.bbio_out_bits = write_bits;
+ io.bbio_dout = write_buf;
+
+ rc = bitbang_io(hdl, &io);
+ if (rc != 0) {
+ goto out;
+ }
+
+ if (binary) {
+ fwrite(read_buf, sizeof(*read_buf), read_bytes, stdout);
+ } else {
+ if (write_bits) {
+ printf("Wrote %u bits:", write_bits);
+ for (i = 0; i < write_bytes; i++) {
+ printf(" %02x", write_buf[i]);
+ }
+ printf("\n");
+ }
+
+ if (read_bits) {
+ printf("Read %u bits:", read_bits);
+ for (i = 0; i < read_bytes; i++) {
+ printf(" %02x", read_buf[i]);
+ }
+ printf("\n");
+ }
+ }
+
+ out:
+ if (hdl) {
+ bitbang_close(hdl);
+ }
+ gpio_close(&ctx.sc_clk);
+ gpio_close(&ctx.sc_miso);
+ gpio_close(&ctx.sc_mosi);
+ if (cs != -1) {
+ /* reset have chip select */
+ gpio_write(&cs_gpio, ((cs_value == BITBANG_PIN_HIGH)
+ ? GPIO_VALUE_LOW : GPIO_VALUE_HIGH));
+ gpio_close(&cs_gpio);
+ }
+
+ if (read_buf) {
+ free(read_buf);
+ }
+ if (write_buf) {
+ free(write_buf);
+ }
+ return rc;
+}
diff --git a/common/recipes-utils/flashrom/files/01-include-make-local.patch b/common/recipes-utils/flashrom/files/01-include-make-local.patch
new file mode 100644
index 0000000..660c4d6
--- /dev/null
+++ b/common/recipes-utils/flashrom/files/01-include-make-local.patch
@@ -0,0 +1,11 @@
+--- a/Makefile.orig 2015-08-05 17:10:45.945870520 -0700
++++ b/Makefile 2015-08-05 17:11:01.212895144 -0700
+@@ -20,6 +20,8 @@
+
+ PROGRAM = flashrom
+
++include make.local
++
+ ###############################################################################
+ # Defaults for the toolchain.
+
diff --git a/common/recipes-utils/flashrom/files/flashrom-0.9.8/make.local b/common/recipes-utils/flashrom/files/flashrom-0.9.8/make.local
new file mode 100644
index 0000000..54f4213
--- /dev/null
+++ b/common/recipes-utils/flashrom/files/flashrom-0.9.8/make.local
@@ -0,0 +1,9 @@
+CONFIG_BUSPIRATE_SPI = no
+CONFIG_SERPROG = no
+CONFIG_PONY_SPI = no
+CONFIG_DEDIPROG = no
+CONFIG_FT2232_SPI = no
+CONFIG_USBBLASTER_SPI = no
+CONFIG_PICKIT2_SPI = no
+CONFIG_LINUX_SPI = yes
+CONFIG_MSTARDDC_SPI = no
diff --git a/common/recipes-utils/flashrom/flashrom_0.9.8.bb b/common/recipes-utils/flashrom/flashrom_0.9.8.bb
new file mode 100644
index 0000000..a65a7c0
--- /dev/null
+++ b/common/recipes-utils/flashrom/flashrom_0.9.8.bb
@@ -0,0 +1,18 @@
+DESCRIPTION = "flashrom is a utility for identifying, reading, writing, verifying and erasing flash chips"
+LICENSE = "GPLv2"
+HOMEPAGE = "http://flashrom.org"
+
+LIC_FILES_CHKSUM = "file://COPYING;md5=751419260aa954499f7abaabaa882bbe"
+DEPENDS = "pciutils"
+
+SRC_URI = "http://download.flashrom.org/releases/flashrom-${PV}.tar.bz2 \
+ file://flashrom-${PV}/make.local \
+ file://01-include-make-local.patch \
+ "
+
+Src_URI[md5sum] = "ac513076b63ab7eb411a7694bb8f6fda"
+SRC_URI[sha256sum] = "13dc7c895e583111ecca370363a3527d237d178a134a94b20db7df177c05f934"
+
+do_install() {
+ oe_runmake PREFIX=${prefix} DESTDIR=${D} install
+}
diff --git a/common/recipes-utils/jbi/files/code/COPYING b/common/recipes-utils/jbi/files/code/COPYING
new file mode 100644
index 0000000..3912109
--- /dev/null
+++ b/common/recipes-utils/jbi/files/code/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/common/recipes-utils/jbi/files/code/Makefile b/common/recipes-utils/jbi/files/code/Makefile
new file mode 100644
index 0000000..ca84b02
--- /dev/null
+++ b/common/recipes-utils/jbi/files/code/Makefile
@@ -0,0 +1,26 @@
+# 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
+
+all: jbi
+
+jbi: jbicomp.o jbijtag.o jbimain.o jbistub.o
+ $(CC) -g -o $@ $^ $(LDFLAGS) -lgpio
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o jbi
diff --git a/common/recipes-utils/jbi/files/code/jbicomp.c b/common/recipes-utils/jbi/files/code/jbicomp.c
new file mode 100644
index 0000000..99ba515
--- /dev/null
+++ b/common/recipes-utils/jbi/files/code/jbicomp.c
@@ -0,0 +1,416 @@
+/****************************************************************************/
+/* */
+/* Module: jbicomp.c */
+/* */
+/* Copyright (C) Altera Corporation 1997-2001 */
+/* */
+/* Description: Contains the code for compressing and uncompressing */
+/* Boolean array data. */
+/* */
+/* This algorithm works by searching previous bytes in the */
+/* data that match the current data. If a match is found, */
+/* then the offset and length of the matching data can */
+/* replace the actual data in the output. */
+/* */
+/* Revisions: 2.2 fixed /W4 warnings */
+/* */
+/****************************************************************************/
+
+#include "jbiport.h"
+#include "jbiexprt.h"
+#include "jbicomp.h"
+
+#define SHORT_BITS 16
+#define CHAR_BITS 8
+#define DATA_BLOB_LENGTH 3
+#define MATCH_DATA_LENGTH 8192
+#define JBI_ACA_REQUEST_SIZE 1024
+#define JBI_ACA_BUFFER_SIZE (MATCH_DATA_LENGTH + JBI_ACA_REQUEST_SIZE)
+
+unsigned long jbi_in_length = 0L;
+unsigned long jbi_in_index = 0L; /* byte index into compressed array */
+unsigned int jbi_bits_avail = CHAR_BITS;
+
+#if PORT == DOS
+int jbi_current_variable_id = -1;
+int jbi_current_page = -1;
+int jbi_version = 0;
+unsigned long jbi_out_length = 0L;
+unsigned int jbi_out_index = 0; /* byte index into jbi_aca_out_buffer[] */
+unsigned long jbi_aca_in_offset = 0L;
+unsigned char jbi_aca_out_buffer[JBI_ACA_BUFFER_SIZE];
+#endif
+
+/****************************************************************************/
+/* */
+/* The following functions implement incremental decompression of Boolean */
+/* array data, using a small memory window. */
+/* */
+/* This algorithm works by searching previous bytes in the data that match */
+/* the current data. If a match is found, then the offset and length of */
+/* the matching data can replace the actual data in the output. */
+/* */
+/* Memory usage is reduced by maintaining a "window" buffer which contains */
+/* the uncompressed data for one 8K page, plus some extra amount specified */
+/* by JBI_ACA_REQUEST_SIZE. The function jbi_uncompress_page() is used to */
+/* request a subrange of the uncompressed data, starting at a particular */
+/* bit position and extending a maximum of JBI_ACA_REQUEST_SIZE bytes. */
+/* */
+/****************************************************************************/
+
+/****************************************************************************/
+/* */
+
+unsigned int jbi_bits_required(unsigned int n)
+
+/* */
+/* Description: Calculate the minimum number of bits required to */
+/* represent n. */
+/* */
+/* Returns: Number of bits. */
+/* */
+/****************************************************************************/
+{
+ unsigned int result = SHORT_BITS;
+
+ if (n == 0)
+ {
+ result = 1;
+ }
+ else
+ {
+ /* Look for the highest non-zero bit position */
+ while ((n & (1 << (SHORT_BITS - 1))) == 0)
+ {
+ n <<= 1;
+ --result;
+ }
+ }
+
+ return (result);
+}
+
+/****************************************************************************/
+/* */
+
+unsigned int jbi_read_packed
+(
+#if PORT!=DOS
+ unsigned char *buffer,
+#endif
+ unsigned int bits
+)
+
+/* */
+/* Description: Read the next value from the input array "buffer". */
+/* Read only "bits" bits from the array. The amount of */
+/* bits that have already been read from "buffer" is */
+/* stored internally to this function. */
+/* */
+/* Returns: Up to 16 bit value. -1 if buffer overrun. */
+/* */
+/****************************************************************************/
+{
+ unsigned int result = 0;
+ unsigned int shift = 0;
+ unsigned int databyte = 0;
+
+ while (bits > 0)
+ {
+#if PORT==DOS
+ databyte = GET_BYTE(jbi_aca_in_offset + jbi_in_index);
+#else
+ databyte = buffer[jbi_in_index];
+#endif
+ result |= (((databyte >> (CHAR_BITS - jbi_bits_avail))
+ & (0xFF >> (CHAR_BITS - jbi_bits_avail))) << shift);
+
+ if (bits <= jbi_bits_avail)
+ {
+ result &= (0xFFFF >> (SHORT_BITS - (bits + shift)));
+ jbi_bits_avail -= bits;
+ bits = 0;
+ }
+ else
+ {
+ ++jbi_in_index;
+ shift += jbi_bits_avail;
+ bits -= jbi_bits_avail;
+ jbi_bits_avail = CHAR_BITS;
+ }
+ }
+
+ return (result);
+}
+
+#if PORT==DOS
+
+/****************************************************************************/
+/* */
+
+void jbi_uncompress_next_page(int version)
+
+/* */
+/* Description: Uncompresses one page of compressed data, using */
+/* data page as reference for repeated sections. */
+/* Overwrites previous page of data in buffer. */
+/* */
+/* Returns: TRUE for success, FALSE if error encountered */
+/* */
+/****************************************************************************/
+{
+ unsigned int i, j, offset, length;
+ unsigned int end_index;
+ unsigned long tmp_in_index = jbi_in_index;
+ unsigned int tmp_out_index = jbi_out_index;
+ unsigned int tmp_bits_avail = jbi_bits_avail;
+ unsigned int prev[3];
+ unsigned long long_end;
+ unsigned int match_data_length = MATCH_DATA_LENGTH;
+
+ if (version > 0) --match_data_length;
+
+ if (jbi_current_page < 0)
+ {
+ /* this is the first page of the array */
+ jbi_current_page = 0;
+ jbi_in_index = 4; /* skip over length field */
+ jbi_out_index = 0;
+ end_index = (jbi_out_length < JBI_ACA_BUFFER_SIZE) ?
+ (unsigned int) jbi_out_length : JBI_ACA_BUFFER_SIZE;
+ }
+ else
+ {
+ /* this is not the first page */
+ ++jbi_current_page;
+ jbi_out_index -= MATCH_DATA_LENGTH;
+ long_end = jbi_out_length -
+ ((long) jbi_current_page * (long) MATCH_DATA_LENGTH);
+ end_index = (long_end < JBI_ACA_BUFFER_SIZE) ?
+ (unsigned int) long_end : JBI_ACA_BUFFER_SIZE;
+
+ /* copy extra data from end of circular buffer to beginning */
+ for (i = 0; i < jbi_out_index; ++i)
+ {
+ jbi_aca_out_buffer[i] = jbi_aca_out_buffer[i + MATCH_DATA_LENGTH];
+ }
+ }
+
+ while (jbi_out_index < end_index)
+ {
+ /* save state so we can undo the last packet when we reach the end */
+ tmp_in_index = jbi_in_index;
+ tmp_out_index = jbi_out_index;
+ tmp_bits_avail = jbi_bits_avail;
+
+ /* A 0 bit indicates literal data. */
+ if (jbi_read_packed(1) == 0)
+ {
+ for (i = 0; i < DATA_BLOB_LENGTH; ++i)
+ {
+ if (jbi_out_index < end_index)
+ {
+ if (version == 0)
+ {
+ prev[i] = jbi_aca_out_buffer[jbi_out_index] & 0xff;
+ }
+ jbi_aca_out_buffer[jbi_out_index++] =
+ (unsigned char) jbi_read_packed(CHAR_BITS);
+ }
+ }
+ }
+ else
+ {
+ /* A 1 bit indicates offset/length to follow. */
+ offset = jbi_read_packed(jbi_bits_required(
+ (jbi_current_page > 0) ? match_data_length :
+ (jbi_out_index > match_data_length ? match_data_length :
+ jbi_out_index)));
+ length = jbi_read_packed(CHAR_BITS);
+
+ if ((version == 0) && (offset == match_data_length + 3))
+ {
+ jbi_aca_out_buffer[jbi_out_index++] = (unsigned char) prev[0];
+ jbi_aca_out_buffer[jbi_out_index++] = (unsigned char) prev[1];
+ jbi_aca_out_buffer[jbi_out_index++] = (unsigned char) prev[2];
+ length -= 3;
+ }
+
+ for (i = 0; i < length; ++i)
+ {
+ if (jbi_out_index < end_index)
+ {
+ if (offset > jbi_out_index)
+ {
+ j = jbi_out_index + MATCH_DATA_LENGTH - offset;
+ }
+ else j = jbi_out_index - offset;
+ jbi_aca_out_buffer[jbi_out_index] = jbi_aca_out_buffer[j];
+ ++jbi_out_index;
+ }
+ }
+
+ if (version == 0)
+ {
+ prev[0] = jbi_aca_out_buffer[jbi_out_index - 3] & 0xff;
+ prev[1] = jbi_aca_out_buffer[jbi_out_index - 2] & 0xff;
+ prev[2] = jbi_aca_out_buffer[jbi_out_index - 1] & 0xff;
+ }
+ }
+ }
+
+ /* restore the state before the previous packet */
+ jbi_in_index = tmp_in_index;
+ jbi_out_index = tmp_out_index;
+ jbi_bits_avail = tmp_bits_avail;
+}
+
+/****************************************************************************/
+/* */
+
+void jbi_uncompress_page
+(
+ int variable_id,
+ int page,
+ int version
+)
+
+/* */
+/* Description: Uncompress requested page of variable data. Stores */
+/* uncompressed data in jbi_aca_out_buffer[]. */
+/* */
+/* Returns: TRUE if successful, otherwise FALSE if: */
+/* 1) variable is not a compressed array */
+/* 2) compressed data is illegal or corrupted */
+/* 3) requested page is beyond the end of the array */
+/* 4) internal error in the code */
+/* */
+/****************************************************************************/
+{
+ unsigned long symbol_table;
+ unsigned long data_section;
+ unsigned long offset;
+ unsigned long value;
+ int delta = version * 2;
+
+ if (variable_id != jbi_current_variable_id)
+ {
+ /* initialize to uncompress the desired variable */
+ symbol_table = GET_DWORD(16 + (version * 8));
+ data_section = GET_DWORD(20 + (version * 8));
+ offset = symbol_table + ((11 + delta) * variable_id);
+ value = GET_DWORD(offset + 3 + delta);
+ jbi_current_variable_id = variable_id;
+ jbi_current_page = -1;
+ jbi_bits_avail = CHAR_BITS;
+ jbi_in_length = GET_DWORD(offset + 7 + delta);
+ jbi_out_length =
+ (((unsigned long) GET_BYTE(data_section + value)) |
+ (((unsigned long) GET_BYTE(data_section + value + 1)) << 8) |
+ (((unsigned long) GET_BYTE(data_section + value + 2)) << 16) |
+ (((unsigned long) GET_BYTE(data_section + value + 3)) << 24));
+ jbi_in_index = 4; /* skip over length field */
+ jbi_out_index = 0;
+ jbi_aca_in_offset = data_section + value;
+ }
+
+ /* to look back at an earlier page, start over at the beginning */
+ if (page < jbi_current_page)
+ {
+ jbi_current_page = -1;
+ jbi_in_index = 4; /* skip over length field */
+ jbi_bits_avail = CHAR_BITS;
+ }
+
+ /* uncompress sequentially up to the desired page */
+ while (page > jbi_current_page)
+ {
+ jbi_uncompress_next_page(version);
+ }
+}
+
+#else
+
+/****************************************************************************/
+/* */
+
+unsigned long jbi_uncompress
+(
+ unsigned char *in,
+ unsigned long in_length,
+ unsigned char *out,
+ unsigned long out_length,
+ int version
+)
+
+/* */
+/* Description: Uncompress data in "in" and write result to "out". */
+/* */
+/* Returns: Length of uncompressed data. -1 if: */
+/* 1) out_length is too small */
+/* 2) Internal error in the code */
+/* 3) in doesn't contain ACA compressed data. */
+/* */
+/****************************************************************************/
+{
+ unsigned long i, j, data_length = 0L;
+ unsigned int offset, length;
+ unsigned int match_data_length = MATCH_DATA_LENGTH;
+
+ if (version > 0) --match_data_length;
+
+ jbi_in_length = in_length;
+ jbi_bits_avail = CHAR_BITS;
+ jbi_in_index = 0L;
+ for (i = 0; i < out_length; ++i) out[i] = 0;
+
+ /* Read number of bytes in data. */
+ for (i = 0; i < sizeof (in_length); ++i)
+ {
+ data_length = data_length | ((unsigned long)
+ jbi_read_packed(in, CHAR_BITS) << (i * CHAR_BITS));
+ }
+
+ if (data_length > out_length)
+ {
+ data_length = 0L;
+ }
+ else
+ {
+ i = 0;
+ while (i < data_length)
+ {
+ /* A 0 bit indicates literal data. */
+ if (jbi_read_packed(in, 1) == 0)
+ {
+ for (j = 0; j < DATA_BLOB_LENGTH; ++j)
+ {
+ if (i < data_length)
+ {
+ out[i] = (unsigned char) jbi_read_packed(in, CHAR_BITS);
+ i++;
+ }
+ }
+ }
+ else
+ {
+ /* A 1 bit indicates offset/length to follow. */
+ offset = jbi_read_packed(in, jbi_bits_required((short) (i > match_data_length ? match_data_length : i)));
+ length = jbi_read_packed(in, CHAR_BITS);
+
+ for (j = 0; j < length; ++j)
+ {
+ if (i < data_length)
+ {
+ out[i] = out[i - offset];
+ i++;
+ }
+ }
+ }
+ }
+ }
+
+ return (data_length);
+}
+
+#endif
diff --git a/common/recipes-utils/jbi/files/code/jbicomp.h b/common/recipes-utils/jbi/files/code/jbicomp.h
new file mode 100644
index 0000000..382995d
--- /dev/null
+++ b/common/recipes-utils/jbi/files/code/jbicomp.h
@@ -0,0 +1,37 @@
+/****************************************************************************/
+/* */
+/* Module: jbicomp.h */
+/* */
+/* Copyright (C) Altera Corporation 1997-2001 */
+/* */
+/* Description: Contains the function prototypes for compressing */
+/* and uncompressing Boolean array data. */
+/* */
+/****************************************************************************/
+
+#ifndef INC_JBICOMP_H
+#define INC_JBICOMP_H
+
+#if PORT==DOS
+
+void jbi_uncompress_page
+(
+ int variable_id,
+ int page,
+ int version
+);
+
+#else
+
+unsigned long jbi_uncompress
+(
+ unsigned char *in,
+ unsigned long in_length,
+ unsigned char *out,
+ unsigned long out_length,
+ int version
+);
+
+#endif /* PORT==DOS */
+
+#endif /* INC_JBICOMP_H */
diff --git a/common/recipes-utils/jbi/files/code/jbiexprt.h b/common/recipes-utils/jbi/files/code/jbiexprt.h
new file mode 100644
index 0000000..6d6a401
--- /dev/null
+++ b/common/recipes-utils/jbi/files/code/jbiexprt.h
@@ -0,0 +1,224 @@
+/****************************************************************************/
+/* */
+/* Module: jbiexprt.h */
+/* */
+/* Copyright (C) Altera Corporation 1998-2001 */
+/* */
+/* Description: Jam STAPL ByteCode Player Export Header File */
+/* */
+/* Revisions: */
+/* */
+/****************************************************************************/
+
+#ifndef INC_JBIEXPRT_H
+#define INC_JBIEXPRT_H
+
+/****************************************************************************/
+/* */
+/* Return codes from most JBI functions */
+/* */
+/****************************************************************************/
+
+#define JBI_RETURN_TYPE int
+
+#define JBIC_SUCCESS 0
+#define JBIC_OUT_OF_MEMORY 1
+#define JBIC_IO_ERROR 2
+/* #define JAMC_SYNTAX_ERROR 3 */
+#define JBIC_UNEXPECTED_END 4
+#define JBIC_UNDEFINED_SYMBOL 5
+/* #define JAMC_REDEFINED_SYMBOL 6 */
+#define JBIC_INTEGER_OVERFLOW 7
+#define JBIC_DIVIDE_BY_ZERO 8
+#define JBIC_CRC_ERROR 9
+#define JBIC_INTERNAL_ERROR 10
+#define JBIC_BOUNDS_ERROR 11
+/* #define JAMC_TYPE_MISMATCH 12 */
+/* #define JAMC_ASSIGN_TO_CONST 13 */
+/* #define JAMC_NEXT_UNEXPECTED 14 */
+/* #define JAMC_POP_UNEXPECTED 15 */
+/* #define JAMC_RETURN_UNEXPECTED 16 */
+/* #define JAMC_ILLEGAL_SYMBOL 17 */
+#define JBIC_VECTOR_MAP_FAILED 18
+#define JBIC_USER_ABORT 19
+#define JBIC_STACK_OVERFLOW 20
+#define JBIC_ILLEGAL_OPCODE 21
+/* #define JAMC_PHASE_ERROR 22 */
+/* #define JAMC_SCOPE_ERROR 23 */
+#define JBIC_ACTION_NOT_FOUND 24
+
+/****************************************************************************/
+/* */
+/* Macro Definitions */
+/* */
+/****************************************************************************/
+
+/*
+* For DOS port, program data is stored in a set of 16K pages, accessed
+* through a pointer table. For 32-bit version, the buffer is continuous.
+* The macro GET_BYTE gets a single byte for either case.
+*/
+#if PORT==DOS
+#define PROGRAM_PTR unsigned char **
+#else
+#define PROGRAM_PTR unsigned char *
+#endif
+
+#if PORT==DOS
+#define GET_BYTE(x) (jbi_program[(x) >> 14L][(x) & 0x3fffL])
+#else
+#define GET_BYTE(x) (program[x])
+#endif
+
+#define GET_WORD(x) \
+ (((((unsigned short) GET_BYTE(x)) << 8) & 0xFF00) | \
+ (((unsigned short) GET_BYTE((x)+1)) & 0x00FF))
+
+#define GET_DWORD(x) \
+ (((((unsigned long) GET_BYTE(x)) << 24L) & 0xFF000000L) | \
+ ((((unsigned long) GET_BYTE((x)+1)) << 16L) & 0x00FF0000L) | \
+ ((((unsigned long) GET_BYTE((x)+2)) << 8L) & 0x0000FF00L) | \
+ (((unsigned long) GET_BYTE((x)+3)) & 0x000000FFL))
+
+/****************************************************************************/
+/* */
+/* Structured Types */
+/* */
+/****************************************************************************/
+
+typedef struct JBI_PROCINFO_STRUCT
+{
+ char *name;
+ unsigned char attributes;
+ struct JBI_PROCINFO_STRUCT *next;
+}
+JBI_PROCINFO;
+
+/****************************************************************************/
+/* */
+/* Global Data Prototypes */
+/* */
+/****************************************************************************/
+
+#if PORT==DOS
+extern unsigned char jbi_aca_out_buffer[8192 + 1024];
+#endif
+
+extern PROGRAM_PTR jbi_program;
+
+extern char *jbi_workspace;
+
+extern long jbi_workspace_size;
+
+/****************************************************************************/
+/* */
+/* Function Prototypes */
+/* */
+/****************************************************************************/
+
+JBI_RETURN_TYPE jbi_execute
+(
+ PROGRAM_PTR program,
+ long program_size,
+ char *workspace,
+ long workspace_size,
+ char *action,
+ char **init_list,
+ int reset_jtag,
+ long *error_address,
+ int *exit_code,
+ int *format_version
+);
+
+JBI_RETURN_TYPE jbi_get_note
+(
+ PROGRAM_PTR program,
+ long program_size,
+ long *offset,
+ char *key,
+ char *value,
+ int length
+);
+
+JBI_RETURN_TYPE jbi_check_crc
+(
+ PROGRAM_PTR program,
+ long program_size,
+ unsigned short *expected_crc,
+ unsigned short *actual_crc
+);
+
+JBI_RETURN_TYPE jbi_get_file_info
+(
+ PROGRAM_PTR program,
+ long program_size,
+ int *format_version,
+ int *action_count,
+ int *procedure_count
+);
+
+JBI_RETURN_TYPE jbi_get_action_info
+(
+ PROGRAM_PTR program,
+ long program_size,
+ int index,
+ char **name,
+ char **description,
+ JBI_PROCINFO **procedure_list
+);
+
+int jbi_jtag_io
+(
+ int tms,
+ int tdi,
+ int read_tdo
+);
+
+void jbi_message
+(
+ char *message_text
+);
+
+void jbi_export_integer
+(
+ char *key,
+ long value
+);
+
+void jbi_export_boolean_array
+(
+ char *key,
+ unsigned char *data,
+ long count
+);
+
+void jbi_delay
+(
+ long microseconds
+);
+
+int jbi_vector_map
+(
+ int signal_count,
+ char **signals
+);
+
+int jbi_vector_io
+(
+ int signal_count,
+ long *dir_vect,
+ long *data_vect,
+ long *capture_vect
+);
+
+void *jbi_malloc
+(
+ unsigned int size
+);
+
+void jbi_free
+(
+ void *ptr
+);
+
+#endif /* INC_JBIEXPRT_H */
diff --git a/common/recipes-utils/jbi/files/code/jbijtag.c b/common/recipes-utils/jbi/files/code/jbijtag.c
new file mode 100644
index 0000000..728ab6a
--- /dev/null
+++ b/common/recipes-utils/jbi/files/code/jbijtag.c
@@ -0,0 +1,1675 @@
+/****************************************************************************/
+/* */
+/* Module: jbijtag.c */
+/* */
+/* Copyright (C) Altera Corporation 1998-2001 */
+/* */
+/* Description: Contains JTAG interface functions */
+/* */
+/* Revisions: 2.2 updated state transition paths */
+/* 2.0 added multi-page scan code for 16-bit PORT */
+/* */
+/****************************************************************************/
+
+#include "jbiport.h"
+#include "jbiexprt.h"
+#include "jbicomp.h"
+#include "jbijtag.h"
+
+#define NULL 0
+
+char *jbi_workspace = NULL;
+long jbi_workspace_size = 0L;
+
+/****************************************************************************/
+/* */
+/* Enumerated Types */
+/* */
+/****************************************************************************/
+
+/* maximum JTAG IR and DR lengths (in bits) */
+#define JBIC_MAX_JTAG_IR_PREAMBLE 256
+#define JBIC_MAX_JTAG_IR_POSTAMBLE 256
+#define JBIC_MAX_JTAG_IR_LENGTH 512
+#define JBIC_MAX_JTAG_DR_PREAMBLE 1024
+#define JBIC_MAX_JTAG_DR_POSTAMBLE 1024
+#define JBIC_MAX_JTAG_DR_LENGTH 2048
+
+/*
+* Global variable to store the current JTAG state
+*/
+JBIE_JTAG_STATE jbi_jtag_state = JBI_ILLEGAL_JTAG_STATE;
+
+/*
+* Store current stop-state for DR and IR scan commands
+*/
+JBIE_JTAG_STATE jbi_drstop_state = IDLE;
+JBIE_JTAG_STATE jbi_irstop_state = IDLE;
+
+/*
+* Store current padding values
+*/
+unsigned int jbi_dr_preamble = 0;
+unsigned int jbi_dr_postamble = 0;
+unsigned int jbi_ir_preamble = 0;
+unsigned int jbi_ir_postamble = 0;
+unsigned int jbi_dr_length = 0;
+unsigned int jbi_ir_length = 0;
+unsigned char *jbi_dr_preamble_data = NULL;
+unsigned char *jbi_dr_postamble_data = NULL;
+unsigned char *jbi_ir_preamble_data = NULL;
+unsigned char *jbi_ir_postamble_data = NULL;
+unsigned char *jbi_dr_buffer = NULL;
+unsigned char *jbi_ir_buffer = NULL;
+
+/*
+* This structure shows, for each JTAG state, which state is reached after
+* a single TCK clock cycle with TMS high or TMS low, respectively. This
+* describes all possible state transitions in the JTAG state machine.
+*/
+struct JBIS_JTAG_MACHINE
+{
+ JBIE_JTAG_STATE tms_high;
+ JBIE_JTAG_STATE tms_low;
+} jbi_jtag_state_transitions[] =
+{
+/* RESET */ { RESET, IDLE },
+/* IDLE */ { DRSELECT, IDLE },
+/* DRSELECT */ { IRSELECT, DRCAPTURE },
+/* DRCAPTURE */ { DREXIT1, DRSHIFT },
+/* DRSHIFT */ { DREXIT1, DRSHIFT },
+/* DREXIT1 */ { DRUPDATE, DRPAUSE },
+/* DRPAUSE */ { DREXIT2, DRPAUSE },
+/* DREXIT2 */ { DRUPDATE, DRSHIFT },
+/* DRUPDATE */ { DRSELECT, IDLE },
+/* IRSELECT */ { RESET, IRCAPTURE },
+/* IRCAPTURE */ { IREXIT1, IRSHIFT },
+/* IRSHIFT */ { IREXIT1, IRSHIFT },
+/* IREXIT1 */ { IRUPDATE, IRPAUSE },
+/* IRPAUSE */ { IREXIT2, IRPAUSE },
+/* IREXIT2 */ { IRUPDATE, IRSHIFT },
+/* IRUPDATE */ { DRSELECT, IDLE }
+};
+
+/*
+* This table contains the TMS value to be used to take the NEXT STEP on
+* the path to the desired state. The array index is the current state,
+* and the bit position is the desired endstate. To find out which state
+* is used as the intermediate state, look up the TMS value in the
+* jbi_jtag_state_transitions[] table.
+*/
+unsigned short jbi_jtag_path_map[16] =
+{
+/* RST RTI SDRS CDR SDR E1DR PDR E2DR */
+ 0x0001, 0xFFFD, 0xFE01, 0xFFE7, 0xFFEF, 0xFF0F, 0xFFBF, 0xFFFF,
+/* UDR SIRS CIR SIR E1IR PIR E2IR UIR */
+ 0xFEFD, 0x0001, 0xF3FF, 0xF7FF, 0x87FF, 0xDFFF, 0xFFFF, 0x7FFD
+};
+
+/*
+* Flag bits for jbi_jtag_io() function
+*/
+#define TMS_HIGH 1
+#define TMS_LOW 0
+#define TDI_HIGH 1
+#define TDI_LOW 0
+#define READ_TDO 1
+#define IGNORE_TDO 0
+
+/****************************************************************************/
+/* */
+
+JBI_RETURN_TYPE jbi_init_jtag()
+
+/* */
+/****************************************************************************/
+{
+ /* initial JTAG state is unknown */
+ jbi_jtag_state = JBI_ILLEGAL_JTAG_STATE;
+
+ /* initialize global variables to default state */
+ jbi_drstop_state = IDLE;
+ jbi_irstop_state = IDLE;
+ jbi_dr_preamble = 0;
+ jbi_dr_postamble = 0;
+ jbi_ir_preamble = 0;
+ jbi_ir_postamble = 0;
+ jbi_dr_length = 0;
+ jbi_ir_length = 0;
+
+ if (jbi_workspace != NULL)
+ {
+ jbi_dr_preamble_data = (unsigned char *) jbi_workspace;
+ jbi_dr_postamble_data = &jbi_dr_preamble_data[JBIC_MAX_JTAG_DR_PREAMBLE / 8];
+ jbi_ir_preamble_data = &jbi_dr_postamble_data[JBIC_MAX_JTAG_DR_POSTAMBLE / 8];
+ jbi_ir_postamble_data = &jbi_ir_preamble_data[JBIC_MAX_JTAG_IR_PREAMBLE / 8];
+ jbi_dr_buffer = &jbi_ir_postamble_data[JBIC_MAX_JTAG_IR_POSTAMBLE / 8];
+ jbi_ir_buffer = &jbi_dr_buffer[JBIC_MAX_JTAG_DR_LENGTH / 8];
+ }
+ else
+ {
+ jbi_dr_preamble_data = NULL;
+ jbi_dr_postamble_data = NULL;
+ jbi_ir_preamble_data = NULL;
+ jbi_ir_postamble_data = NULL;
+ jbi_dr_buffer = NULL;
+ jbi_ir_buffer = NULL;
+ }
+
+ return (JBIC_SUCCESS);
+}
+
+/****************************************************************************/
+/* */
+
+JBI_RETURN_TYPE jbi_set_drstop_state
+(
+ JBIE_JTAG_STATE state
+)
+
+/* */
+/****************************************************************************/
+{
+ jbi_drstop_state = state;
+
+ return (JBIC_SUCCESS);
+}
+
+/****************************************************************************/
+/* */
+
+JBI_RETURN_TYPE jbi_set_irstop_state
+(
+ JBIE_JTAG_STATE state
+)
+
+/* */
+/****************************************************************************/
+{
+ jbi_irstop_state = state;
+
+ return (JBIC_SUCCESS);
+}
+
+/****************************************************************************/
+/* */
+
+JBI_RETURN_TYPE jbi_set_dr_preamble
+(
+ unsigned int count,
+ unsigned int start_index,
+ unsigned char *preamble_data
+)
+
+/* */
+/****************************************************************************/
+{
+ JBI_RETURN_TYPE status = JBIC_SUCCESS;
+ unsigned int i;
+ unsigned int j;
+
+ if (jbi_workspace != NULL)
+ {
+ if (count > JBIC_MAX_JTAG_DR_PREAMBLE)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ jbi_dr_preamble = count;
+ }
+ }
+ else
+ {
+ if (count > jbi_dr_preamble)
+ {
+ jbi_free(jbi_dr_preamble_data);
+ jbi_dr_preamble_data = (unsigned char *) jbi_malloc((count + 7) >> 3);
+
+ if (jbi_dr_preamble_data == NULL)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ jbi_dr_preamble = count;
+ }
+ }
+ else
+ {
+ jbi_dr_preamble = count;
+ }
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ for (i = 0; i < count; ++i)
+ {
+ j = i + start_index;
+
+ if (preamble_data == NULL)
+ {
+ jbi_dr_preamble_data[i >> 3] |= (1 << (i & 7));
+ }
+ else
+ {
+ if (preamble_data[j >> 3] & (1 << (j & 7)))
+ {
+ jbi_dr_preamble_data[i >> 3] |= (1 << (i & 7));
+ }
+ else
+ {
+ jbi_dr_preamble_data[i >> 3] &=
+ ~(unsigned int) (1 << (i & 7));
+ }
+ }
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JBI_RETURN_TYPE jbi_set_ir_preamble
+(
+ unsigned int count,
+ unsigned int start_index,
+ unsigned char *preamble_data
+)
+
+/* */
+/****************************************************************************/
+{
+ JBI_RETURN_TYPE status = JBIC_SUCCESS;
+ unsigned int i;
+ unsigned int j;
+
+ if (jbi_workspace != NULL)
+ {
+ if (count > JBIC_MAX_JTAG_IR_PREAMBLE)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ jbi_ir_preamble = count;
+ }
+ }
+ else
+ {
+ if (count > jbi_ir_preamble)
+ {
+ jbi_free(jbi_ir_preamble_data);
+ jbi_ir_preamble_data = (unsigned char *) jbi_malloc((count + 7) >> 3);
+
+ if (jbi_ir_preamble_data == NULL)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ jbi_ir_preamble = count;
+ }
+ }
+ else
+ {
+ jbi_ir_preamble = count;
+ }
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ for (i = 0; i < count; ++i)
+ {
+ j = i + start_index;
+
+ if (preamble_data == NULL)
+ {
+ jbi_ir_preamble_data[i >> 3] |= (1 << (i & 7));
+ }
+ else
+ {
+ if (preamble_data[j >> 3] & (1 << (j & 7)))
+ {
+ jbi_ir_preamble_data[i >> 3] |= (1 << (i & 7));
+ }
+ else
+ {
+ jbi_ir_preamble_data[i >> 3] &=
+ ~(unsigned int) (1 << (i & 7));
+ }
+ }
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JBI_RETURN_TYPE jbi_set_dr_postamble
+(
+ unsigned int count,
+ unsigned int start_index,
+ unsigned char *postamble_data
+)
+
+/* */
+/****************************************************************************/
+{
+ JBI_RETURN_TYPE status = JBIC_SUCCESS;
+ unsigned int i;
+ unsigned int j;
+
+ if (jbi_workspace != NULL)
+ {
+ if (count > JBIC_MAX_JTAG_DR_POSTAMBLE)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ jbi_dr_postamble = count;
+ }
+ }
+ else
+ {
+ if (count > jbi_dr_postamble)
+ {
+ jbi_free(jbi_dr_postamble_data);
+ jbi_dr_postamble_data = (unsigned char *) jbi_malloc((count + 7) >> 3);
+
+ if (jbi_dr_postamble_data == NULL)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ jbi_dr_postamble = count;
+ }
+ }
+ else
+ {
+ jbi_dr_postamble = count;
+ }
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ for (i = 0; i < count; ++i)
+ {
+ j = i + start_index;
+
+ if (postamble_data == NULL)
+ {
+ jbi_dr_postamble_data[i >> 3] |= (1 << (i & 7));
+ }
+ else
+ {
+ if (postamble_data[j >> 3] & (1 << (j & 7)))
+ {
+ jbi_dr_postamble_data[i >> 3] |= (1 << (i & 7));
+ }
+ else
+ {
+ jbi_dr_postamble_data[i >> 3] &=
+ ~(unsigned int) (1 << (i & 7));
+ }
+ }
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JBI_RETURN_TYPE jbi_set_ir_postamble
+(
+ unsigned int count,
+ unsigned int start_index,
+ unsigned char *postamble_data
+)
+
+/* */
+/****************************************************************************/
+{
+ JBI_RETURN_TYPE status = JBIC_SUCCESS;
+ unsigned int i;
+ unsigned int j;
+
+ if (jbi_workspace != NULL)
+ {
+ if (count > JBIC_MAX_JTAG_IR_POSTAMBLE)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ jbi_ir_postamble = count;
+ }
+ }
+ else
+ {
+ if (count > jbi_ir_postamble)
+ {
+ jbi_free(jbi_ir_postamble_data);
+ jbi_ir_postamble_data = (unsigned char *) jbi_malloc((count + 7) >> 3);
+
+ if (jbi_ir_postamble_data == NULL)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ jbi_ir_postamble = count;
+ }
+ }
+ else
+ {
+ jbi_ir_postamble = count;
+ }
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ for (i = 0; i < count; ++i)
+ {
+ j = i + start_index;
+
+ if (postamble_data == NULL)
+ {
+ jbi_ir_postamble_data[i >> 3] |= (1 << (i & 7));
+ }
+ else
+ {
+ if (postamble_data[j >> 3] & (1 << (j & 7)))
+ {
+ jbi_ir_postamble_data[i >> 3] |= (1 << (i & 7));
+ }
+ else
+ {
+ jbi_ir_postamble_data[i >> 3] &=
+ ~(unsigned int) (1 << (i & 7));
+ }
+ }
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+void jbi_jtag_reset_idle(void)
+
+/* */
+/****************************************************************************/
+{
+ int i;
+
+ /*
+ * Go to Test Logic Reset (no matter what the starting state may be)
+ */
+ for (i = 0; i < 5; ++i)
+ {
+ jbi_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO);
+ }
+
+ /*
+ * Now step to Run Test / Idle
+ */
+ jbi_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO);
+
+ jbi_jtag_state = IDLE;
+}
+
+/****************************************************************************/
+/* */
+
+JBI_RETURN_TYPE jbi_goto_jtag_state
+(
+ JBIE_JTAG_STATE state
+)
+
+/* */
+/****************************************************************************/
+{
+ int tms;
+ int count = 0;
+ JBI_RETURN_TYPE status = JBIC_SUCCESS;
+
+ if (jbi_jtag_state == JBI_ILLEGAL_JTAG_STATE)
+ {
+ /* initialize JTAG chain to known state */
+ jbi_jtag_reset_idle();
+ }
+
+ if (jbi_jtag_state == state)
+ {
+ /*
+ * We are already in the desired state. If it is a stable state,
+ * loop here. Otherwise do nothing (no clock cycles).
+ */
+ if ((state == IDLE) ||
+ (state == DRSHIFT) ||
+ (state == DRPAUSE) ||
+ (state == IRSHIFT) ||
+ (state == IRPAUSE))
+ {
+ jbi_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO);
+ }
+ else if (state == RESET)
+ {
+ jbi_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO);
+ }
+ }
+ else
+ {
+ while ((jbi_jtag_state != state) && (count < 9))
+ {
+ /*
+ * Get TMS value to take a step toward desired state
+ */
+ tms = (jbi_jtag_path_map[jbi_jtag_state] & (1 << state)) ?
+ TMS_HIGH : TMS_LOW;
+
+ /*
+ * Take a step
+ */
+ jbi_jtag_io(tms, TDI_LOW, IGNORE_TDO);
+
+ if (tms)
+ {
+ jbi_jtag_state =
+ jbi_jtag_state_transitions[jbi_jtag_state].tms_high;
+ }
+ else
+ {
+ jbi_jtag_state =
+ jbi_jtag_state_transitions[jbi_jtag_state].tms_low;
+ }
+
+ ++count;
+ }
+ }
+
+ if (jbi_jtag_state != state)
+ {
+ status = JBIC_INTERNAL_ERROR;
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JBI_RETURN_TYPE jbi_do_wait_cycles
+(
+ long cycles,
+ JBIE_JTAG_STATE wait_state
+)
+
+/* */
+/* Description: Causes JTAG hardware to loop in the specified stable */
+/* state for the specified number of TCK clock cycles. */
+/* */
+/* Returns: JBIC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int tms;
+ long count;
+ JBI_RETURN_TYPE status = JBIC_SUCCESS;
+
+ if (jbi_jtag_state != wait_state)
+ {
+ status = jbi_goto_jtag_state(wait_state);
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ /*
+ * Set TMS high to loop in RESET state
+ * Set TMS low to loop in any other stable state
+ */
+ tms = (wait_state == RESET) ? TMS_HIGH : TMS_LOW;
+
+ for (count = 0L; count < cycles; count++)
+ {
+ jbi_jtag_io(tms, TDI_LOW, IGNORE_TDO);
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JBI_RETURN_TYPE jbi_do_wait_microseconds
+(
+ long microseconds,
+ JBIE_JTAG_STATE wait_state
+)
+
+/* */
+/* Description: Causes JTAG hardware to sit in the specified stable */
+/* state for the specified duration of real time. If */
+/* no JTAG operations have been performed yet, then only */
+/* a delay is performed. This permits the WAIT USECS */
+/* statement to be used in VECTOR programs without causing */
+/* any JTAG operations. */
+/* */
+/* Returns: JBIC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ JBI_RETURN_TYPE status = JBIC_SUCCESS;
+
+ if ((jbi_jtag_state != JBI_ILLEGAL_JTAG_STATE) &&
+ (jbi_jtag_state != wait_state))
+ {
+ status = jbi_goto_jtag_state(wait_state);
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ /*
+ * Wait for specified time interval
+ */
+ jbi_delay(microseconds);
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+void jbi_jtag_concatenate_data
+(
+ unsigned char *buffer,
+ unsigned char *preamble_data,
+ unsigned int preamble_count,
+ unsigned char *target_data,
+ unsigned long start_index,
+ unsigned int target_count,
+ unsigned char *postamble_data,
+ unsigned int postamble_count
+)
+
+/* */
+/* Description: Copies preamble data, target data, and postamble data */
+/* into one buffer for IR or DR scans. */
+/* */
+/* Returns: nothing */
+/* */
+/****************************************************************************/
+{
+ unsigned long i;
+ unsigned long j;
+ unsigned long k;
+
+ for (i = 0L; i < preamble_count; ++i)
+ {
+ if (preamble_data[i >> 3L] & (1L << (i & 7L)))
+ {
+ buffer[i >> 3L] |= (1L << (i & 7L));
+ }
+ else
+ {
+ buffer[i >> 3L] &= ~(unsigned int) (1L << (i & 7L));
+ }
+ }
+
+ j = start_index;
+ k = preamble_count + target_count;
+ for (; i < k; ++i, ++j)
+ {
+ if (target_data[j >> 3L] & (1L << (j & 7L)))
+ {
+ buffer[i >> 3L] |= (1L << (i & 7L));
+ }
+ else
+ {
+ buffer[i >> 3L] &= ~(unsigned int) (1L << (i & 7L));
+ }
+ }
+
+ j = 0L;
+ k = preamble_count + target_count + postamble_count;
+ for (; i < k; ++i, ++j)
+ {
+ if (postamble_data[j >> 3L] & (1L << (j & 7L)))
+ {
+ buffer[i >> 3L] |= (1L << (i & 7L));
+ }
+ else
+ {
+ buffer[i >> 3L] &= ~(unsigned int) (1L << (i & 7L));
+ }
+ }
+}
+
+int jbi_jtag_drscan
+(
+ int start_state,
+ int count,
+ unsigned char *tdi,
+ unsigned char *tdo
+)
+{
+ int i = 0;
+ int tdo_bit = 0;
+ int status = 1;
+
+ /*
+ * First go to DRSHIFT state
+ */
+ switch (start_state)
+ {
+ case 0: /* IDLE */
+ jbi_jtag_io(1, 0, 0); /* DRSELECT */
+ jbi_jtag_io(0, 0, 0); /* DRCAPTURE */
+ jbi_jtag_io(0, 0, 0); /* DRSHIFT */
+ break;
+
+ case 1: /* DRPAUSE */
+ jbi_jtag_io(1, 0, 0); /* DREXIT2 */
+ jbi_jtag_io(1, 0, 0); /* DRUPDATE */
+ jbi_jtag_io(1, 0, 0); /* DRSELECT */
+ jbi_jtag_io(0, 0, 0); /* DRCAPTURE */
+ jbi_jtag_io(0, 0, 0); /* DRSHIFT */
+ break;
+
+ case 2: /* IRPAUSE */
+ jbi_jtag_io(1, 0, 0); /* IREXIT2 */
+ jbi_jtag_io(1, 0, 0); /* IRUPDATE */
+ jbi_jtag_io(1, 0, 0); /* DRSELECT */
+ jbi_jtag_io(0, 0, 0); /* DRCAPTURE */
+ jbi_jtag_io(0, 0, 0); /* DRSHIFT */
+ break;
+
+ default:
+ status = 0;
+ }
+
+ if (status)
+ {
+ /* loop in the SHIFT-DR state */
+ for (i = 0; i < count; i++)
+ {
+ tdo_bit = jbi_jtag_io(
+ (i == count - 1),
+ tdi[i >> 3] & (1 << (i & 7)),
+ (tdo != NULL));
+
+ if (tdo != NULL)
+ {
+ if (tdo_bit)
+ {
+ tdo[i >> 3] |= (1 << (i & 7));
+ }
+ else
+ {
+ tdo[i >> 3] &= ~(unsigned int) (1 << (i & 7));
+ }
+ }
+ }
+
+ jbi_jtag_io(0, 0, 0); /* DRPAUSE */
+ }
+
+ return (status);
+}
+
+int jbi_jtag_irscan
+(
+ int start_state,
+ int count,
+ unsigned char *tdi,
+ unsigned char *tdo
+)
+{
+ int i = 0;
+ int tdo_bit = 0;
+ int status = 1;
+
+ /*
+ * First go to IRSHIFT state
+ */
+ switch (start_state)
+ {
+ case 0: /* IDLE */
+ jbi_jtag_io(1, 0, 0); /* DRSELECT */
+ jbi_jtag_io(1, 0, 0); /* IRSELECT */
+ jbi_jtag_io(0, 0, 0); /* IRCAPTURE */
+ jbi_jtag_io(0, 0, 0); /* IRSHIFT */
+ break;
+
+ case 1: /* DRPAUSE */
+ jbi_jtag_io(1, 0, 0); /* DREXIT2 */
+ jbi_jtag_io(1, 0, 0); /* DRUPDATE */
+ jbi_jtag_io(1, 0, 0); /* DRSELECT */
+ jbi_jtag_io(1, 0, 0); /* IRSELECT */
+ jbi_jtag_io(0, 0, 0); /* IRCAPTURE */
+ jbi_jtag_io(0, 0, 0); /* IRSHIFT */
+ break;
+
+ case 2: /* IRPAUSE */
+ jbi_jtag_io(1, 0, 0); /* IREXIT2 */
+ jbi_jtag_io(1, 0, 0); /* IRUPDATE */
+ jbi_jtag_io(1, 0, 0); /* DRSELECT */
+ jbi_jtag_io(1, 0, 0); /* IRSELECT */
+ jbi_jtag_io(0, 0, 0); /* IRCAPTURE */
+ jbi_jtag_io(0, 0, 0); /* IRSHIFT */
+ break;
+
+ default:
+ status = 0;
+ }
+
+ if (status)
+ {
+ /* loop in the SHIFT-IR state */
+ for (i = 0; i < count; i++)
+ {
+ tdo_bit = jbi_jtag_io(
+ (i == count - 1),
+ tdi[i >> 3] & (1 << (i & 7)),
+ (tdo != NULL));
+
+ if (tdo != NULL)
+ {
+ if (tdo_bit)
+ {
+ tdo[i >> 3] |= (1 << (i & 7));
+ }
+ else
+ {
+ tdo[i >> 3] &= ~(unsigned int) (1 << (i & 7));
+ }
+ }
+ }
+
+ jbi_jtag_io(0, 0, 0); /* IRPAUSE */
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+void jbi_jtag_extract_target_data
+(
+ unsigned char *buffer,
+ unsigned char *target_data,
+ unsigned int start_index,
+ unsigned int preamble_count,
+ unsigned int target_count
+)
+
+/* */
+/* Description: Copies target data from scan buffer, filtering out */
+/* preamble and postamble data. */
+/* */
+/* Returns: nothing */
+/* */
+/****************************************************************************/
+{
+ unsigned int i;
+ unsigned int j;
+ unsigned int k;
+
+ j = preamble_count;
+ k = start_index + target_count;
+ for (i = start_index; i < k; ++i, ++j)
+ {
+ if (buffer[j >> 3] & (1 << (j & 7)))
+ {
+ target_data[i >> 3] |= (1 << (i & 7));
+ }
+ else
+ {
+ target_data[i >> 3] &= ~(unsigned int) (1 << (i & 7));
+ }
+ }
+}
+
+/****************************************************************************/
+/* */
+
+JBI_RETURN_TYPE jbi_do_irscan
+(
+ unsigned int count,
+ unsigned char *tdi_data,
+ unsigned int start_index
+)
+
+/* */
+/* Description: Shifts data into instruction register */
+/* */
+/* Returns: JBIC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int start_code = 0;
+ unsigned int alloc_chars = 0;
+ unsigned int shift_count = jbi_ir_preamble + count + jbi_ir_postamble;
+ JBI_RETURN_TYPE status = JBIC_SUCCESS;
+ JBIE_JTAG_STATE start_state = JBI_ILLEGAL_JTAG_STATE;
+
+ switch (jbi_jtag_state)
+ {
+ case JBI_ILLEGAL_JTAG_STATE:
+ case RESET:
+ case IDLE:
+ start_code = 0;
+ start_state = IDLE;
+ break;
+
+ case DRSELECT:
+ case DRCAPTURE:
+ case DRSHIFT:
+ case DREXIT1:
+ case DRPAUSE:
+ case DREXIT2:
+ case DRUPDATE:
+ start_code = 1;
+ start_state = DRPAUSE;
+ break;
+
+ case IRSELECT:
+ case IRCAPTURE:
+ case IRSHIFT:
+ case IREXIT1:
+ case IRPAUSE:
+ case IREXIT2:
+ case IRUPDATE:
+ start_code = 2;
+ start_state = IRPAUSE;
+ break;
+
+ default:
+ status = JBIC_INTERNAL_ERROR;
+ break;
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ if (jbi_jtag_state != start_state)
+ {
+ status = jbi_goto_jtag_state(start_state);
+ }
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ if (jbi_workspace != NULL)
+ {
+ if (shift_count > JBIC_MAX_JTAG_IR_LENGTH)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ }
+ }
+ else if (shift_count > jbi_ir_length)
+ {
+ alloc_chars = (shift_count + 7) >> 3;
+ jbi_free(jbi_ir_buffer);
+ jbi_ir_buffer = (unsigned char *) jbi_malloc(alloc_chars);
+
+ if (jbi_ir_buffer == NULL)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ jbi_ir_length = alloc_chars * 8;
+ }
+ }
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ /*
+ * Copy preamble data, IR data, and postamble data into a buffer
+ */
+ jbi_jtag_concatenate_data
+ (
+ jbi_ir_buffer,
+ jbi_ir_preamble_data,
+ jbi_ir_preamble,
+ tdi_data,
+ start_index,
+ count,
+ jbi_ir_postamble_data,
+ jbi_ir_postamble
+ );
+
+ /*
+ * Do the IRSCAN
+ */
+ jbi_jtag_irscan
+ (
+ start_code,
+ shift_count,
+ jbi_ir_buffer,
+ NULL
+ );
+
+ /* jbi_jtag_irscan() always ends in IRPAUSE state */
+ jbi_jtag_state = IRPAUSE;
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ if (jbi_irstop_state != IRPAUSE)
+ {
+ status = jbi_goto_jtag_state(jbi_irstop_state);
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JBI_RETURN_TYPE jbi_swap_ir
+(
+ unsigned int count,
+ unsigned char *in_data,
+ unsigned int in_index,
+ unsigned char *out_data,
+ unsigned int out_index
+)
+
+/* */
+/* Description: Shifts data into instruction register, capturing output */
+/* data */
+/* */
+/* Returns: JBIC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int start_code = 0;
+ unsigned int alloc_chars = 0;
+ unsigned int shift_count = jbi_ir_preamble + count + jbi_ir_postamble;
+ JBI_RETURN_TYPE status = JBIC_SUCCESS;
+ JBIE_JTAG_STATE start_state = JBI_ILLEGAL_JTAG_STATE;
+
+ switch (jbi_jtag_state)
+ {
+ case JBI_ILLEGAL_JTAG_STATE:
+ case RESET:
+ case IDLE:
+ start_code = 0;
+ start_state = IDLE;
+ break;
+
+ case DRSELECT:
+ case DRCAPTURE:
+ case DRSHIFT:
+ case DREXIT1:
+ case DRPAUSE:
+ case DREXIT2:
+ case DRUPDATE:
+ start_code = 1;
+ start_state = DRPAUSE;
+ break;
+
+ case IRSELECT:
+ case IRCAPTURE:
+ case IRSHIFT:
+ case IREXIT1:
+ case IRPAUSE:
+ case IREXIT2:
+ case IRUPDATE:
+ start_code = 2;
+ start_state = IRPAUSE;
+ break;
+
+ default:
+ status = JBIC_INTERNAL_ERROR;
+ break;
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ if (jbi_jtag_state != start_state)
+ {
+ status = jbi_goto_jtag_state(start_state);
+ }
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ if (jbi_workspace != NULL)
+ {
+ if (shift_count > JBIC_MAX_JTAG_IR_LENGTH)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ }
+ }
+ else if (shift_count > jbi_ir_length)
+ {
+ alloc_chars = (shift_count + 7) >> 3;
+ jbi_free(jbi_ir_buffer);
+ jbi_ir_buffer = (unsigned char *) jbi_malloc(alloc_chars);
+
+ if (jbi_ir_buffer == NULL)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ jbi_ir_length = alloc_chars * 8;
+ }
+ }
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ /*
+ * Copy preamble data, IR data, and postamble data into a buffer
+ */
+ jbi_jtag_concatenate_data
+ (
+ jbi_ir_buffer,
+ jbi_ir_preamble_data,
+ jbi_ir_preamble,
+ in_data,
+ in_index,
+ count,
+ jbi_ir_postamble_data,
+ jbi_ir_postamble
+ );
+
+ /*
+ * Do the IRSCAN
+ */
+ jbi_jtag_irscan
+ (
+ start_code,
+ shift_count,
+ jbi_ir_buffer,
+ jbi_ir_buffer
+ );
+
+ /* jbi_jtag_irscan() always ends in IRPAUSE state */
+ jbi_jtag_state = IRPAUSE;
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ if (jbi_irstop_state != IRPAUSE)
+ {
+ status = jbi_goto_jtag_state(jbi_irstop_state);
+ }
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ /*
+ * Now extract the returned data from the buffer
+ */
+ jbi_jtag_extract_target_data
+ (
+ jbi_ir_buffer,
+ out_data,
+ out_index,
+ jbi_ir_preamble,
+ count
+ );
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JBI_RETURN_TYPE jbi_do_drscan
+(
+ unsigned int count,
+ unsigned char *tdi_data,
+ unsigned long start_index
+)
+
+/* */
+/* Description: Shifts data into data register (ignoring output data) */
+/* */
+/* Returns: JBIC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int start_code = 0;
+ unsigned int alloc_chars = 0;
+ unsigned int shift_count = jbi_dr_preamble + count + jbi_dr_postamble;
+ JBI_RETURN_TYPE status = JBIC_SUCCESS;
+ JBIE_JTAG_STATE start_state = JBI_ILLEGAL_JTAG_STATE;
+
+ switch (jbi_jtag_state)
+ {
+ case JBI_ILLEGAL_JTAG_STATE:
+ case RESET:
+ case IDLE:
+ start_code = 0;
+ start_state = IDLE;
+ break;
+
+ case DRSELECT:
+ case DRCAPTURE:
+ case DRSHIFT:
+ case DREXIT1:
+ case DRPAUSE:
+ case DREXIT2:
+ case DRUPDATE:
+ start_code = 1;
+ start_state = DRPAUSE;
+ break;
+
+ case IRSELECT:
+ case IRCAPTURE:
+ case IRSHIFT:
+ case IREXIT1:
+ case IRPAUSE:
+ case IREXIT2:
+ case IRUPDATE:
+ start_code = 2;
+ start_state = IRPAUSE;
+ break;
+
+ default:
+ status = JBIC_INTERNAL_ERROR;
+ break;
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ if (jbi_jtag_state != start_state)
+ {
+ status = jbi_goto_jtag_state(start_state);
+ }
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ if (jbi_workspace != NULL)
+ {
+ if (shift_count > JBIC_MAX_JTAG_DR_LENGTH)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ }
+ }
+ else if (shift_count > jbi_dr_length)
+ {
+ alloc_chars = (shift_count + 7) >> 3;
+ jbi_free(jbi_dr_buffer);
+ jbi_dr_buffer = (unsigned char *) jbi_malloc(alloc_chars);
+
+ if (jbi_dr_buffer == NULL)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ jbi_dr_length = alloc_chars * 8;
+ }
+ }
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ /*
+ * Copy preamble data, DR data, and postamble data into a buffer
+ */
+ jbi_jtag_concatenate_data
+ (
+ jbi_dr_buffer,
+ jbi_dr_preamble_data,
+ jbi_dr_preamble,
+ tdi_data,
+ start_index,
+ count,
+ jbi_dr_postamble_data,
+ jbi_dr_postamble
+ );
+
+ /*
+ * Do the DRSCAN
+ */
+ jbi_jtag_drscan
+ (
+ start_code,
+ shift_count,
+ jbi_dr_buffer,
+ NULL
+ );
+
+ /* jbi_jtag_drscan() always ends in DRPAUSE state */
+ jbi_jtag_state = DRPAUSE;
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ if (jbi_drstop_state != DRPAUSE)
+ {
+ status = jbi_goto_jtag_state(jbi_drstop_state);
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JBI_RETURN_TYPE jbi_swap_dr
+(
+ unsigned int count,
+ unsigned char *in_data,
+ unsigned long in_index,
+ unsigned char *out_data,
+ unsigned int out_index
+)
+
+/* */
+/* Description: Shifts data into data register, capturing output data */
+/* */
+/* Returns: JBIC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int start_code = 0;
+ unsigned int alloc_chars = 0;
+ unsigned int shift_count = jbi_dr_preamble + count + jbi_dr_postamble;
+ JBI_RETURN_TYPE status = JBIC_SUCCESS;
+ JBIE_JTAG_STATE start_state = JBI_ILLEGAL_JTAG_STATE;
+
+ switch (jbi_jtag_state)
+ {
+ case JBI_ILLEGAL_JTAG_STATE:
+ case RESET:
+ case IDLE:
+ start_code = 0;
+ start_state = IDLE;
+ break;
+
+ case DRSELECT:
+ case DRCAPTURE:
+ case DRSHIFT:
+ case DREXIT1:
+ case DRPAUSE:
+ case DREXIT2:
+ case DRUPDATE:
+ start_code = 1;
+ start_state = DRPAUSE;
+ break;
+
+ case IRSELECT:
+ case IRCAPTURE:
+ case IRSHIFT:
+ case IREXIT1:
+ case IRPAUSE:
+ case IREXIT2:
+ case IRUPDATE:
+ start_code = 2;
+ start_state = IRPAUSE;
+ break;
+
+ default:
+ status = JBIC_INTERNAL_ERROR;
+ break;
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ if (jbi_jtag_state != start_state)
+ {
+ status = jbi_goto_jtag_state(start_state);
+ }
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ if (jbi_workspace != NULL)
+ {
+ if (shift_count > JBIC_MAX_JTAG_DR_LENGTH)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ }
+ }
+ else if (shift_count > jbi_dr_length)
+ {
+ alloc_chars = (shift_count + 7) >> 3;
+ jbi_free(jbi_dr_buffer);
+ jbi_dr_buffer = (unsigned char *) jbi_malloc(alloc_chars);
+
+ if (jbi_dr_buffer == NULL)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ jbi_dr_length = alloc_chars * 8;
+ }
+ }
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ /*
+ * Copy preamble data, DR data, and postamble data into a buffer
+ */
+ jbi_jtag_concatenate_data
+ (
+ jbi_dr_buffer,
+ jbi_dr_preamble_data,
+ jbi_dr_preamble,
+ in_data,
+ in_index,
+ count,
+ jbi_dr_postamble_data,
+ jbi_dr_postamble
+ );
+
+ /*
+ * Do the DRSCAN
+ */
+ jbi_jtag_drscan
+ (
+ start_code,
+ shift_count,
+ jbi_dr_buffer,
+ jbi_dr_buffer
+ );
+
+ /* jbi_jtag_drscan() always ends in DRPAUSE state */
+ jbi_jtag_state = DRPAUSE;
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ if (jbi_drstop_state != DRPAUSE)
+ {
+ status = jbi_goto_jtag_state(jbi_drstop_state);
+ }
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ /*
+ * Now extract the returned data from the buffer
+ */
+ jbi_jtag_extract_target_data
+ (
+ jbi_dr_buffer,
+ out_data,
+ out_index,
+ jbi_dr_preamble,
+ count
+ );
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+void jbi_free_jtag_padding_buffers(int reset_jtag)
+
+/* */
+/* Description: Frees memory allocated for JTAG IR and DR buffers */
+/* */
+/* Returns: nothing */
+/* */
+/****************************************************************************/
+{
+ /*
+ * If the JTAG interface was used, reset it to TLR
+ */
+ if (reset_jtag && (jbi_jtag_state != JBI_ILLEGAL_JTAG_STATE))
+ {
+ jbi_jtag_reset_idle();
+ }
+
+ if (jbi_workspace == NULL)
+ {
+ if (jbi_dr_preamble_data != NULL)
+ {
+ jbi_free(jbi_dr_preamble_data);
+ jbi_dr_preamble_data = NULL;
+ }
+
+ if (jbi_dr_postamble_data != NULL)
+ {
+ jbi_free(jbi_dr_postamble_data);
+ jbi_dr_postamble_data = NULL;
+ }
+
+ if (jbi_dr_buffer != NULL)
+ {
+ jbi_free(jbi_dr_buffer);
+ jbi_dr_buffer = NULL;
+ }
+
+ if (jbi_ir_preamble_data != NULL)
+ {
+ jbi_free(jbi_ir_preamble_data);
+ jbi_ir_preamble_data = NULL;
+ }
+
+ if (jbi_ir_postamble_data != NULL)
+ {
+ jbi_free(jbi_ir_postamble_data);
+ jbi_ir_postamble_data = NULL;
+ }
+
+ if (jbi_ir_buffer != NULL)
+ {
+ jbi_free(jbi_ir_buffer);
+ jbi_ir_buffer = NULL;
+ }
+ }
+}
+
+#if PORT==DOS
+
+/****************************************************************************/
+/* */
+
+JBI_RETURN_TYPE jbi_do_drscan_multi_page
+(
+ unsigned int variable_id,
+ unsigned long count,
+ unsigned long start_index,
+ int version
+)
+
+/* */
+/* Description: Shifts data into data register (ignoring output data) */
+/* Scan data comes from compressed Boolean array. */
+/* */
+/* Returns: JBIC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ JBI_RETURN_TYPE status = JBIC_SUCCESS;
+ unsigned long shift_count = jbi_dr_preamble + count + jbi_dr_postamble;
+ unsigned long i;
+ unsigned long j;
+ unsigned long k;
+ unsigned int bi;
+
+
+ if (status == JBIC_SUCCESS)
+ {
+ status = jbi_goto_jtag_state(DRSHIFT);
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ /*
+ * Get preamble data, DR data, and postamble data one bit at a time
+ * and immediately scan it into the JTAG chain
+ */
+
+ for (i = 0L; i < jbi_dr_preamble; ++i)
+ {
+ jbi_jtag_io((i == shift_count - 1),
+ (int) (jbi_dr_preamble_data[i >> 3L] & (1L << (i & 7L))), 0);
+ }
+
+ j = start_index;
+ k = jbi_dr_preamble + count;
+
+ jbi_uncompress_page(variable_id, (unsigned int) (j >> 16L), version);
+
+ for (; i < k; ++i, ++j)
+ {
+ bi = (unsigned int) (j & 0x0000ffffL);
+
+ /* check for page boundary - load next page if necessary */
+ if (bi == 0)
+ {
+ jbi_uncompress_page(variable_id, (unsigned int) (j >> 16L), version);
+ }
+
+ jbi_jtag_io((i == shift_count - 1),
+ (int) (jbi_aca_out_buffer[bi >> 3] & (1 << (bi & 7))), 0);
+ }
+
+ j = 0L;
+ k = jbi_dr_preamble + count + jbi_dr_postamble;
+ for (; i < k; ++i, ++j)
+ {
+ jbi_jtag_io((i == shift_count - 1),
+ (int) (jbi_dr_postamble_data[j >> 3L] & (1L << (j & 7L))), 0);
+ }
+
+ jbi_jtag_io(0, 0, 0); /* DRPAUSE */
+
+
+ /* jbi_jtag_drscan() always ends in DRPAUSE state */
+ jbi_jtag_state = DRPAUSE;
+
+ if (jbi_drstop_state != DRPAUSE)
+ {
+ status = jbi_goto_jtag_state(jbi_drstop_state);
+ }
+ }
+
+ return (status);
+}
+
+#endif
diff --git a/common/recipes-utils/jbi/files/code/jbijtag.h b/common/recipes-utils/jbi/files/code/jbijtag.h
new file mode 100644
index 0000000..27299f0
--- /dev/null
+++ b/common/recipes-utils/jbi/files/code/jbijtag.h
@@ -0,0 +1,147 @@
+/****************************************************************************/
+/* */
+/* Module: jbijtag.h */
+/* */
+/* Copyright (C) Altera Corporation 1998-2001 */
+/* */
+/* Description: Definitions of JTAG constants, types, and functions */
+/* */
+/****************************************************************************/
+
+#ifndef INC_JBIJTAG_H
+#define INC_JBIJTAG_H
+
+/****************************************************************************/
+/* */
+/* Function Prototypes */
+/* */
+/****************************************************************************/
+typedef enum
+{
+ JBI_ILLEGAL_JTAG_STATE = -1,
+ RESET = 0,
+ IDLE = 1,
+ DRSELECT = 2,
+ DRCAPTURE = 3,
+ DRSHIFT = 4,
+ DREXIT1 = 5,
+ DRPAUSE = 6,
+ DREXIT2 = 7,
+ DRUPDATE = 8,
+ IRSELECT = 9,
+ IRCAPTURE = 10,
+ IRSHIFT = 11,
+ IREXIT1 = 12,
+ IRPAUSE = 13,
+ IREXIT2 = 14,
+ IRUPDATE = 15
+
+} JBIE_JTAG_STATE;
+
+
+JBI_RETURN_TYPE jbi_init_jtag
+(
+ void
+);
+
+JBI_RETURN_TYPE jbi_set_drstop_state
+(
+ JBIE_JTAG_STATE state
+);
+
+JBI_RETURN_TYPE jbi_set_irstop_state
+(
+ JBIE_JTAG_STATE state
+);
+
+JBI_RETURN_TYPE jbi_set_dr_preamble
+(
+ unsigned int count,
+ unsigned int start_index,
+ unsigned char *preamble_data
+);
+
+JBI_RETURN_TYPE jbi_set_ir_preamble
+(
+ unsigned int count,
+ unsigned int start_index,
+ unsigned char *preamble_data
+);
+
+JBI_RETURN_TYPE jbi_set_dr_postamble
+(
+ unsigned int count,
+ unsigned int start_index,
+ unsigned char *postamble_data
+);
+
+JBI_RETURN_TYPE jbi_set_ir_postamble
+(
+ unsigned int count,
+ unsigned int start_index,
+ unsigned char *postamble_data
+);
+
+JBI_RETURN_TYPE jbi_goto_jtag_state
+(
+ JBIE_JTAG_STATE state
+);
+
+JBI_RETURN_TYPE jbi_do_wait_cycles
+(
+ long cycles,
+ JBIE_JTAG_STATE wait_state
+);
+
+JBI_RETURN_TYPE jbi_do_wait_microseconds
+(
+ long microseconds,
+ JBIE_JTAG_STATE wait_state
+);
+
+JBI_RETURN_TYPE jbi_do_irscan
+(
+ unsigned int count,
+ unsigned char *tdi_data,
+ unsigned int start_index
+);
+
+JBI_RETURN_TYPE jbi_swap_ir
+(
+ unsigned int count,
+ unsigned char *in_data,
+ unsigned int in_index,
+ unsigned char *out_data,
+ unsigned int out_index
+);
+
+JBI_RETURN_TYPE jbi_do_drscan
+(
+ unsigned int count,
+ unsigned char *tdi_data,
+ unsigned long start_index
+);
+
+JBI_RETURN_TYPE jbi_swap_dr
+(
+ unsigned int count,
+ unsigned char *in_data,
+ unsigned long in_index,
+ unsigned char *out_data,
+ unsigned int out_index
+);
+
+void jbi_free_jtag_padding_buffers
+(
+ int reset_jtag
+);
+
+JBI_RETURN_TYPE jbi_do_drscan_multi_page
+(
+ unsigned int variable_id,
+ unsigned long long_count,
+ unsigned long long_index,
+ int version
+);
+
+#endif /* INC_JBIJTAG_H */
diff --git a/common/recipes-utils/jbi/files/code/jbimain.c b/common/recipes-utils/jbi/files/code/jbimain.c
new file mode 100644
index 0000000..79bdf69
--- /dev/null
+++ b/common/recipes-utils/jbi/files/code/jbimain.c
@@ -0,0 +1,3290 @@
+/****************************************************************************/
+/* */
+/* Module: jbimain.c */
+/* */
+/* Copyright (C) Altera Corporation 1998-2001 */
+/* */
+/* Description: Jam STAPL ByteCode Player (Interpreter) */
+/* */
+/* Revisions: 2.2 fixed /W4 warnings */
+/* 2.0 added support for STAPL ByteCode format */
+/* */
+/****************************************************************************/
+
+#include "jbiport.h"
+#include "jbiexprt.h"
+#include "jbijtag.h"
+#include "jbicomp.h"
+
+/****************************************************************************/
+/* */
+/* MACROS */
+/* */
+/****************************************************************************/
+
+#define NULL 0
+
+#define JBI_STACK_SIZE 128
+
+#define JBIC_MESSAGE_LENGTH 1024
+
+/*
+* This macro checks if enough parameters are available on the stack. The
+* argument is the number of parameters needed.
+*/
+#define IF_CHECK_STACK(x) \
+ if (stack_ptr < (int) (x)) \
+ { \
+ status = JBIC_STACK_OVERFLOW; \
+ } \
+ else
+
+/*
+* This macro checks if a code address is inside the code section
+*/
+#define CHECK_PC \
+ if ((pc < code_section) || (pc >= debug_section)) \
+ { \
+ status = JBIC_BOUNDS_ERROR; \
+ }
+
+/****************************************************************************/
+/* */
+/* GLOBAL VARIABLES */
+/* */
+/****************************************************************************/
+
+#if PORT==DOS
+/*
+* jbi_program is a global pointer used by macros GET_BYTE, GET_WORD, and
+* GET_DWORD to read data from the JBC file
+*/
+PROGRAM_PTR jbi_program;
+#endif
+
+/****************************************************************************/
+/* */
+/* UTILITY FUNCTIONS */
+/* */
+/****************************************************************************/
+
+int jbi_strlen(char *string)
+{
+ int len = 0;
+
+ while (string[len] != '\0') ++len;
+
+ return (len);
+}
+
+long jbi_atol(char *buffer)
+{
+ long result = 0L;
+ int index = 0;
+
+ while ((buffer[index] >= '0') && (buffer[index] <= '9'))
+ {
+ result = (result * 10) + (buffer[index] - '0');
+ ++index;
+ }
+
+ return (result);
+}
+
+void jbi_ltoa(char *buffer, long number)
+{
+ int index = 0;
+ int rev_index = 0;
+ char reverse[32];
+
+ if (number < 0L)
+ {
+ buffer[index++] = '-';
+ number = 0 - number;
+ }
+ else if (number == 0)
+ {
+ buffer[index++] = '0';
+ }
+
+ while (number != 0)
+ {
+ reverse[rev_index++] = (char) ((number % 10) + '0');
+ number /= 10;
+ }
+
+ while (rev_index > 0)
+ {
+ buffer[index++] = reverse[--rev_index];
+ }
+
+ buffer[index] = '\0';
+}
+
+char jbi_toupper(char ch)
+{
+ return ((char) (((ch >= 'a') && (ch <= 'z')) ? (ch + 'A' - 'a') : ch));
+}
+
+int jbi_stricmp(char *left, char *right)
+{
+ int result = 0;
+ char l, r;
+
+ do
+ {
+ l = jbi_toupper(*left);
+ r = jbi_toupper(*right);
+ result = l - r;
+ ++left;
+ ++right;
+ }
+ while ((result == 0) && (l != '\0') && (r != '\0'));
+
+ return (result);
+}
+
+void jbi_strncpy(char *left, char *right, int count)
+{
+ char ch;
+
+ do
+ {
+ *left = *right;
+ ch = *right;
+ ++left;
+ ++right;
+ --count;
+ }
+ while ((ch != '\0') && (count != 0));
+}
+
+void jbi_make_dword(unsigned char *buf, unsigned long num)
+{
+ buf[0] = (unsigned char) num;
+ buf[1] = (unsigned char) (num >> 8L);
+ buf[2] = (unsigned char) (num >> 16L);
+ buf[3] = (unsigned char) (num >> 24L);
+}
+
+unsigned long jbi_get_dword(unsigned char *buf)
+{
+ return
+ (((unsigned long) buf[0]) |
+ (((unsigned long) buf[1]) << 8L) |
+ (((unsigned long) buf[2]) << 16L) |
+ (((unsigned long) buf[3]) << 24L));
+}
+
+/****************************************************************************/
+/* */
+
+JBI_RETURN_TYPE jbi_execute
+(
+ PROGRAM_PTR program,
+ long program_size,
+ char *workspace,
+ long workspace_size,
+ char *action,
+ char **init_list,
+ int reset_jtag,
+ long *error_address,
+ int *exit_code,
+ int *format_version
+)
+
+/* */
+/* Description: */
+/* */
+/* Returns: */
+/* */
+/****************************************************************************/
+{
+ JBI_RETURN_TYPE status = JBIC_SUCCESS;
+ unsigned long first_word = 0L;
+ unsigned long action_table = 0L;
+ unsigned long proc_table = 0L;
+ unsigned long string_table = 0L;
+ unsigned long symbol_table = 0L;
+ unsigned long data_section = 0L;
+ unsigned long code_section = 0L;
+ unsigned long debug_section = 0L;
+ unsigned long action_count = 0L;
+ unsigned long proc_count = 0L;
+ unsigned long symbol_count = 0L;
+ char message_buffer[JBIC_MESSAGE_LENGTH + 1];
+ long *variables = NULL;
+ long *variable_size = NULL;
+ char *attributes = NULL;
+ unsigned char *proc_attributes = NULL;
+ unsigned long pc;
+ unsigned long opcode_address;
+ unsigned long args[3];
+ unsigned int opcode;
+ unsigned long name_id;
+ long stack[JBI_STACK_SIZE] = {0};
+ unsigned char charbuf[4];
+ long long_temp;
+ unsigned int variable_id;
+ unsigned char *charptr_temp;
+ unsigned char *charptr_temp2;
+ long *longptr_temp;
+ int version = 0;
+ int delta = 0;
+ int stack_ptr = 0;
+ unsigned int arg_count;
+ int done = 0;
+ int bad_opcode = 0;
+ unsigned int count;
+ unsigned int index;
+ unsigned int index2;
+ long long_count;
+ long long_index;
+ long long_index2;
+ unsigned int i;
+ unsigned int j;
+ unsigned long uncompressed_size;
+ unsigned int offset;
+ unsigned long value;
+ int current_proc = 0;
+ char *equal_ptr;
+ int length;
+ int reverse;
+
+#if PORT==DOS
+ char name[33];
+#else
+ char *name;
+#endif
+
+ jbi_workspace = workspace;
+ jbi_workspace_size = workspace_size;
+
+#if PORT==DOS
+ jbi_program = program;
+#endif
+
+ /*
+ * Read header information
+ */
+ if (program_size > 52L)
+ {
+ first_word = GET_DWORD(0);
+ version = (int) (first_word & 1L);
+ *format_version = version + 1;
+ delta = version * 8;
+
+ action_table = GET_DWORD(4);
+ proc_table = GET_DWORD(8);
+ string_table = GET_DWORD(4 + delta);
+ symbol_table = GET_DWORD(16 + delta);
+ data_section = GET_DWORD(20 + delta);
+ code_section = GET_DWORD(24 + delta);
+ debug_section = GET_DWORD(28 + delta);
+ action_count = GET_DWORD(40 + delta);
+ proc_count = GET_DWORD(44 + delta);
+ symbol_count = GET_DWORD(48 + (2 * delta));
+ }
+
+ if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L))
+ {
+ done = 1;
+ status = JBIC_IO_ERROR;
+ }
+
+ if ((status == JBIC_SUCCESS) && (symbol_count > 0))
+ {
+ variables = (long *) jbi_malloc(
+ (unsigned int) symbol_count * sizeof(long));
+
+ if (variables == NULL) status = JBIC_OUT_OF_MEMORY;
+
+ if (status == JBIC_SUCCESS)
+ {
+ variable_size = (long *) jbi_malloc(
+ (unsigned int) symbol_count * sizeof(long));
+
+ if (variable_size == NULL) status = JBIC_OUT_OF_MEMORY;
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ attributes = (char *) jbi_malloc((unsigned int) symbol_count);
+
+ if (attributes == NULL) status = JBIC_OUT_OF_MEMORY;
+ }
+
+ if ((status == JBIC_SUCCESS) && (version > 0))
+ {
+ proc_attributes = (unsigned char *) jbi_malloc((unsigned int) proc_count);
+
+ if (proc_attributes == NULL) status = JBIC_OUT_OF_MEMORY;
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ delta = version * 2;
+
+ for (i = 0; i < (unsigned int) symbol_count; ++i)
+ {
+ offset = (unsigned int) (symbol_table + ((11 + delta) * i));
+
+ value = GET_DWORD(offset + 3 + delta);
+
+ attributes[i] = GET_BYTE(offset);
+
+ /* use bit 7 of attribute byte to indicate that this buffer */
+ /* was dynamically allocated and should be freed later */
+ attributes[i] &= 0x7f;
+
+ variable_size[i] = GET_DWORD(offset + 7 + delta);
+
+ /*
+ * Attribute bits:
+ * bit 0: 0 = read-only, 1 = read-write
+ * bit 1: 0 = not compressed, 1 = compressed
+ * bit 2: 0 = not initialized, 1 = initialized
+ * bit 3: 0 = scalar, 1 = array
+ * bit 4: 0 = Boolean, 1 = integer
+ * bit 5: 0 = declared variable,
+ * 1 = compiler created temporary variable
+ */
+
+ if ((attributes[i] & 0x0c) == 0x04)
+ {
+ /* initialized scalar variable */
+ variables[i] = value;
+ }
+ else if ((attributes[i] & 0x1e) == 0x0e)
+ {
+ /* initialized compressed Boolean array */
+#if PORT==DOS
+ /* for DOS port, get the size but do not uncompress */
+ long_index = data_section + value;
+ uncompressed_size =
+ (((unsigned long) GET_BYTE(long_index)) |
+ (((unsigned long) GET_BYTE(long_index + 1L)) << 8L) |
+ (((unsigned long) GET_BYTE(long_index + 2L)) << 16L) |
+ (((unsigned long) GET_BYTE(long_index + 3L)) << 24L));
+ variable_size[i] = uncompressed_size;
+#else
+ uncompressed_size = jbi_get_dword(
+ &program[data_section + value]);
+
+ /* allocate a buffer for the uncompressed data */
+ variables[i] = (long) jbi_malloc(uncompressed_size);
+
+ if (variables[i] == 0L)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ /* set flag so buffer will be freed later */
+ attributes[i] |= 0x80;
+
+ /* uncompress the data */
+ if (jbi_uncompress(
+ &program[data_section + value],
+ variable_size[i],
+ (unsigned char *) variables[i],
+ uncompressed_size,
+ version)
+ != uncompressed_size)
+ {
+ /* decompression failed */
+ status = JBIC_IO_ERROR;
+ }
+ else
+ {
+ variable_size[i] = uncompressed_size * 8L;
+ }
+ }
+#endif
+ }
+ else if ((attributes[i] & 0x1e) == 0x0c)
+ {
+ /* initialized Boolean array */
+#if PORT==DOS
+ /* flag attributes so that memory is freed */
+ attributes[i] |= 0x80;
+
+ if (variable_size[i] > 0)
+ {
+ unsigned int size = (unsigned int)
+ ((variable_size[i] + 7L) / 8L);
+
+ variables[i] = (long) jbi_malloc(size);
+
+ if (variables[i] == NULL)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ unsigned char *p = (unsigned char *) variables[i];
+ /* copy array values into buffer */
+ for (j = 0; j < size; ++j)
+ {
+ p[j] = GET_BYTE(data_section + value + j);
+ }
+ }
+ }
+ else
+ {
+ variables[i] = 0;
+ }
+#else
+ variables[i] = value + data_section + (long) program;
+#endif
+ }
+ else if ((attributes[i] & 0x1c) == 0x1c)
+ {
+ /* initialized integer array */
+ variables[i] = value + data_section;
+ }
+ else if ((attributes[i] & 0x0c) == 0x08)
+ {
+ /* uninitialized array */
+
+ /* flag attributes so that memory is freed */
+ attributes[i] |= 0x80;
+
+ if (variable_size[i] > 0)
+ {
+ unsigned int size;
+
+ if (attributes[i] & 0x10)
+ {
+ /* integer array */
+ size = (unsigned int)
+ (variable_size[i] * sizeof(long));
+ }
+ else
+ {
+ /* Boolean array */
+ size = (unsigned int)
+ ((variable_size[i] + 7L) / 8L);
+ }
+
+ variables[i] = (long) jbi_malloc(size);
+
+ if (variables[i] == NULL)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ /* zero out memory */
+ for (j = 0; j < size; ++j)
+ {
+ ((unsigned char *)(variables[i]))[j] = 0;
+ }
+ }
+ }
+ else
+ {
+ variables[i] = 0;
+ }
+ }
+ else
+ {
+ variables[i] = 0;
+ }
+ }
+ }
+ }
+
+ /*
+ * Initialize variables listed in init_list
+ */
+ if ((status == JBIC_SUCCESS) && (init_list != NULL) && (version == 0))
+ {
+ delta = version * 2;
+ count = 0;
+ while (init_list[count] != NULL)
+ {
+ equal_ptr = init_list[count];
+ length = 0;
+ while ((*equal_ptr != '=') && (*equal_ptr != '\0'))
+ {
+ ++equal_ptr;
+ ++length;
+ }
+ if (*equal_ptr == '=')
+ {
+ ++equal_ptr;
+ value = jbi_atol(equal_ptr);
+ jbi_strncpy(message_buffer, init_list[count], length);
+ message_buffer[length] = '\0';
+ for (i = 0; i < (unsigned int) symbol_count; ++i)
+ {
+ offset = (unsigned int) (symbol_table + ((11 + delta) * i));
+ name_id = (version == 0) ? GET_WORD(offset + 1) :
+ GET_DWORD(offset + 1);
+#if PORT==DOS
+ for (j = 0; j < 32; ++j)
+ {
+ name[j] = GET_BYTE(string_table + name_id + j);
+ }
+ name[32] = '\0';
+#else
+ name = (char *) &program[string_table + name_id];
+#endif
+
+ if (jbi_stricmp(message_buffer, name) == 0)
+ {
+ variables[i] = value;
+ }
+ }
+ }
+
+ ++count;
+ }
+ }
+
+ if (status != JBIC_SUCCESS) done = 1;
+
+ jbi_init_jtag();
+
+ pc = code_section;
+ message_buffer[0] = '\0';
+
+ /*
+ * For JBC version 2, we will execute the procedures corresponding to
+ * the selected ACTION
+ */
+ if (version > 0)
+ {
+ if (action == NULL)
+ {
+ status = JBIC_ACTION_NOT_FOUND;
+ done = 1;
+ }
+ else
+ {
+ int action_found = 0;
+
+ for (i = 0; (i < action_count) && !action_found; ++i)
+ {
+ name_id = GET_DWORD(action_table + (12 * i));
+
+#if PORT==DOS
+ for (j = 0; j < 32; ++j)
+ {
+ name[j] = GET_BYTE(string_table + name_id + j);
+ }
+ name[32] = '\0';
+#else
+ name = (char *) &program[string_table + name_id];
+#endif
+
+ if (jbi_stricmp(action, name) == 0)
+ {
+ action_found = 1;
+ current_proc = (int) GET_DWORD(action_table + (12 * i) + 8);
+ }
+ }
+
+ if (!action_found)
+ {
+ status = JBIC_ACTION_NOT_FOUND;
+ done = 1;
+ }
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ int first_time = 1;
+ i = current_proc;
+ while ((i != 0) || first_time)
+ {
+ first_time = 0;
+ /* check procedure attribute byte */
+ proc_attributes[i] = (unsigned char)
+ (GET_BYTE(proc_table + (13 * i) + 8) & 0x03);
+
+ if (proc_attributes[i] != 0)
+ {
+ /*
+ * BIT0 - OPTIONAL
+ * BIT1 - RECOMMENDED
+ * BIT6 - FORCED OFF
+ * BIT7 - FORCED ON
+ */
+ if (init_list != NULL)
+ {
+ name_id = GET_DWORD(proc_table + (13 * i));
+#if PORT==DOS
+ for (j = 0; j < 32; ++j)
+ {
+ name[j] = GET_BYTE(string_table + name_id + j);
+ }
+ name[32] = '\0';
+#else
+ name = (char *) &program[string_table + name_id];
+#endif
+ count = 0;
+ while (init_list[count] != NULL)
+ {
+ equal_ptr = init_list[count];
+ length = 0;
+ while ((*equal_ptr != '=') && (*equal_ptr != '\0'))
+ {
+ ++equal_ptr;
+ ++length;
+ }
+ if (*equal_ptr == '=')
+ {
+ ++equal_ptr;
+ jbi_strncpy(message_buffer, init_list[count], length);
+ message_buffer[length] = '\0';
+
+ if (jbi_stricmp(message_buffer, name) == 0)
+ {
+ if (jbi_atol(equal_ptr) == 0)
+ {
+ proc_attributes[i] |= 0x40;
+ }
+ else
+ {
+ proc_attributes[i] |= 0x80;
+ }
+ }
+ }
+
+ ++count;
+ }
+ }
+ }
+
+ i = (unsigned int) GET_DWORD(proc_table + (13 * i) + 4);
+ }
+
+ /*
+ * Set current_proc to the first procedure to be executed
+ */
+ i = current_proc;
+ while ((i != 0) &&
+ ((proc_attributes[i] == 1) ||
+ ((proc_attributes[i] & 0xc0) == 0x40)))
+ {
+ i = (unsigned int) GET_DWORD(proc_table + (13 * i) + 4);
+ }
+
+ if ((i != 0) || ((i == 0) && (current_proc == 0) &&
+ ((proc_attributes[0] != 1) &&
+ ((proc_attributes[0] & 0xc0) != 0x40))))
+ {
+ current_proc = i;
+ pc = code_section + GET_DWORD(proc_table + (13 * i) + 9);
+ CHECK_PC;
+ }
+ else
+ {
+ /* there are no procedures to execute! */
+ done = 1;
+ }
+ }
+ }
+
+ message_buffer[0] = '\0';
+
+ while (!done)
+ {
+ opcode = (unsigned int) (GET_BYTE(pc) & 0xff);
+ opcode_address = pc;
+ ++pc;
+
+ arg_count = (opcode >> 6) & 3;
+ for (i = 0; i < arg_count; ++i)
+ {
+ args[i] = GET_DWORD(pc);
+ pc += 4;
+ }
+
+ switch (opcode)
+ {
+ case 0x00: /* NOP */
+ /* do nothing */
+ break;
+
+ case 0x01: /* DUP */
+ IF_CHECK_STACK(1)
+ {
+ stack[stack_ptr] = stack[stack_ptr - 1];
+ ++stack_ptr;
+ }
+ break;
+
+ case 0x02: /* SWP */
+ IF_CHECK_STACK(2)
+ {
+ long_temp = stack[stack_ptr - 2];
+ stack[stack_ptr - 2] = stack[stack_ptr - 1];
+ stack[stack_ptr - 1] = long_temp;
+ }
+ break;
+
+ case 0x03: /* ADD */
+ IF_CHECK_STACK(2)
+ {
+ --stack_ptr;
+ stack[stack_ptr - 1] += stack[stack_ptr];
+ }
+ break;
+
+ case 0x04: /* SUB */
+ IF_CHECK_STACK(2)
+ {
+ --stack_ptr;
+ stack[stack_ptr - 1] -= stack[stack_ptr];
+ }
+ break;
+
+ case 0x05: /* MULT */
+ IF_CHECK_STACK(2)
+ {
+ --stack_ptr;
+ stack[stack_ptr - 1] *= stack[stack_ptr];
+ }
+ break;
+
+ case 0x06: /* DIV */
+ IF_CHECK_STACK(2)
+ {
+ --stack_ptr;
+ stack[stack_ptr - 1] /= stack[stack_ptr];
+ }
+ break;
+
+ case 0x07: /* MOD */
+ IF_CHECK_STACK(2)
+ {
+ --stack_ptr;
+ stack[stack_ptr - 1] %= stack[stack_ptr];
+ }
+ break;
+
+ case 0x08: /* SHL */
+ IF_CHECK_STACK(2)
+ {
+ --stack_ptr;
+ stack[stack_ptr - 1] <<= stack[stack_ptr];
+ }
+ break;
+
+ case 0x09: /* SHR */
+ IF_CHECK_STACK(2)
+ {
+ --stack_ptr;
+ stack[stack_ptr - 1] >>= stack[stack_ptr];
+ }
+ break;
+
+ case 0x0A: /* NOT */
+ IF_CHECK_STACK(1)
+ {
+ stack[stack_ptr - 1] ^= (-1L);
+ }
+ break;
+
+ case 0x0B: /* AND */
+ IF_CHECK_STACK(2)
+ {
+ --stack_ptr;
+ stack[stack_ptr - 1] &= stack[stack_ptr];
+ }
+ break;
+
+ case 0x0C: /* OR */
+ IF_CHECK_STACK(2)
+ {
+ --stack_ptr;
+ stack[stack_ptr - 1] |= stack[stack_ptr];
+ }
+ break;
+
+ case 0x0D: /* XOR */
+ IF_CHECK_STACK(2)
+ {
+ --stack_ptr;
+ stack[stack_ptr - 1] ^= stack[stack_ptr];
+ }
+ break;
+
+ case 0x0E: /* INV */
+ IF_CHECK_STACK(1)
+ {
+ stack[stack_ptr - 1] = stack[stack_ptr - 1] ? 0L : 1L;
+ }
+ break;
+
+ case 0x0F: /* GT */
+ IF_CHECK_STACK(2)
+ {
+ --stack_ptr;
+ stack[stack_ptr - 1] =
+ (stack[stack_ptr - 1] > stack[stack_ptr]) ? 1L : 0L;
+ }
+ break;
+
+ case 0x10: /* LT */
+ IF_CHECK_STACK(2)
+ {
+ --stack_ptr;
+ stack[stack_ptr - 1] =
+ (stack[stack_ptr - 1] < stack[stack_ptr]) ? 1L : 0L;
+ }
+ break;
+
+ case 0x11: /* RET */
+ if ((version > 0) && (stack_ptr == 0))
+ {
+ /*
+ * We completed one of the main procedures of an ACTION.
+ * Find the next procedure to be executed and jump to it.
+ * If there are no more procedures, then EXIT.
+ */
+ i = (unsigned int) GET_DWORD(proc_table + (13 * current_proc) + 4);
+ while ((i != 0) &&
+ ((proc_attributes[i] == 1) ||
+ ((proc_attributes[i] & 0xc0) == 0x40)))
+ {
+ i = (unsigned int) GET_DWORD(proc_table + (13 * i) + 4);
+ }
+
+ if (i == 0)
+ {
+ /* there are no procedures to execute! */
+ done = 1;
+ *exit_code = 0; /* success */
+ }
+ else
+ {
+ current_proc = i;
+ pc = code_section + GET_DWORD(proc_table + (13 * i) + 9);
+ CHECK_PC;
+ }
+ }
+ else IF_CHECK_STACK(1)
+ {
+ pc = stack[--stack_ptr] + code_section;
+ CHECK_PC;
+ if (pc == code_section)
+ {
+ status = JBIC_BOUNDS_ERROR;
+ }
+ }
+ break;
+
+ case 0x12: /* CMPS */
+ /*
+ * Array short compare
+ * ...stack 0 is source 1 value
+ * ...stack 1 is source 2 value
+ * ...stack 2 is mask value
+ * ...stack 3 is count
+ */
+ IF_CHECK_STACK(4)
+ {
+ long a = stack[--stack_ptr];
+ long b = stack[--stack_ptr];
+ long_temp = stack[--stack_ptr];
+ count = (unsigned int) stack[stack_ptr - 1];
+
+ if ((count < 1) || (count > 32))
+ {
+ status = JBIC_BOUNDS_ERROR;
+ }
+ else
+ {
+ long_temp &= ((-1L) >> (32 - count));
+
+ stack[stack_ptr - 1] =
+ ((a & long_temp) == (b & long_temp)) ? 1L : 0L;
+ }
+ }
+ break;
+
+ case 0x13: /* PINT */
+ /*
+ * PRINT add integer
+ * ...stack 0 is integer value
+ */
+ IF_CHECK_STACK(1)
+ {
+ jbi_ltoa(&message_buffer[jbi_strlen(message_buffer)],
+ stack[--stack_ptr]);
+ }
+ break;
+
+ case 0x14: /* PRNT */
+ /*
+ * PRINT finish
+ */
+ jbi_message(message_buffer);
+ message_buffer[0] = '\0';
+ break;
+
+ case 0x15: /* DSS */
+ /*
+ * DRSCAN short
+ * ...stack 0 is scan data
+ * ...stack 1 is count
+ */
+ IF_CHECK_STACK(2)
+ {
+ long_temp = stack[--stack_ptr];
+ count = (unsigned int) stack[--stack_ptr];
+ jbi_make_dword(charbuf, long_temp);
+ status = jbi_do_drscan(count, charbuf, 0);
+ }
+ break;
+
+ case 0x16: /* DSSC */
+ /*
+ * DRSCAN short with capture
+ * ...stack 0 is scan data
+ * ...stack 1 is count
+ */
+ IF_CHECK_STACK(2)
+ {
+ long_temp = stack[--stack_ptr];
+ count = (unsigned int) stack[stack_ptr - 1];
+ jbi_make_dword(charbuf, long_temp);
+ status = jbi_swap_dr(count, charbuf, 0, charbuf, 0);
+ stack[stack_ptr - 1] = jbi_get_dword(charbuf);
+ }
+ break;
+
+ case 0x17: /* ISS */
+ /*
+ * IRSCAN short
+ * ...stack 0 is scan data
+ * ...stack 1 is count
+ */
+ IF_CHECK_STACK(2)
+ {
+ long_temp = stack[--stack_ptr];
+ count = (unsigned int) stack[--stack_ptr];
+ jbi_make_dword(charbuf, long_temp);
+ status = jbi_do_irscan(count, charbuf, 0);
+ }
+ break;
+
+ case 0x18: /* ISSC */
+ /*
+ * IRSCAN short with capture
+ * ...stack 0 is scan data
+ * ...stack 1 is count
+ */
+ IF_CHECK_STACK(2)
+ {
+ long_temp = stack[--stack_ptr];
+ count = (unsigned int) stack[stack_ptr - 1];
+ jbi_make_dword(charbuf, long_temp);
+ status = jbi_swap_ir(count, charbuf, 0, charbuf, 0);
+ stack[stack_ptr - 1] = jbi_get_dword(charbuf);
+ }
+ break;
+
+ case 0x19: /* VSS */
+ /*
+ * VECTOR short
+ * ...stack 0 is scan data
+ * ...stack 1 is count
+ */
+ bad_opcode = 1;
+ break;
+
+ case 0x1A: /* VSSC */
+ /*
+ * VECTOR short with capture
+ * ...stack 0 is scan data
+ * ...stack 1 is count
+ */
+ bad_opcode = 1;
+ break;
+
+ case 0x1B: /* VMPF */
+ /*
+ * VMAP finish
+ */
+ bad_opcode = 1;
+ break;
+
+ case 0x1C: /* DPR */
+ IF_CHECK_STACK(1)
+ {
+ count = (unsigned int) stack[--stack_ptr];
+ status = jbi_set_dr_preamble(count, 0, NULL);
+ }
+ break;
+
+ case 0x1D: /* DPRL */
+ /*
+ * DRPRE with literal data
+ * ...stack 0 is count
+ * ...stack 1 is literal data
+ */
+ IF_CHECK_STACK(2)
+ {
+ count = (unsigned int) stack[--stack_ptr];
+ long_temp = stack[--stack_ptr];
+ jbi_make_dword(charbuf, long_temp);
+ status = jbi_set_dr_preamble(count, 0, charbuf);
+ }
+ break;
+
+ case 0x1E: /* DPO */
+ /*
+ * DRPOST
+ * ...stack 0 is count
+ */
+ IF_CHECK_STACK(1)
+ {
+ count = (unsigned int) stack[--stack_ptr];
+ status = jbi_set_dr_postamble(count, 0, NULL);
+ }
+ break;
+
+ case 0x1F: /* DPOL */
+ /*
+ * DRPOST with literal data
+ * ...stack 0 is count
+ * ...stack 1 is literal data
+ */
+ IF_CHECK_STACK(2)
+ {
+ count = (unsigned int) stack[--stack_ptr];
+ long_temp = stack[--stack_ptr];
+ jbi_make_dword(charbuf, long_temp);
+ status = jbi_set_dr_postamble(count, 0, charbuf);
+ }
+ break;
+
+ case 0x20: /* IPR */
+ IF_CHECK_STACK(1)
+ {
+ count = (unsigned int) stack[--stack_ptr];
+ status = jbi_set_ir_preamble(count, 0, NULL);
+ }
+ break;
+
+ case 0x21: /* IPRL */
+ /*
+ * IRPRE with literal data
+ * ...stack 0 is count
+ * ...stack 1 is literal data
+ */
+ IF_CHECK_STACK(2)
+ {
+ count = (unsigned int) stack[--stack_ptr];
+ long_temp = stack[--stack_ptr];
+ jbi_make_dword(charbuf, long_temp);
+ status = jbi_set_ir_preamble(count, 0, charbuf);
+ }
+ break;
+
+ case 0x22: /* IPO */
+ /*
+ * IRPOST
+ * ...stack 0 is count
+ */
+ IF_CHECK_STACK(1)
+ {
+ count = (unsigned int) stack[--stack_ptr];
+ status = jbi_set_ir_postamble(count, 0, NULL);
+ }
+ break;
+
+ case 0x23: /* IPOL */
+ /*
+ * IRPOST with literal data
+ * ...stack 0 is count
+ * ...stack 1 is literal data
+ */
+ IF_CHECK_STACK(2)
+ {
+ count = (unsigned int) stack[--stack_ptr];
+ long_temp = stack[--stack_ptr];
+ jbi_make_dword(charbuf, long_temp);
+ status = jbi_set_ir_postamble(count, 0, charbuf);
+ }
+ break;
+
+ case 0x24: /* PCHR */
+ IF_CHECK_STACK(1)
+ {
+ unsigned char ch;
+ count = jbi_strlen(message_buffer);
+ ch = (char) stack[--stack_ptr];
+ if ((ch < 1) || (ch > 127))
+ {
+ /* character code out of range */
+ /* instead of flagging an error, force the value to 127 */
+ ch = 127;
+ }
+ message_buffer[count] = ch;
+ message_buffer[count + 1] = '\0';
+ }
+ break;
+
+ case 0x25: /* EXIT */
+ IF_CHECK_STACK(1)
+ {
+ *exit_code = (int) stack[--stack_ptr];
+ }
+ done = 1;
+ break;
+
+ case 0x26: /* EQU */
+ IF_CHECK_STACK(2)
+ {
+ --stack_ptr;
+ stack[stack_ptr - 1] =
+ (stack[stack_ptr - 1] == stack[stack_ptr]) ? 1L : 0L;
+ }
+ break;
+
+ case 0x27: /* POPT */
+ IF_CHECK_STACK(1)
+ {
+ --stack_ptr;
+ }
+ break;
+
+ case 0x28: /* TRST */
+ bad_opcode = 1;
+ break;
+
+ case 0x29: /* FRQ */
+ bad_opcode = 1;
+ break;
+
+ case 0x2A: /* FRQU */
+ bad_opcode = 1;
+ break;
+
+ case 0x2B: /* PD32 */
+ bad_opcode = 1;
+ break;
+
+ case 0x2C: /* ABS */
+ IF_CHECK_STACK(1)
+ {
+ if (stack[stack_ptr - 1] < 0)
+ {
+ stack[stack_ptr - 1] = 0 - stack[stack_ptr - 1];
+ }
+ }
+ break;
+
+ case 0x2D: /* BCH0 */
+ /*
+ * Batch operation 0
+ * SWP
+ * SWPN 7
+ * SWP
+ * SWPN 6
+ * DUPN 8
+ * SWPN 2
+ * SWP
+ * DUPN 6
+ * DUPN 6
+ */
+
+ /* SWP */
+ IF_CHECK_STACK(2)
+ {
+ long_temp = stack[stack_ptr - 2];
+ stack[stack_ptr - 2] = stack[stack_ptr - 1];
+ stack[stack_ptr - 1] = long_temp;
+ }
+
+ /* SWPN 7 */
+ index = 7 + 1;
+ IF_CHECK_STACK(index)
+ {
+ long_temp = stack[stack_ptr - index];
+ stack[stack_ptr - index] = stack[stack_ptr - 1];
+ stack[stack_ptr - 1] = long_temp;
+ }
+
+ /* SWP */
+ IF_CHECK_STACK(2)
+ {
+ long_temp = stack[stack_ptr - 2];
+ stack[stack_ptr - 2] = stack[stack_ptr - 1];
+ stack[stack_ptr - 1] = long_temp;
+ }
+
+ /* SWPN 6 */
+ index = 6 + 1;
+ IF_CHECK_STACK(index)
+ {
+ long_temp = stack[stack_ptr - index];
+ stack[stack_ptr - index] = stack[stack_ptr - 1];
+ stack[stack_ptr - 1] = long_temp;
+ }
+
+ /* DUPN 8 */
+ index = 8 + 1;
+ IF_CHECK_STACK(index)
+ {
+ stack[stack_ptr] = stack[stack_ptr - index];
+ ++stack_ptr;
+ }
+
+ /* SWPN 2 */
+ index = 2 + 1;
+ IF_CHECK_STACK(index)
+ {
+ long_temp = stack[stack_ptr - index];
+ stack[stack_ptr - index] = stack[stack_ptr - 1];
+ stack[stack_ptr - 1] = long_temp;
+ }
+
+ /* SWP */
+ IF_CHECK_STACK(2)
+ {
+ long_temp = stack[stack_ptr - 2];
+ stack[stack_ptr - 2] = stack[stack_ptr - 1];
+ stack[stack_ptr - 1] = long_temp;
+ }
+
+ /* DUPN 6 */
+ index = 6 + 1;
+ IF_CHECK_STACK(index)
+ {
+ stack[stack_ptr] = stack[stack_ptr - index];
+ ++stack_ptr;
+ }
+
+ /* DUPN 6 */
+ index = 6 + 1;
+ IF_CHECK_STACK(index)
+ {
+ stack[stack_ptr] = stack[stack_ptr - index];
+ ++stack_ptr;
+ }
+ break;
+
+ case 0x2E: /* BCH1 */
+ /*
+ * Batch operation 1
+ * SWPN 8
+ * SWP
+ * SWPN 9
+ * SWPN 3
+ * SWP
+ * SWPN 2
+ * SWP
+ * SWPN 7
+ * SWP
+ * SWPN 6
+ * DUPN 5
+ * DUPN 5
+ */
+ bad_opcode = 1;
+ break;
+
+ case 0x2F: /* PSH0 */
+ stack[stack_ptr++] = 0;
+ break;
+
+ case 0x40: /* PSHL */
+ stack[stack_ptr++] = (long) args[0];
+ break;
+
+ case 0x41: /* PSHV */
+ stack[stack_ptr++] = variables[args[0]];
+ break;
+
+ case 0x42: /* JMP */
+ pc = args[0] + code_section;
+ CHECK_PC;
+ break;
+
+ case 0x43: /* CALL */
+ stack[stack_ptr++] = pc;
+ pc = args[0] + code_section;
+ CHECK_PC;
+ break;
+
+ case 0x44: /* NEXT */
+ /*
+ * Process FOR / NEXT loop
+ * ...argument 0 is variable ID
+ * ...stack 0 is step value
+ * ...stack 1 is end value
+ * ...stack 2 is top address
+ */
+ IF_CHECK_STACK(3)
+ {
+ long step = stack[stack_ptr - 1];
+ long end = stack[stack_ptr - 2];
+ long top = stack[stack_ptr - 3];
+ long iterator = variables[args[0]];
+ int break_out = 0;
+
+ if (step < 0)
+ {
+ if (iterator <= end) break_out = 1;
+ }
+ else
+ {
+ if (iterator >= end) break_out = 1;
+ }
+
+ if (break_out)
+ {
+ stack_ptr -= 3;
+ }
+ else
+ {
+ variables[args[0]] = iterator + step;
+ pc = top + code_section;
+ CHECK_PC;
+ }
+ }
+ break;
+
+ case 0x45: /* PSTR */
+ /*
+ * PRINT add string
+ * ...argument 0 is string ID
+ */
+#if PORT==DOS
+ long_index = string_table + args[0];
+ index2 = jbi_strlen(message_buffer);
+
+ do
+ {
+ i = GET_BYTE(long_index);
+ message_buffer[index2] = (char) i;
+ ++long_index;
+ ++index2;
+ }
+ while ((i != '\0') && (index2 < JBIC_MESSAGE_LENGTH));
+#else
+ count = jbi_strlen(message_buffer);
+ jbi_strncpy(&message_buffer[count],
+ (char *) &program[string_table + args[0]],
+ JBIC_MESSAGE_LENGTH - count);
+#endif
+ message_buffer[JBIC_MESSAGE_LENGTH] = '\0';
+ break;
+
+ case 0x46: /* VMAP */
+ /*
+ * VMAP add signal name
+ * ...argument 0 is string ID
+ */
+ bad_opcode = 1;
+ break;
+
+ case 0x47: /* SINT */
+ /*
+ * STATE intermediate state
+ * ...argument 0 is state code
+ */
+ status = jbi_goto_jtag_state((int) args[0]);
+ break;
+
+ case 0x48: /* ST */
+ /*
+ * STATE final state
+ * ...argument 0 is state code
+ */
+ status = jbi_goto_jtag_state((int) args[0]);
+ break;
+
+ case 0x49: /* ISTP */
+ /*
+ * IRSTOP state
+ * ...argument 0 is state code
+ */
+ status = jbi_set_irstop_state((int) args[0]);
+ break;
+
+ case 0x4A: /* DSTP */
+ /*
+ * DRSTOP state
+ * ...argument 0 is state code
+ */
+ status = jbi_set_drstop_state((int) args[0]);
+ break;
+
+ case 0x4B: /* SWPN */
+ /*
+ * Exchange top with Nth stack value
+ * ...argument 0 is 0-based stack entry to swap with top element
+ */
+ index = ((int) args[0]) + 1;
+ IF_CHECK_STACK(index)
+ {
+ long_temp = stack[stack_ptr - index];
+ stack[stack_ptr - index] = stack[stack_ptr - 1];
+ stack[stack_ptr - 1] = long_temp;
+ }
+ break;
+
+ case 0x4C: /* DUPN */
+ /*
+ * Duplicate Nth stack value
+ * ...argument 0 is 0-based stack entry to duplicate
+ */
+ index = ((int) args[0]) + 1;
+ IF_CHECK_STACK(index)
+ {
+ stack[stack_ptr] = stack[stack_ptr - index];
+ ++stack_ptr;
+ }
+ break;
+
+ case 0x4D: /* POPV */
+ /*
+ * Pop stack into scalar variable
+ * ...argument 0 is variable ID
+ * ...stack 0 is value
+ */
+ IF_CHECK_STACK(1)
+ {
+ variables[args[0]] = stack[--stack_ptr];
+ }
+ break;
+
+ case 0x4E: /* POPE */
+ /*
+ * Pop stack into integer array element
+ * ...argument 0 is variable ID
+ * ...stack 0 is array index
+ * ...stack 1 is value
+ */
+ IF_CHECK_STACK(2)
+ {
+ variable_id = (unsigned int) args[0];
+
+ /*
+ * If variable is read-only, convert to writable array
+ */
+ if ((version > 0) &&
+ ((attributes[variable_id] & 0x9c) == 0x1c))
+ {
+ /*
+ * Allocate a writable buffer for this array
+ */
+ count = (unsigned int) variable_size[variable_id];
+ long_temp = variables[variable_id];
+ longptr_temp = (long *) jbi_malloc(count * sizeof(long));
+ variables[variable_id] = (long) longptr_temp;
+
+ if (variables[variable_id] == NULL)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ break;
+ }
+ else
+ {
+ /* copy previous contents into buffer */
+ for (i = 0; i < count; ++i)
+ {
+ longptr_temp[i] = GET_DWORD(long_temp);
+ long_temp += 4L;
+ }
+
+ /* set bit 7 - buffer was dynamically allocated */
+ attributes[variable_id] |= 0x80;
+
+ /* clear bit 2 - variable is writable */
+ attributes[variable_id] &= ~0x04;
+ attributes[variable_id] |= 0x01;
+ }
+ }
+
+#if PORT==DOS
+ /* for 16-bit version, allow writing in allocated buffers */
+ if ((version > 0) &&
+ ((attributes[variable_id] & 0x9c) == 0x9c))
+ {
+ attributes[variable_id] &= ~0x04;
+ attributes[variable_id] |= 0x01;
+ }
+#endif
+
+ /* check that variable is a writable integer array */
+ if ((attributes[variable_id] & 0x1c) != 0x18)
+ {
+ status = JBIC_BOUNDS_ERROR;
+ }
+ else
+ {
+ longptr_temp = (long *) variables[variable_id];
+
+ /* pop the array index */
+ index = (unsigned int) stack[--stack_ptr];
+
+ /* pop the value and store it into the array */
+ longptr_temp[index] = stack[--stack_ptr];
+ }
+ }
+ break;
+
+ case 0x4F: /* POPA */
+ /*
+ * Pop stack into Boolean array
+ * ...argument 0 is variable ID
+ * ...stack 0 is count
+ * ...stack 1 is array index
+ * ...stack 2 is value
+ */
+ IF_CHECK_STACK(3)
+ {
+ variable_id = (unsigned int) args[0];
+
+ /*
+ * If variable is read-only, convert to writable array
+ */
+ if ((version > 0) &&
+ ((attributes[variable_id] & 0x9c) == 0x0c))
+ {
+ /*
+ * Allocate a writable buffer for this array
+ */
+ long_temp = (variable_size[variable_id] + 7L) >> 3L;
+ charptr_temp2 = (unsigned char *) variables[variable_id];
+ charptr_temp = jbi_malloc((unsigned int) long_temp);
+ variables[variable_id] = (long) charptr_temp;
+
+ if (variables[variable_id] == NULL)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ /* zero the buffer */
+ for (long_index = 0L;
+ long_index < long_temp;
+ ++long_index)
+ {
+ charptr_temp[long_index] = 0;
+ }
+
+ /* copy previous contents into buffer */
+ for (long_index = 0L;
+ long_index < variable_size[variable_id];
+ ++long_index)
+ {
+#if PORT==DOS
+ if ((attributes[variable_id] & 0x02) &&
+ ((long_index & 0x0000FFFF) == 0L))
+ {
+ /* initialized compressed Boolean array */
+ jbi_uncompress_page(variable_id,
+ (int) (long_index >> 16), version);
+ charptr_temp = jbi_aca_out_buffer;
+ long_index2 = long_index & 0xFFFF;
+ }
+#else
+ long_index2 = long_index;
+#endif
+
+ if (charptr_temp2[long_index2 >> 3] &
+ (1 << (long_index2 & 7)))
+ {
+ charptr_temp[long_index >> 3] |=
+ (1 << (long_index & 7));
+ }
+ }
+
+ /* set bit 7 - buffer was dynamically allocated */
+ attributes[variable_id] |= 0x80;
+
+ /* clear bit 2 - variable is writable */
+ attributes[variable_id] &= ~0x04;
+ attributes[variable_id] |= 0x01;
+ }
+ }
+
+#if PORT==DOS
+ /* for 16-bit version, allow writing in allocated buffers */
+ if ((version > 0) &&
+ ((attributes[variable_id] & 0x9c) == 0x8c))
+ {
+ attributes[variable_id] &= ~0x04;
+ attributes[variable_id] |= 0x01;
+ }
+#endif
+
+ /* check that variable is a writable Boolean array */
+ if ((attributes[variable_id] & 0x1c) != 0x08)
+ {
+ status = JBIC_BOUNDS_ERROR;
+ }
+ else
+ {
+ charptr_temp = (unsigned char *) variables[variable_id];
+
+ /* pop the count (number of bits to copy) */
+ long_count = stack[--stack_ptr];
+
+ /* pop the array index */
+ long_index = stack[--stack_ptr];
+
+ reverse = 0;
+
+ if (version > 0)
+ {
+ /* stack 0 = array right index */
+ /* stack 1 = array left index */
+
+ if (long_index > long_count)
+ {
+ reverse = 1;
+ long_temp = long_count;
+ long_count = 1 + long_index - long_count;
+ long_index = long_temp;
+
+ /* reverse POPA is not supported */
+ status = JBIC_BOUNDS_ERROR;
+ break;
+ }
+ else
+ {
+ long_count = 1 + long_count - long_index;
+ }
+ }
+
+ /* pop the data */
+ long_temp = stack[--stack_ptr];
+
+ if (long_count < 1)
+ {
+ status = JBIC_BOUNDS_ERROR;
+ }
+ else
+ {
+ for (i = 0; i < (unsigned int) long_count; ++i)
+ {
+ if (long_temp & (1L << (long) i))
+ {
+ charptr_temp[long_index >> 3L] |=
+ (1L << (long_index & 7L));
+ }
+ else
+ {
+ charptr_temp[long_index >> 3L] &=
+ ~ (unsigned int) (1L << (long_index & 7L));
+ }
+ ++long_index;
+ }
+ }
+ }
+ }
+ break;
+
+ case 0x50: /* JMPZ */
+ /*
+ * Pop stack and branch if zero
+ * ...argument 0 is address
+ * ...stack 0 is condition value
+ */
+ IF_CHECK_STACK(1)
+ {
+ if (stack[--stack_ptr] == 0)
+ {
+ pc = args[0] + code_section;
+ CHECK_PC;
+ }
+ }
+ break;
+
+ case 0x51: /* DS */
+ case 0x52: /* IS */
+ /*
+ * DRSCAN
+ * IRSCAN
+ * ...argument 0 is scan data variable ID
+ * ...stack 0 is array index
+ * ...stack 1 is count
+ */
+ IF_CHECK_STACK(2)
+ {
+ long_index = stack[--stack_ptr];
+ long_count = stack[--stack_ptr];
+
+ reverse = 0;
+
+ if (version > 0)
+ {
+ /* stack 0 = array right index */
+ /* stack 1 = array left index */
+ /* stack 2 = count */
+ long_temp = long_count;
+ long_count = stack[--stack_ptr];
+
+ if (long_index > long_temp)
+ {
+ reverse = 1;
+ long_index = long_temp;
+ }
+ }
+
+#if PORT==DOS
+ if (((long_index & 0xFFFF0000) == 0) &&
+ ((long_count & 0xFFFF0000) == 0))
+ {
+ variable_id = (unsigned int) args[0];
+ if ((attributes[variable_id] & 0x1e) == 0x0e)
+ {
+ /* initialized compressed Boolean array */
+ jbi_uncompress_page(variable_id,
+ (int) (long_index >> 16), version);
+ long_index &= 0x0000ffff;
+ charptr_temp = jbi_aca_out_buffer;
+ }
+ else
+ {
+ charptr_temp = (unsigned char *) variables[variable_id];
+ }
+
+ if (reverse)
+ {
+ /* allocate a buffer and reverse the data order */
+ charptr_temp2 = charptr_temp;
+ charptr_temp = jbi_malloc((unsigned int)
+ ((long_count >> 3L) + 1L));
+
+ if (charptr_temp == NULL)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ break;
+ }
+ else
+ {
+ long_temp = long_index + long_count - 1;
+ long_index2 = 0;
+ while (long_index2 < long_count)
+ {
+ if (charptr_temp2[long_temp >> 3] &
+ (1 << (long_temp & 7)))
+ {
+ charptr_temp[long_index2 >> 3] |=
+ (1 << (long_index2 & 7));
+ }
+ else
+ {
+ charptr_temp[long_index2 >> 3] &=
+ ~(1 << (long_index2 & 7));
+ }
+
+ --long_temp;
+ ++long_index2;
+ }
+ }
+ }
+
+ if (opcode == 0x51) /* DS */
+ {
+ status = jbi_do_drscan((unsigned int) long_count,
+ charptr_temp, (unsigned long) long_index);
+ }
+ else /* IS */
+ {
+ status = jbi_do_irscan((unsigned int) long_count,
+ charptr_temp, (unsigned int) long_index);
+ }
+
+ if (reverse) jbi_free(charptr_temp);
+ }
+ else if ((opcode == 0x51) && !reverse)
+ {
+ status = jbi_do_drscan_multi_page(
+ (unsigned int) args[0],
+ (unsigned long) long_count,
+ (unsigned long) long_index, version);
+ }
+ else
+ {
+ /* reverse multi-page scans are not supported */
+ /* multi-page IR scans are not supported */
+ status = JBIC_BOUNDS_ERROR;
+ }
+#else
+ charptr_temp = (unsigned char *) variables[args[0]];
+
+ if (reverse)
+ {
+ /* allocate a buffer and reverse the data order */
+ charptr_temp2 = charptr_temp;
+ charptr_temp = jbi_malloc((long_count >> 3) + 1);
+ if (charptr_temp == NULL)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ break;
+ }
+ else
+ {
+ long_temp = long_index + long_count - 1;
+ long_index2 = 0;
+ while (long_index2 < long_count)
+ {
+ if (charptr_temp2[long_temp >> 3] &
+ (1 << (long_temp & 7)))
+ {
+ charptr_temp[long_index2 >> 3] |=
+ (1 << (long_index2 & 7));
+ }
+ else
+ {
+ charptr_temp[long_index2 >> 3] &=
+ ~(1 << (long_index2 & 7));
+ }
+
+ --long_temp;
+ ++long_index2;
+ }
+ }
+ }
+
+ if (opcode == 0x51) /* DS */
+ {
+ status = jbi_do_drscan((unsigned int) long_count,
+ charptr_temp, (unsigned long) long_index);
+ }
+ else /* IS */
+ {
+ status = jbi_do_irscan((unsigned int) long_count,
+ charptr_temp, (unsigned int) long_index);
+ }
+#endif
+
+ if (reverse && (charptr_temp != NULL))
+ {
+ jbi_free(charptr_temp);
+ }
+ }
+ break;
+
+ case 0x53: /* DPRA */
+ /*
+ * DRPRE with array data
+ * ...argument 0 is variable ID
+ * ...stack 0 is array index
+ * ...stack 1 is count
+ */
+ IF_CHECK_STACK(2)
+ {
+ index = (unsigned int) stack[--stack_ptr];
+ count = (unsigned int) stack[--stack_ptr];
+
+ if (version > 0)
+ {
+ /* stack 0 = array right index */
+ /* stack 1 = array left index */
+ count = 1 + count - index;
+ }
+
+ charptr_temp = (unsigned char *) variables[args[0]];
+ status = jbi_set_dr_preamble(count, index, charptr_temp);
+ }
+ break;
+
+ case 0x54: /* DPOA */
+ /*
+ * DRPOST with array data
+ * ...argument 0 is variable ID
+ * ...stack 0 is array index
+ * ...stack 1 is count
+ */
+ IF_CHECK_STACK(2)
+ {
+ index = (unsigned int) stack[--stack_ptr];
+ count = (unsigned int) stack[--stack_ptr];
+
+ if (version > 0)
+ {
+ /* stack 0 = array right index */
+ /* stack 1 = array left index */
+ count = 1 + count - index;
+ }
+
+ charptr_temp = (unsigned char *) variables[args[0]];
+ status = jbi_set_dr_postamble(count, index, charptr_temp);
+ }
+ break;
+
+ case 0x55: /* IPRA */
+ /*
+ * IRPRE with array data
+ * ...argument 0 is variable ID
+ * ...stack 0 is array index
+ * ...stack 1 is count
+ */
+ IF_CHECK_STACK(2)
+ {
+ index = (unsigned int) stack[--stack_ptr];
+ count = (unsigned int) stack[--stack_ptr];
+
+ if (version > 0)
+ {
+ /* stack 0 = array right index */
+ /* stack 1 = array left index */
+ count = 1 + count - index;
+ }
+
+ charptr_temp = (unsigned char *) variables[args[0]];
+ status = jbi_set_ir_preamble(count, index, charptr_temp);
+ }
+ break;
+
+ case 0x56: /* IPOA */
+ /*
+ * IRPOST with array data
+ * ...argument 0 is variable ID
+ * ...stack 0 is array index
+ * ...stack 1 is count
+ */
+ IF_CHECK_STACK(2)
+ {
+ index = (unsigned int) stack[--stack_ptr];
+ count = (unsigned int) stack[--stack_ptr];
+
+ if (version > 0)
+ {
+ /* stack 0 = array right index */
+ /* stack 1 = array left index */
+ count = 1 + count - index;
+ }
+
+ charptr_temp = (unsigned char *) variables[args[0]];
+ status = jbi_set_ir_postamble(count, index, charptr_temp);
+ }
+ break;
+
+ case 0x57: /* EXPT */
+ /*
+ * EXPORT
+ * ...argument 0 is string ID
+ * ...stack 0 is integer expression
+ */
+ IF_CHECK_STACK(1)
+ {
+#if PORT==DOS
+ name_id = args[0];
+ for (j = 0; j < 32; ++j)
+ {
+ name[j] = GET_BYTE(string_table + name_id + j);
+ }
+ name[32] = '\0';
+#else
+ name = (char *) &program[string_table + args[0]];
+#endif
+ long_temp = stack[--stack_ptr];
+ jbi_export_integer(name, long_temp);
+ }
+ break;
+
+ case 0x58: /* PSHE */
+ /*
+ * Push integer array element
+ * ...argument 0 is variable ID
+ * ...stack 0 is array index
+ */
+ IF_CHECK_STACK(1)
+ {
+ variable_id = (unsigned int) args[0];
+ index = (unsigned int) stack[stack_ptr - 1];
+
+ /* check variable type */
+ if ((attributes[variable_id] & 0x1f) == 0x19)
+ {
+ /* writable integer array */
+ longptr_temp = (long *) variables[variable_id];
+ stack[stack_ptr - 1] = longptr_temp[index];
+ }
+ else if ((attributes[variable_id] & 0x1f) == 0x1c)
+ {
+ /* read-only integer array */
+ long_temp = variables[variable_id] + (4L * index);
+ stack[stack_ptr - 1] = GET_DWORD(long_temp);
+ }
+ else
+ {
+ status = JBIC_BOUNDS_ERROR;
+ }
+ }
+ break;
+
+ case 0x59: /* PSHA */
+ /*
+ * Push Boolean array
+ * ...argument 0 is variable ID
+ * ...stack 0 is count
+ * ...stack 1 is array index
+ */
+ IF_CHECK_STACK(2)
+ {
+ variable_id = (unsigned int) args[0];
+
+ /* check that variable is a Boolean array */
+ if ((attributes[variable_id] & 0x18) != 0x08)
+ {
+ status = JBIC_BOUNDS_ERROR;
+ }
+ else
+ {
+ charptr_temp = (unsigned char *) variables[variable_id];
+
+ /* pop the count (number of bits to copy) */
+ count = (unsigned int) stack[--stack_ptr];
+
+ /* pop the array index */
+ index = (unsigned int) stack[stack_ptr - 1];
+
+ if (version > 0)
+ {
+ /* stack 0 = array right index */
+ /* stack 1 = array left index */
+ count = 1 + count - index;
+ }
+
+ if ((count < 1) || (count > 32))
+ {
+ status = JBIC_BOUNDS_ERROR;
+ }
+ else
+ {
+#if PORT==DOS
+ if ((attributes[variable_id] & 0x1e) == 0x0e)
+ {
+ /* initialized compressed Boolean array */
+ jbi_uncompress_page(variable_id,
+ (int) (stack[stack_ptr - 1] >> 16), version);
+ charptr_temp = jbi_aca_out_buffer;
+ }
+#endif
+ long_temp = 0L;
+
+ for (i = 0; i < count; ++i)
+ {
+ if (charptr_temp[(i + index) >> 3] &
+ (1 << ((i + index) & 7)))
+ {
+ long_temp |= (1L << i);
+ }
+ }
+
+ stack[stack_ptr - 1] = long_temp;
+ }
+ }
+ }
+ break;
+
+ case 0x5A: /* DYNA */
+ /*
+ * Dynamically change size of array
+ * ...argument 0 is variable ID
+ * ...stack 0 is new size
+ */
+ IF_CHECK_STACK(1)
+ {
+ variable_id = (unsigned int) args[0];
+ long_temp = stack[--stack_ptr];
+
+ if (long_temp > variable_size[variable_id])
+ {
+ variable_size[variable_id] = long_temp;
+
+ if (attributes[variable_id] & 0x10)
+ {
+ /* allocate integer array */
+ long_temp *= 4;
+ }
+ else
+ {
+ /* allocate Boolean array */
+ long_temp = (long_temp + 7) >> 3;
+ }
+
+ /*
+ * If the buffer was previously allocated, free it
+ */
+ if ((attributes[variable_id] & 0x80) &&
+ (variables[variable_id] != NULL))
+ {
+ jbi_free((void *) variables[variable_id]);
+ variables[variable_id] = NULL;
+ }
+
+ /*
+ * Allocate a new buffer of the requested size
+ */
+ variables[variable_id] = (long)
+ jbi_malloc((unsigned int) long_temp);
+
+ if (variables[variable_id] == NULL)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ /*
+ * Set the attribute bit to indicate that this buffer
+ * was dynamically allocated and should be freed later
+ */
+ attributes[variable_id] |= 0x80;
+
+ /* zero out memory */
+ count = (unsigned int)
+ ((variable_size[variable_id] + 7L) / 8L);
+ charptr_temp = (unsigned char *)
+ (variables[variable_id]);
+ for (index = 0; index < count; ++index)
+ {
+ charptr_temp[index] = 0;
+ }
+ }
+ }
+ }
+ break;
+
+ case 0x5B: /* EXPR */
+ bad_opcode = 1;
+ break;
+
+ case 0x5C: /* EXPV */
+ /*
+ * Export Boolean array
+ * ...argument 0 is string ID
+ * ...stack 0 is variable ID
+ * ...stack 1 is array right index
+ * ...stack 2 is array left index
+ */
+ IF_CHECK_STACK(3)
+ {
+ if (version == 0)
+ {
+ /* EXPV is not supported in JBC 1.0 */
+ bad_opcode = 1;
+ break;
+ }
+#if PORT==DOS
+ name_id = args[0];
+ for (j = 0; j < 32; ++j)
+ {
+ name[j] = GET_BYTE(string_table + name_id + j);
+ }
+ name[32] = '\0';
+#else
+ name = (char *) &program[string_table + args[0]];
+#endif
+ variable_id = (unsigned int) stack[--stack_ptr];
+ long_index = stack[--stack_ptr]; /* right index */
+ long_index2 = stack[--stack_ptr]; /* left index */
+
+ if (long_index > long_index2)
+ {
+ /* reverse indices not supported */
+ status = JBIC_BOUNDS_ERROR;
+ break;
+ }
+
+ long_count = 1 + long_index2 - long_index;
+
+ charptr_temp = (unsigned char *) variables[variable_id];
+ charptr_temp2 = NULL;
+
+#if PORT==DOS
+ if ((attributes[variable_id] & 0x1e) == 0x0e)
+ {
+ /* initialized compressed Boolean array */
+ jbi_uncompress_page(variable_id,
+ (int) (long_index >> 16), version);
+ charptr_temp = jbi_aca_out_buffer;
+ long_index &= 0x0000FFFF;
+ }
+#endif
+
+ if ((long_index & 7L) != 0)
+ {
+ charptr_temp2 = jbi_malloc((unsigned int)
+ ((long_count + 7L) / 8L));
+ if (charptr_temp2 == NULL)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ break;
+ }
+ else
+ {
+ long k = long_index;
+ for (i = 0; i < (unsigned int) long_count; ++i)
+ {
+ if (charptr_temp[k >> 3] & (1 << (k & 7)))
+ {
+ charptr_temp2[i >> 3] |= (1 << (i & 7));
+ }
+ else
+ {
+ charptr_temp2[i >> 3] &= ~(1 << (i & 7));
+ }
+
+ ++k;
+ }
+ charptr_temp = charptr_temp2;
+ }
+ }
+ else if (long_index != 0)
+ {
+ charptr_temp = &charptr_temp[long_index >> 3];
+ }
+
+ jbi_export_boolean_array(name, charptr_temp, long_count);
+
+ /* free allocated buffer */
+ if (((long_index & 7L) != 0) && (charptr_temp2 != NULL))
+ {
+ jbi_free(charptr_temp2);
+ }
+ }
+ break;
+
+ case 0x80: /* COPY */
+ /*
+ * Array copy
+ * ...argument 0 is dest ID
+ * ...argument 1 is source ID
+ * ...stack 0 is count
+ * ...stack 1 is dest index
+ * ...stack 2 is source index
+ */
+ IF_CHECK_STACK(3)
+ {
+ long copy_count = stack[--stack_ptr];
+ long copy_index = stack[--stack_ptr];
+ long copy_index2 = stack[--stack_ptr];
+ long destleft;
+ long src_count;
+ long dest_count;
+ int src_reverse = 0;
+ int dest_reverse = 0;
+
+ reverse = 0;
+
+ if (version > 0)
+ {
+ /* stack 0 = source right index */
+ /* stack 1 = source left index */
+ /* stack 2 = destination right index */
+ /* stack 3 = destination left index */
+ destleft = stack[--stack_ptr];
+
+ if (copy_count > copy_index)
+ {
+ src_reverse = 1;
+ reverse = 1;
+ src_count = 1 + copy_count - copy_index;
+ /* copy_index = source start index */
+ }
+ else
+ {
+ src_count = 1 + copy_index - copy_count;
+ copy_index = copy_count; /* source start index */
+ }
+
+ if (copy_index2 > destleft)
+ {
+ dest_reverse = 1;
+ reverse = !reverse;
+ dest_count = 1 + copy_index2 - destleft;
+ copy_index2 = destleft; /* destination start index */
+ }
+ else
+ {
+ dest_count = 1 + destleft - copy_index2;
+ /* copy_index2 = destination start index */
+ }
+
+ copy_count = (src_count < dest_count) ? src_count : dest_count;
+
+ if ((src_reverse || dest_reverse) &&
+ (src_count != dest_count))
+ {
+ /* If either the source or destination is reversed, */
+ /* we can't tolerate a length mismatch, because we */
+ /* "left justify" the arrays when copying. This */
+ /* won't work correctly with reversed arrays. */
+ status = JBIC_BOUNDS_ERROR;
+ }
+ }
+
+ count = (unsigned int) copy_count;
+ index = (unsigned int) copy_index;
+ index2 = (unsigned int) copy_index2;
+
+ /*
+ * If destination is a read-only array, allocate a buffer
+ * and convert it to a writable array
+ */
+ variable_id = (unsigned int) args[1];
+ if ((version > 0) && ((attributes[variable_id] & 0x9c) == 0x0c))
+ {
+ /*
+ * Allocate a writable buffer for this array
+ */
+ long_temp = (variable_size[variable_id] + 7L) >> 3L;
+ charptr_temp2 = (unsigned char *) variables[variable_id];
+ charptr_temp = jbi_malloc((unsigned int) long_temp);
+ variables[variable_id] = (long) charptr_temp;
+
+ if (variables[variable_id] == NULL)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ break;
+ }
+ else
+ {
+ /* zero the buffer */
+ for (long_index = 0L;
+ long_index < long_temp;
+ ++long_index)
+ {
+ charptr_temp[long_index] = 0;
+ }
+
+ /* copy previous contents into buffer */
+ for (long_index = 0L;
+ long_index < variable_size[variable_id];
+ ++long_index)
+ {
+#if PORT==DOS
+ if ((attributes[variable_id] & 0x02) &&
+ ((long_index & 0x0000FFFF) == 0L))
+ {
+ /* initialized compressed Boolean array */
+ jbi_uncompress_page(variable_id,
+ (int) (long_index >> 16), version);
+ charptr_temp = jbi_aca_out_buffer;
+ long_index2 = long_index & 0xFFFF;
+ }
+#else
+ long_index2 = long_index;
+#endif
+
+ if (charptr_temp2[long_index2 >> 3] &
+ (1 << (long_index2 & 7)))
+ {
+ charptr_temp[long_index >> 3] |=
+ (1 << (long_index & 7));
+ }
+ }
+
+ /* set bit 7 - buffer was dynamically allocated */
+ attributes[variable_id] |= 0x80;
+
+ /* clear bit 2 - variable is writable */
+ attributes[variable_id] &= ~0x04;
+ attributes[variable_id] |= 0x01;
+ }
+ }
+
+#if PORT==DOS
+ /* for 16-bit version, allow writing in allocated buffers */
+ if ((version > 0) &&
+ ((attributes[variable_id] & 0x9c) == 0x8c))
+ {
+ attributes[variable_id] &= ~0x04;
+ attributes[variable_id] |= 0x01;
+ }
+#endif
+
+ charptr_temp = (unsigned char *) variables[args[1]];
+ charptr_temp2 = (unsigned char *) variables[args[0]];
+
+#if PORT==DOS
+ variable_id = (unsigned int) args[0];
+ if ((attributes[variable_id] & 0x1e) == 0x0e)
+ {
+ /* initialized compressed Boolean array */
+ jbi_uncompress_page(variable_id,
+ (int) (copy_index >> 16), version);
+ charptr_temp2 = jbi_aca_out_buffer;
+ }
+#endif
+
+ /* check that destination is a writable Boolean array */
+ if ((attributes[args[1]] & 0x1c) != 0x08)
+ {
+ status = JBIC_BOUNDS_ERROR;
+ break;
+ }
+
+ if (count < 1)
+ {
+ status = JBIC_BOUNDS_ERROR;
+ }
+ else
+ {
+ if (reverse)
+ {
+ index2 += (count - 1);
+ }
+
+ for (i = 0; i < count; ++i)
+ {
+ if (charptr_temp2[index >> 3] & (1 << (index & 7)))
+ {
+ charptr_temp[index2 >> 3] |= (1 << (index2 & 7));
+ }
+ else
+ {
+ charptr_temp[index2 >> 3] &=
+ ~(unsigned int) (1 << (index2 & 7));
+ }
+ ++index;
+ if (reverse) --index2; else ++index2;
+ }
+ }
+ }
+ break;
+
+ case 0x81: /* REVA */
+ /*
+ * ARRAY COPY reversing bit order
+ * ...argument 0 is dest ID
+ * ...argument 1 is source ID
+ * ...stack 0 is dest index
+ * ...stack 1 is source index
+ * ...stack 2 is count
+ */
+ bad_opcode = 1;
+ break;
+
+ case 0x82: /* DSC */
+ case 0x83: /* ISC */
+ /*
+ * DRSCAN with capture
+ * IRSCAN with capture
+ * ...argument 0 is scan data variable ID
+ * ...argument 1 is capture variable ID
+ * ...stack 0 is capture index
+ * ...stack 1 is scan data index
+ * ...stack 2 is count
+ */
+ IF_CHECK_STACK(3)
+ {
+ long scan_right, scan_left;
+ long capture_count = 0;
+ long scan_count = 0;
+ long capture_index = stack[--stack_ptr];
+ long scan_index = stack[--stack_ptr];
+ if (version > 0)
+ {
+ /* stack 0 = capture right index */
+ /* stack 1 = capture left index */
+ /* stack 2 = scan right index */
+ /* stack 3 = scan left index */
+ /* stack 4 = count */
+ scan_right = stack[--stack_ptr];
+ scan_left = stack[--stack_ptr];
+ capture_count = 1 + scan_index - capture_index;
+ scan_count = 1 + scan_left - scan_right;
+ scan_index = scan_right;
+ }
+ long_count = stack[--stack_ptr];
+
+ /*
+ * If capture array is read-only, allocate a buffer
+ * and convert it to a writable array
+ */
+ variable_id = (unsigned int) args[1];
+ if ((version > 0) && ((attributes[variable_id] & 0x9c) == 0x0c))
+ {
+ /*
+ * Allocate a writable buffer for this array
+ */
+ long_temp = (variable_size[variable_id] + 7L) >> 3L;
+ charptr_temp2 = (unsigned char *) variables[variable_id];
+ charptr_temp = jbi_malloc((unsigned int) long_temp);
+ variables[variable_id] = (long) charptr_temp;
+
+ if (variables[variable_id] == NULL)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ break;
+ }
+ else
+ {
+ /* zero the buffer */
+ for (long_index = 0L;
+ long_index < long_temp;
+ ++long_index)
+ {
+ charptr_temp[long_index] = 0;
+ }
+
+ /* copy previous contents into buffer */
+ for (long_index = 0L;
+ long_index < variable_size[variable_id];
+ ++long_index)
+ {
+#if PORT==DOS
+ if ((attributes[variable_id] & 0x02) &&
+ ((long_index & 0x0000FFFF) == 0L))
+ {
+ /* initialized compressed Boolean array */
+ jbi_uncompress_page(variable_id,
+ (int) (long_index >> 16), version);
+ charptr_temp = jbi_aca_out_buffer;
+ long_index2 = long_index & 0xFFFF;
+ }
+#else
+ long_index2 = long_index;
+#endif
+
+ if (charptr_temp2[long_index2 >> 3] &
+ (1 << (long_index2 & 7)))
+ {
+ charptr_temp[long_index >> 3] |=
+ (1 << (long_index & 7));
+ }
+ }
+
+ /* set bit 7 - buffer was dynamically allocated */
+ attributes[variable_id] |= 0x80;
+
+ /* clear bit 2 - variable is writable */
+ attributes[variable_id] &= ~0x04;
+ attributes[variable_id] |= 0x01;
+ }
+ }
+
+#if PORT==DOS
+ /* for 16-bit version, allow writing in allocated buffers */
+ if ((version > 0) &&
+ ((attributes[variable_id] & 0x9c) == 0x8c))
+ {
+ attributes[variable_id] &= ~0x04;
+ attributes[variable_id] |= 0x01;
+ }
+#endif
+
+ charptr_temp = (unsigned char *) variables[args[0]];
+ charptr_temp2 = (unsigned char *) variables[args[1]];
+
+#if PORT==DOS
+ variable_id = (unsigned int) args[0];
+ if ((attributes[variable_id] & 0x1e) == 0x0e)
+ {
+ /* initialized compressed Boolean array */
+ jbi_uncompress_page(variable_id,
+ (int) (scan_index >> 16), version);
+ scan_index &= 0x0000ffff;
+ charptr_temp = jbi_aca_out_buffer;
+ }
+#endif
+
+ if ((version > 0) &&
+ ((long_count > capture_count) || (long_count > scan_count)))
+ {
+ status = JBIC_BOUNDS_ERROR;
+ }
+
+ /* check that capture array is a writable Boolean array */
+ if ((attributes[args[1]] & 0x1c) != 0x08)
+ {
+ status = JBIC_BOUNDS_ERROR;
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ if (opcode == 0x82) /* DSC */
+ {
+ status = jbi_swap_dr((unsigned int) long_count,
+ charptr_temp, (unsigned long) scan_index,
+ charptr_temp2, (unsigned int) capture_index);
+ }
+ else /* ISC */
+ {
+ status = jbi_swap_ir((unsigned int) long_count,
+ charptr_temp, (unsigned int) scan_index,
+ charptr_temp2, (unsigned int) capture_index);
+ }
+ }
+ }
+ break;
+
+ case 0x84: /* WAIT */
+ /*
+ * WAIT
+ * ...argument 0 is wait state
+ * ...argument 1 is end state
+ * ...stack 0 is cycles
+ * ...stack 1 is microseconds
+ */
+ IF_CHECK_STACK(2)
+ {
+ long_temp = stack[--stack_ptr];
+
+ if (long_temp != 0L)
+ {
+ status = jbi_do_wait_cycles(long_temp, (unsigned int) args[0]);
+ }
+
+ long_temp = stack[--stack_ptr];
+
+ if ((status == JBIC_SUCCESS) && (long_temp != 0L))
+ {
+ status = jbi_do_wait_microseconds(long_temp, (unsigned int) args[0]);
+ }
+
+ if ((status == JBIC_SUCCESS) && (args[1] != args[0]))
+ {
+ status = jbi_goto_jtag_state((unsigned int) args[1]);
+ }
+
+ if (version > 0)
+ {
+ --stack_ptr; /* throw away MAX cycles */
+ --stack_ptr; /* throw away MAX microseconds */
+ }
+ }
+ break;
+
+ case 0x85: /* VS */
+ /*
+ * VECTOR
+ * ...argument 0 is dir data variable ID
+ * ...argument 1 is scan data variable ID
+ * ...stack 0 is dir array index
+ * ...stack 1 is scan array index
+ * ...stack 2 is count
+ */
+ bad_opcode = 1;
+ break;
+
+ case 0xC0: /* CMPA */
+ /*
+ * Array compare
+ * ...argument 0 is source 1 ID
+ * ...argument 1 is source 2 ID
+ * ...argument 2 is mask ID
+ * ...stack 0 is source 1 index
+ * ...stack 1 is source 2 index
+ * ...stack 2 is mask index
+ * ...stack 3 is count
+ */
+ IF_CHECK_STACK(4)
+ {
+ long a, b;
+ unsigned char *source1 = (unsigned char *) variables[args[0]];
+ unsigned char *source2 = (unsigned char *) variables[args[1]];
+ unsigned char *mask = (unsigned char *) variables[args[2]];
+ unsigned long index1 = stack[--stack_ptr];
+ unsigned long index2 = stack[--stack_ptr];
+ unsigned long mask_index = stack[--stack_ptr];
+ long_count = stack[--stack_ptr];
+
+ if (version > 0)
+ {
+ /* stack 0 = source 1 right index */
+ /* stack 1 = source 1 left index */
+ /* stack 2 = source 2 right index */
+ /* stack 3 = source 2 left index */
+ /* stack 4 = mask right index */
+ /* stack 5 = mask left index */
+ long mask_right = stack[--stack_ptr];
+ long mask_left = stack[--stack_ptr];
+ a = 1 + index2 - index1; /* source 1 count */
+ b = 1 + long_count - mask_index; /* source 2 count */
+ a = (a < b) ? a : b;
+ b = 1 + mask_left - mask_right; /* mask count */
+ a = (a < b) ? a : b;
+ index2 = mask_index; /* source 2 start index */
+ mask_index = mask_right; /* mask start index */
+ long_count = a;
+ }
+
+ long_temp = 1L;
+
+ if (long_count < 1)
+ {
+ status = JBIC_BOUNDS_ERROR;
+ }
+ else
+ {
+#if PORT==DOS
+ variable_id = (unsigned int) args[0];
+ if ((attributes[variable_id] & 0x1e) == 0x0e)
+ {
+ jbi_uncompress_page(variable_id,
+ (int) (index1 >> 16), version);
+ index1 &= 0x0000ffff;
+ source1 = jbi_aca_out_buffer;
+ }
+
+ variable_id = (unsigned int) args[1];
+ if ((attributes[variable_id] & 0x1e) == 0x0e)
+ {
+ jbi_uncompress_page(variable_id,
+ (int) (index2 >> 16), version);
+ index2 &= 0x0000ffff;
+ source2 = jbi_aca_out_buffer;
+ }
+#endif
+ count = (unsigned int) long_count;
+
+ for (i = 0; i < count; ++i)
+ {
+ if (mask[mask_index >> 3] & (1 << (mask_index & 7)))
+ {
+ a = source1[index1 >> 3] & (1 << (index1 & 7))
+ ? 1 : 0;
+ b = source2[index2 >> 3] & (1 << (index2 & 7))
+ ? 1 : 0;
+
+ if (a != b) long_temp = 0L; /* failure */
+ }
+ ++index1;
+ ++index2;
+ ++mask_index;
+ }
+ }
+
+ stack[stack_ptr++] = long_temp;
+ }
+ break;
+
+ case 0xC1: /* VSC */
+ /*
+ * VECTOR with capture
+ * ...argument 0 is dir data variable ID
+ * ...argument 1 is scan data variable ID
+ * ...argument 2 is capture variable ID
+ * ...stack 0 is capture index
+ * ...stack 1 is scan data index
+ * ...stack 2 is dir data index
+ * ...stack 3 is count
+ */
+ bad_opcode = 1;
+ break;
+
+ default:
+ /*
+ * Unrecognized opcode -- ERROR!
+ */
+ bad_opcode = 1;
+ break;
+ }
+
+ if (bad_opcode)
+ {
+ status = JBIC_ILLEGAL_OPCODE;
+ }
+
+ if ((stack_ptr < 0) || (stack_ptr >= JBI_STACK_SIZE))
+ {
+ status = JBIC_STACK_OVERFLOW;
+ }
+
+ if (status != JBIC_SUCCESS)
+ {
+ done = 1;
+ *error_address = (long) (opcode_address - code_section);
+ }
+ }
+
+ jbi_free_jtag_padding_buffers(reset_jtag);
+
+ /*
+ * Free all dynamically allocated arrays
+ */
+ if ((attributes != NULL) && (variables != NULL))
+ {
+ for (i = 0; i < (unsigned int) symbol_count; ++i)
+ {
+ if ((attributes[i] & 0x80) && (variables[i] != NULL))
+ {
+ jbi_free((void *) variables[i]);
+ }
+ }
+ }
+
+ if (variables != NULL) jbi_free(variables);
+
+ if (variable_size != NULL) jbi_free(variable_size);
+
+ if (attributes != NULL) jbi_free(attributes);
+
+ if (proc_attributes != NULL) jbi_free(proc_attributes);
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JBI_RETURN_TYPE jbi_get_note
+(
+ PROGRAM_PTR program,
+ long program_size,
+ long *offset,
+ char *key,
+ char *value,
+ int length
+)
+
+/* */
+/* Description: Gets key and value of NOTE fields in the JBC file. */
+/* Can be called in two modes: if offset pointer is NULL, */
+/* then the function searches for note fields which match */
+/* the key string provided. If offset is not NULL, then */
+/* the function finds the next note field of any key, */
+/* starting at the offset specified by the offset pointer. */
+/* */
+/* Returns: JBIC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ JBI_RETURN_TYPE status = JBIC_UNEXPECTED_END;
+ unsigned long note_strings = 0L;
+ unsigned long note_table = 0L;
+ unsigned long note_count = 0L;
+ unsigned long first_word = 0L;
+ int version = 0;
+ int delta = 0;
+ char *key_ptr;
+ char *value_ptr;
+ int i;
+
+#if PORT==DOS
+ int count = 0;
+ int done = 0;
+ long long_index = 0;
+ char key_buffer[256];
+ char value_buffer[256];
+
+ jbi_program = program;
+#endif
+
+ /*
+ * Read header information
+ */
+ if (program_size > 52L)
+ {
+ first_word = GET_DWORD(0);
+ version = (int) (first_word & 1L);
+ delta = version * 8;
+
+ note_strings = GET_DWORD(8 + delta);
+ note_table = GET_DWORD(12 + delta);
+ note_count = GET_DWORD(44 + (2 * delta));
+ }
+
+ if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L))
+ {
+ status = JBIC_IO_ERROR;
+ }
+ else if (note_count > 0L)
+ {
+ if (offset == NULL)
+ {
+ /*
+ * We will search for the first note with a specific key, and
+ * return only the value
+ */
+ for (i = 0; (i < (int) note_count) && (status != JBIC_SUCCESS); ++i)
+ {
+#if PORT==DOS
+ done = 0;
+ count = 0;
+ long_index = note_strings + GET_DWORD(note_table + (8 * i));
+ while ((count < 255) && !done)
+ {
+ key_buffer[count] = GET_BYTE(long_index);
+ if (key_buffer[count] == '\0') done = 1;
+ ++long_index;
+ ++count;
+ }
+ key_buffer[255] = '\0';
+ key_ptr = key_buffer;
+#else
+ key_ptr = (char *) &program[note_strings +
+ GET_DWORD(note_table + (8 * i))];
+#endif
+ if ((key != NULL) && (jbi_stricmp(key, key_ptr) == 0))
+ {
+ status = JBIC_SUCCESS;
+
+#if PORT==DOS
+ done = 0;
+ count = 0;
+ long_index = note_strings + GET_DWORD(note_table + (8 * i) + 4);
+ while ((count < 255) && !done)
+ {
+ value_buffer[count] = GET_BYTE(long_index);
+ if (value_buffer[count] == '\0') done = 1;
+ ++long_index;
+ ++count;
+ }
+ value_buffer[255] = '\0';
+ value_ptr = value_buffer;
+#else
+ value_ptr = (char *) &program[note_strings +
+ GET_DWORD(note_table + (8 * i) + 4)];
+#endif
+
+ if (value != NULL)
+ {
+ jbi_strncpy(value, value_ptr, length);
+ }
+ }
+ }
+ }
+ else
+ {
+ /*
+ * We will search for the next note, regardless of the key, and
+ * return both the value and the key
+ */
+
+ i = (int) *offset;
+
+ if ((i >= 0) && (i < (int) note_count))
+ {
+ status = JBIC_SUCCESS;
+
+ if (key != NULL)
+ {
+#if PORT==DOS
+ done = 0;
+ count = 0;
+ long_index = note_strings +
+ GET_DWORD(note_table + (8 * i));
+
+ while ((count < length) && !done)
+ {
+ key[count] = GET_BYTE(long_index);
+ if (key[count] == '\0') done = 1;
+ ++long_index;
+ ++count;
+ }
+#else
+ jbi_strncpy(key, (char *) &program[note_strings +
+ GET_DWORD(note_table + (8 * i))], length);
+#endif
+ }
+
+ if (value != NULL)
+ {
+#if PORT==DOS
+ done = 0;
+ count = 0;
+ long_index = note_strings +
+ GET_DWORD(note_table + (8 * i) + 4);
+
+ while ((count < length) && !done)
+ {
+ value[count] = GET_BYTE(long_index);
+ if (value[count] == '\0') done = 1;
+ ++long_index;
+ ++count;
+ }
+#else
+ jbi_strncpy(value, (char *) &program[note_strings +
+ GET_DWORD(note_table + (8 * i) + 4)], length);
+#endif
+ }
+
+ *offset = i + 1;
+ }
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JBI_RETURN_TYPE jbi_check_crc
+(
+ PROGRAM_PTR program,
+ long program_size,
+ unsigned short *expected_crc,
+ unsigned short *actual_crc
+)
+
+/* */
+/* Description: This function reads the entire input file and computes */
+/* the CRC of everything up to the CRC field. */
+/* */
+/* Returns: JBIC_SUCCESS for success, JBIC_CRC_ERROR for failure */
+/* */
+/****************************************************************************/
+{
+ JBI_RETURN_TYPE status = JBIC_SUCCESS;
+ unsigned short local_expected, local_actual, shift_reg = 0xffff;
+ int bit, feedback;
+ unsigned char databyte;
+ unsigned long i;
+ unsigned long crc_section = 0L;
+ unsigned long first_word = 0L;
+ int version = 0;
+ int delta = 0;
+
+#if PORT==DOS
+ jbi_program = program;
+#endif
+
+ if (program_size > 52L)
+ {
+ first_word = GET_DWORD(0);
+ version = (int) (first_word & 1L);
+ delta = version * 8;
+
+ crc_section = GET_DWORD(32 + delta);
+ }
+
+ if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L))
+ {
+ status = JBIC_IO_ERROR;
+ }
+
+ if (crc_section >= (unsigned long) program_size)
+ {
+ status = JBIC_IO_ERROR;
+ }
+
+ if (status == JBIC_SUCCESS)
+ {
+ local_expected = (unsigned short) GET_WORD(crc_section);
+ if (expected_crc != NULL) *expected_crc = local_expected;
+
+ for (i = 0; i < crc_section; ++i)
+ {
+ databyte = GET_BYTE(i);
+ for (bit = 0; bit < 8; bit++) /* compute for each bit */
+ {
+ feedback = (databyte ^ shift_reg) & 0x01;
+ shift_reg >>= 1; /* shift the shift register */
+ if (feedback) shift_reg ^= 0x8408; /* invert selected bits */
+ databyte >>= 1; /* get the next bit of input_byte */
+ }
+ }
+
+ local_actual = (unsigned short) ~shift_reg;
+ if (actual_crc != NULL) *actual_crc = local_actual;
+
+ if (local_expected != local_actual)
+ {
+ status = JBIC_CRC_ERROR;
+ }
+ }
+
+ return (status);
+}
+
+JBI_RETURN_TYPE jbi_get_file_info
+(
+ PROGRAM_PTR program,
+ long program_size,
+ int *format_version,
+ int *action_count,
+ int *procedure_count
+)
+{
+ JBI_RETURN_TYPE status = JBIC_IO_ERROR;
+ unsigned long first_word = 0;
+ int version = 0;
+
+#if PORT==DOS
+ jbi_program = program;
+#endif
+
+ /*
+ * Read header information
+ */
+ if (program_size > 52L)
+ {
+ first_word = GET_DWORD(0);
+
+ if ((first_word == 0x4A414D00L) || (first_word == 0x4A414D01L))
+ {
+ status = JBIC_SUCCESS;
+
+ version = (int) (first_word & 1L);
+ *format_version = version + 1;
+
+ if (version > 0)
+ {
+ *action_count = (int) GET_DWORD(48);
+ *procedure_count = (int) GET_DWORD(52);
+ }
+ }
+
+ }
+
+ return (status);
+}
+
+JBI_RETURN_TYPE jbi_get_action_info
+(
+ PROGRAM_PTR program,
+ long program_size,
+ int index,
+ char **name,
+ char **description,
+ JBI_PROCINFO **procedure_list
+)
+{
+ JBI_RETURN_TYPE status = JBIC_IO_ERROR;
+ JBI_PROCINFO *procptr = NULL;
+ JBI_PROCINFO *tmpptr = NULL;
+ unsigned long first_word = 0L;
+ unsigned long action_table = 0L;
+ unsigned long proc_table = 0L;
+ unsigned long string_table = 0L;
+ unsigned long note_strings = 0L;
+ unsigned long action_count = 0L;
+ unsigned long proc_count = 0L;
+ unsigned long act_name_id = 0L;
+ unsigned long act_desc_id = 0L;
+ unsigned long act_proc_id = 0L;
+ unsigned long act_proc_name = 0L;
+ unsigned char act_proc_attribute = 0;
+
+#if PORT==DOS
+ int i, length;
+ jbi_program = program;
+#endif
+
+ /*
+ * Read header information
+ */
+ if (program_size > 52L)
+ {
+ first_word = GET_DWORD(0);
+
+ if (first_word == 0x4A414D01L)
+ {
+ action_table = GET_DWORD(4);
+ proc_table = GET_DWORD(8);
+ string_table = GET_DWORD(12);
+ note_strings = GET_DWORD(16);
+ action_count = GET_DWORD(48);
+ proc_count = GET_DWORD(52);
+
+ if (index < (int) action_count)
+ {
+ act_name_id = GET_DWORD(action_table + (12 * index));
+ act_desc_id = GET_DWORD(action_table + (12 * index) + 4);
+ act_proc_id = GET_DWORD(action_table + (12 * index) + 8);
+
+#if PORT==DOS
+ length = 0;
+ while (GET_BYTE(string_table + act_name_id + length) != 0) ++length;
+ *name = jbi_malloc(length + 1);
+ if (*name == NULL)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ for (i = 0; i < length; ++i)
+ {
+ (*name)[i] = GET_BYTE(string_table + act_name_id + i);
+ }
+ (*name)[length] = '\0';
+ }
+#else
+ *name = (char *) &program[string_table + act_name_id];
+#endif
+
+ if (act_desc_id < (note_strings - string_table))
+ {
+#if PORT==DOS
+ length = 0;
+ while (GET_BYTE(string_table + act_desc_id + length) != 0) ++length;
+ *description = jbi_malloc(length + 1);
+ if (*description == NULL)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ for (i = 0; i < length; ++i)
+ {
+ (*description)[i] = GET_BYTE(string_table + act_desc_id + i);
+ }
+ (*description)[length] = '\0';
+ }
+#else
+ *description = (char *) &program[string_table + act_desc_id];
+#endif
+ }
+
+ do
+ {
+ act_proc_name = GET_DWORD(proc_table + (13 * act_proc_id));
+ act_proc_attribute = (unsigned char)
+ (GET_BYTE(proc_table + (13 * act_proc_id) + 8) & 0x03);
+
+ procptr = (JBI_PROCINFO *) jbi_malloc(sizeof(JBI_PROCINFO));
+
+ if (procptr == NULL)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ }
+ else
+ {
+#if PORT==DOS
+ length = 0;
+ while (GET_BYTE(string_table + act_proc_name + length) != 0) ++length;
+ procptr->name = jbi_malloc(length + 1);
+ if (procptr->name == NULL)
+ {
+ status = JBIC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ for (i = 0; i < length; ++i)
+ {
+ procptr->name[i] =
+ GET_BYTE(string_table + act_proc_name + i);
+ }
+ procptr->name[length] = '\0';
+ }
+#else
+ procptr->name = (char *)
+ &program[string_table + act_proc_name];
+#endif
+ procptr->attributes = act_proc_attribute;
+ procptr->next = NULL;
+
+ /* add record to end of linked list */
+ if (*procedure_list == NULL)
+ {
+ *procedure_list = procptr;
+ }
+ else
+ {
+ tmpptr = *procedure_list;
+ while (tmpptr->next != NULL) tmpptr = tmpptr->next;
+ tmpptr->next = procptr;
+ }
+ }
+
+ act_proc_id =
+ GET_DWORD(proc_table + (13 * act_proc_id) + 4);
+ }
+ while ((act_proc_id != 0) && (act_proc_id < proc_count));
+ }
+ }
+
+ }
+
+ return (status);
+}
diff --git a/common/recipes-utils/jbi/files/code/jbiport.h b/common/recipes-utils/jbi/files/code/jbiport.h
new file mode 100644
index 0000000..885e84d
--- /dev/null
+++ b/common/recipes-utils/jbi/files/code/jbiport.h
@@ -0,0 +1,45 @@
+/****************************************************************************/
+/* */
+/* Module: jbiport.h */
+/* */
+/* Copyright (C) Altera Corporation 2000-2001 */
+/* */
+/* Description: Defines porting macros */
+/* */
+/****************************************************************************/
+
+#ifndef INC_JBIPORT_H
+#define INC_JBIPORT_H
+
+/*
+* PORT defines the target platform: DOS, WINDOWS, UNIX, or EMBEDDED
+*
+* PORT = DOS means a 16-bit DOS console-mode application
+*
+* PORT = WINDOWS means a 32-bit WIN32 console-mode application for
+* Windows 95, 98, 2000, ME or NT. On NT this will use the
+* DeviceIoControl() API to access the Parallel Port.
+*
+* PORT = UNIX means any UNIX system. BitBlaster access is support via
+* the standard ANSI system calls open(), read(), write().
+* The ByteBlaster is not supported.
+*
+* PORT = EMBEDDED means all DOS, WINDOWS, and UNIX code is excluded.
+* Remaining code supports 16 and 32-bit compilers.
+* Additional porting steps may be necessary. See readme
+* file for more details.
+*/
+
+#define DOS 2
+#define WINDOWS 3
+#define UNIX 4
+#define EMBEDDED 5
+
+#ifndef PORT
+/* change this line to build a different port */
+#define PORT UNIX
+#endif
+
+#define OPENBMC
+
+#endif /* INC_JBIPORT_H */
diff --git a/common/recipes-utils/jbi/files/code/jbistub.c b/common/recipes-utils/jbi/files/code/jbistub.c
new file mode 100644
index 0000000..87e9066
--- /dev/null
+++ b/common/recipes-utils/jbi/files/code/jbistub.c
@@ -0,0 +1,2222 @@
+/****************************************************************************/
+/* */
+/* Module: jbistub.c */
+/* */
+/* Copyright (C) Altera Corporation 1997-2001 */
+/* */
+/* Description: Jam STAPL ByteCode Player main source file */
+/* */
+/* Supports Altera ByteBlaster hardware download cable */
+/* on Windows 95 and Windows NT operating systems. */
+/* (A device driver is required for Windows NT.) */
+/* */
+/* Also supports BitBlaster hardware download cable on */
+/* Windows 95, Windows NT, and UNIX platforms. */
+/* */
+/* Revisions: 1.1 fixed control port initialization for ByteBlaster */
+/* 2.0 added support for STAPL bytecode format, added code */
+/* to get printer port address from Windows registry */
+/* 2.1 improved messages, fixed delay-calibration bug in */
+/* 16-bit DOS port, added support for "alternative */
+/* cable X", added option to control whether to reset */
+/* the TAP after execution, moved porting macros into */
+/* jbiport.h */
+/* 2.2 added support for static memory */
+/* fixed /W4 warnings */
+/* */
+/****************************************************************************/
+
+#ifndef NO_ALTERA_STDIO
+#define NO_ALTERA_STDIO
+#endif
+
+#if ( _MSC_VER >= 800 )
+#pragma warning(disable:4115)
+#pragma warning(disable:4201)
+#pragma warning(disable:4214)
+#pragma warning(disable:4514)
+#endif
+
+#include "jbiport.h"
+
+#if PORT == WINDOWS
+#include <windows.h>
+#else
+typedef int BOOL;
+typedef unsigned char BYTE;
+typedef unsigned short WORD;
+typedef unsigned long DWORD;
+#define TRUE 1
+#define FALSE 0
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifndef OPENBMC
+#include <io.h>
+#endif
+#include <fcntl.h>
+#ifndef OPENBMC
+#include <process.h>
+#endif
+#if defined(USE_STATIC_MEMORY)
+ #define N_STATIC_MEMORY_KBYTES ((unsigned int) USE_STATIC_MEMORY)
+ #define N_STATIC_MEMORY_BYTES (N_STATIC_MEMORY_KBYTES * 1024)
+ #define POINTER_ALIGNMENT sizeof(DWORD)
+#else /* USE_STATIC_MEMORY */
+ #include <malloc.h>
+ #define POINTER_ALIGNMENT sizeof(BYTE)
+#endif /* USE_STATIC_MEMORY */
+#include <time.h>
+#ifndef OPENBMC
+#include <conio.h>
+#endif
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef OPENBMC
+//#define VERBOSE
+//#define DEBUG
+#include <openbmc/gpio.h>
+#include <openbmc/log.h>
+#include <errno.h>
+#endif
+
+#if PORT == DOS
+#include <bios.h>
+#endif
+
+#include "jbiexprt.h"
+
+#if PORT == WINDOWS
+#define PGDC_IOCTL_GET_DEVICE_INFO_PP 0x00166A00L
+#define PGDC_IOCTL_READ_PORT_PP 0x00166A04L
+#define PGDC_IOCTL_WRITE_PORT_PP 0x0016AA08L
+#define PGDC_IOCTL_PROCESS_LIST_PP 0x0016AA1CL
+#define PGDC_READ_INFO 0x0a80
+#define PGDC_READ_PORT 0x0a81
+#define PGDC_WRITE_PORT 0x0a82
+#define PGDC_PROCESS_LIST 0x0a87
+#define PGDC_HDLC_NTDRIVER_VERSION 2
+#define PORT_IO_BUFFER_SIZE 256
+#endif
+
+#if PORT == WINDOWS
+#ifdef __BORLANDC__
+/* create dummy inp() and outp() functions for Borland 32-bit compile */
+WORD inp(WORD address) { address = address; return(0); }
+void outp(WORD address, WORD data) { address = address; data = data; }
+#else
+#pragma intrinsic (inp, outp)
+#endif
+#endif
+
+/*
+* For Borland C compiler (16-bit), set the stack size
+*/
+#if PORT == DOS
+#ifdef __BORLANDC__
+extern unsigned int _stklen = 50000;
+#endif
+#endif
+
+/************************************************************************
+*
+* Global variables
+*/
+
+/* file buffer for Jam STAPL ByteCode input file */
+#if PORT == DOS
+unsigned char **file_buffer = NULL;
+#else
+unsigned char *file_buffer = NULL;
+#endif
+long file_pointer = 0L;
+long file_length = 0L;
+
+/* delay count for one millisecond delay */
+long one_ms_delay = 0L;
+
+/* serial port interface available on all platforms */
+BOOL jtag_hardware_initialized = FALSE;
+char *serial_port_name = NULL;
+BOOL specified_com_port = FALSE;
+int com_port = -1;
+void initialize_jtag_hardware(void);
+void close_jtag_hardware(void);
+
+#ifdef OPENBMC
+int g_tck = -1;
+int g_tms = -1;
+int g_tdo = -1;
+int g_tdi = -1;
+gpio_st g_gpio_tck;
+gpio_st g_gpio_tms;
+gpio_st g_gpio_tdo;
+gpio_st g_gpio_tdi;
+#endif
+
+#if defined(USE_STATIC_MEMORY)
+ unsigned char static_memory_heap[N_STATIC_MEMORY_BYTES] = { 0 };
+#endif /* USE_STATIC_MEMORY */
+
+#if defined(USE_STATIC_MEMORY) || defined(MEM_TRACKER)
+ unsigned int n_bytes_allocated = 0;
+#endif /* USE_STATIC_MEMORY || MEM_TRACKER */
+
+#if defined(MEM_TRACKER)
+ unsigned int peak_memory_usage = 0;
+ unsigned int peak_allocations = 0;
+ unsigned int n_allocations = 0;
+#if defined(USE_STATIC_MEMORY)
+ unsigned int n_bytes_not_recovered = 0;
+#endif /* USE_STATIC_MEMORY */
+ const DWORD BEGIN_GUARD = 0x01234567;
+ const DWORD END_GUARD = 0x76543210;
+#endif /* MEM_TRACKER */
+
+#if PORT == WINDOWS || PORT == DOS
+/* parallel port interface available on PC only */
+BOOL specified_lpt_port = FALSE;
+BOOL specified_lpt_addr = FALSE;
+int lpt_port = 1;
+int initial_lpt_ctrl = 0;
+WORD lpt_addr = 0x3bc;
+WORD lpt_addr_table[3] = { 0x3bc, 0x378, 0x278 };
+BOOL alternative_cable_l = FALSE;
+BOOL alternative_cable_x = FALSE;
+void write_byteblaster(int port, int data);
+int read_byteblaster(int port);
+#endif
+
+#if PORT==WINDOWS
+#ifndef __BORLANDC__
+WORD lpt_addresses_from_registry[4] = { 0 };
+#endif
+#endif
+
+#if PORT == WINDOWS
+/* variables to manage cached I/O under Windows NT */
+BOOL windows_nt = FALSE;
+int port_io_count = 0;
+HANDLE nt_device_handle = INVALID_HANDLE_VALUE;
+struct PORT_IO_LIST_STRUCT
+{
+ USHORT command;
+ USHORT data;
+} port_io_buffer[PORT_IO_BUFFER_SIZE];
+extern void flush_ports(void);
+BOOL initialize_nt_driver(void);
+#endif
+
+/* function prototypes to allow forward reference */
+extern void delay_loop(long count);
+
+/*
+* This structure stores information about each available vector signal
+*/
+struct VECTOR_LIST_STRUCT
+{
+ char *signal_name;
+ int hardware_bit;
+ int vector_index;
+};
+
+struct VECTOR_LIST_STRUCT vector_list[] =
+{
+ /* add a record here for each vector signal */
+ { "", 0, -1 }
+};
+
+#define VECTOR_SIGNAL_COUNT ((int)(sizeof(vector_list)/sizeof(vector_list[0])))
+
+BOOL verbose = FALSE;
+
+/************************************************************************
+*
+* Customized interface functions for Jam STAPL ByteCode Player I/O:
+*
+* jbi_jtag_io()
+* jbi_message()
+* jbi_delay()
+*/
+
+#ifdef OPENBMC
+
+/*
+ * The threshold (ns) to use spin instead of nanosleep().
+ * Before adding the high resolution timer support, either spin or nanosleep()
+ * will not bring the process wakeup within 10ms. It turns out the system time
+ * update is also controlled by HZ (100).
+ * After I added the high resolution timer support, the spin works as the
+ * system time is updated more frequently. However, nanosleep() solution is
+ * still noticable slower comparing with spin. There could be some kernel
+ * scheduling tweak missing. Did not get time on that yet.
+ * For now, use 10ms as the threshold to determine if spin or nanosleep()
+ * is used.
+ */
+#define SPIN_THRESHOLD (10 * 1000 * 1000)
+#define NANOSEC_IN_SEC (1000 * 1000 * 1000)
+
+static int sleep_ns(unsigned long clk)
+{
+ struct timespec req, rem;
+ int rc = 0;
+ if (clk <= SPIN_THRESHOLD) {
+ struct timespec orig;
+ rc = clock_gettime(CLOCK_MONOTONIC, &req);
+ orig = req;
+ while (!rc && clk) {
+ unsigned long tmp;
+ rc = clock_gettime(CLOCK_MONOTONIC, &rem);
+ tmp = (rem.tv_sec - req.tv_sec) * NANOSEC_IN_SEC;
+ if (rem.tv_nsec >= req.tv_nsec) {
+ tmp += rem.tv_nsec - req.tv_nsec;
+ } else {
+ tmp -= req.tv_nsec - rem.tv_nsec;
+ }
+ if (tmp >= clk) {
+ break;
+ }
+ clk -= tmp;
+ req = rem;
+ }
+ } else {
+ req.tv_sec = 0;
+ req.tv_nsec = clk;
+ while ((rc = nanosleep(&req, &rem)) == -1 && errno == EINTR) {
+ req = rem;
+ }
+ }
+ if (rc == -1) {
+ rc = errno;
+ LOG_ERR(rc, "Failed to sleep %u nanoseconds", clk);
+ }
+ return rc;
+}
+
+int initialize_jtag_gpios()
+{
+ if (gpio_open(&g_gpio_tck, g_tck) || gpio_open(&g_gpio_tms, g_tms)
+ || gpio_open(&g_gpio_tdo, g_tdo) || gpio_open(&g_gpio_tdi, g_tdi)) {
+ return -1;
+ }
+
+ /* change GPIO directions, only TDO is input, all others are output */
+ if (gpio_change_direction(&g_gpio_tck, GPIO_DIRECTION_OUT)
+ || gpio_change_direction(&g_gpio_tms, GPIO_DIRECTION_OUT)
+ || gpio_change_direction(&g_gpio_tdo, GPIO_DIRECTION_IN)
+ || gpio_change_direction(&g_gpio_tdi, GPIO_DIRECTION_OUT)) {
+ return -1;
+ }
+
+ /* set tck, tms, tdi to low */
+ gpio_write(&g_gpio_tck, GPIO_VALUE_LOW);
+ gpio_write(&g_gpio_tms, GPIO_VALUE_LOW);
+ gpio_write(&g_gpio_tdi, GPIO_VALUE_LOW);
+
+ jbi_delay(1);
+
+ LOG_DBG("Opened TCK(GPIO %d), TMS(GPIO %d), TDI(GPIO %d), and TDO(GPIO %d)",
+ g_tck, g_tms, g_tdi, g_tdo);
+
+ return 0;
+}
+
+int jbi_jtag_io(int tms, int tdi, int read_tdo)
+{
+ int tdo = 0;
+
+ if (!jtag_hardware_initialized) {
+ initialize_jtag_gpios();
+ jtag_hardware_initialized = TRUE;
+ }
+
+ gpio_write(&g_gpio_tms, tms ? GPIO_VALUE_HIGH : GPIO_VALUE_LOW);
+ gpio_write(&g_gpio_tdi, tdi ? GPIO_VALUE_HIGH : GPIO_VALUE_LOW);
+
+ /* sleep 500ns to make sure the signal shows up on wire */
+ sleep_ns(500);
+ /*
+ * if we need to read data, the data should be ready from the
+ * previous clock falling edge. Read it now.
+ */
+ if (read_tdo) {
+ tdo = gpio_read(&g_gpio_tdo) == GPIO_VALUE_HIGH ? 1 : 0;
+ }
+
+ /* do rising edge to clock out the data */
+ gpio_write(&g_gpio_tck, GPIO_VALUE_HIGH);
+ sleep_ns(500);
+ /* do falling edge clocking */
+ gpio_write(&g_gpio_tck, GPIO_VALUE_LOW);
+
+ LOG_VER("tms=%d tdi=%d do_read=%d tdo=%d", tms, tdi, read_tdo, tdo);
+
+ return tdo;
+}
+
+#else
+
+int jbi_jtag_io(int tms, int tdi, int read_tdo)
+{
+ int data = 0;
+ int tdo = 0;
+ int i = 0;
+ int result = 0;
+ char ch_data = 0;
+
+ if (!jtag_hardware_initialized)
+ {
+ initialize_jtag_hardware();
+ jtag_hardware_initialized = TRUE;
+ }
+
+ if (specified_com_port)
+ {
+ ch_data = (char)
+ ((tdi ? 0x01 : 0) | (tms ? 0x02 : 0) | 0x60);
+
+ write(com_port, &ch_data, 1);
+
+ if (read_tdo)
+ {
+ ch_data = 0x7e;
+ write(com_port, &ch_data, 1);
+ for (i = 0; (i < 100) && (result != 1); ++i)
+ {
+ result = read(com_port, &ch_data, 1);
+ }
+ if (result == 1)
+ {
+ tdo = ch_data & 0x01;
+ }
+ else
+ {
+ fprintf(stderr, "Error: BitBlaster not responding\n");
+ }
+ }
+
+ ch_data = (char)
+ ((tdi ? 0x01 : 0) | (tms ? 0x02 : 0) | 0x64);
+
+ write(com_port, &ch_data, 1);
+ }
+ else
+ {
+#if PORT == WINDOWS || PORT == DOS
+ data = (alternative_cable_l ? ((tdi ? 0x01 : 0) | (tms ? 0x04 : 0)) :
+ (alternative_cable_x ? ((tdi ? 0x01 : 0) | (tms ? 0x04 : 0) | 0x10) :
+ ((tdi ? 0x40 : 0) | (tms ? 0x02 : 0))));
+
+ write_byteblaster(0, data);
+
+ if (read_tdo)
+ {
+ tdo = read_byteblaster(1);
+ tdo = (alternative_cable_l ? ((tdo & 0x40) ? 1 : 0) :
+ (alternative_cable_x ? ((tdo & 0x10) ? 1 : 0) :
+ ((tdo & 0x80) ? 0 : 1)));
+ }
+
+ write_byteblaster(0, data | (alternative_cable_l ? 0x02 : (alternative_cable_x ? 0x02: 0x01)));
+
+ write_byteblaster(0, data);
+#else
+ /* parallel port interface not available */
+ tdo = 0;
+#endif
+ }
+
+ return (tdo);
+}
+
+#endif
+
+void jbi_message(char *message_text)
+{
+ puts(message_text);
+ fflush(stdout);
+}
+
+void jbi_export_integer(char *key, long value)
+{
+ if (verbose)
+ {
+ printf("Export: key = \"%s\", value = %ld\n", key, value);
+ fflush(stdout);
+ }
+}
+
+#define HEX_LINE_CHARS 72
+#define HEX_LINE_BITS (HEX_LINE_CHARS * 4)
+
+char conv_to_hex(unsigned long value)
+{
+ char c;
+
+ if (value > 9)
+ {
+ c = (char) (value + ('A' - 10));
+ }
+ else
+ {
+ c = (char) (value + '0');
+ }
+
+ return (c);
+}
+
+void jbi_export_boolean_array(char *key, unsigned char *data, long count)
+{
+ char string[HEX_LINE_CHARS + 1];
+ long i, offset;
+ unsigned long size, line, lines, linebits, value, j, k;
+
+ if (verbose)
+ {
+ if (count > HEX_LINE_BITS)
+ {
+ printf("Export: key = \"%s\", %ld bits, value = HEX\n", key, count);
+ lines = (count + (HEX_LINE_BITS - 1)) / HEX_LINE_BITS;
+
+ for (line = 0; line < lines; ++line)
+ {
+ if (line < (lines - 1))
+ {
+ linebits = HEX_LINE_BITS;
+ size = HEX_LINE_CHARS;
+ offset = count - ((line + 1) * HEX_LINE_BITS);
+ }
+ else
+ {
+ linebits = count - ((lines - 1) * HEX_LINE_BITS);
+ size = (linebits + 3) / 4;
+ offset = 0L;
+ }
+
+ string[size] = '\0';
+ j = size - 1;
+ value = 0;
+
+ for (k = 0; k < linebits; ++k)
+ {
+ i = k + offset;
+ if (data[i >> 3] & (1 << (i & 7))) value |= (1 << (i & 3));
+ if ((i & 3) == 3)
+ {
+ string[j] = conv_to_hex(value);
+ value = 0;
+ --j;
+ }
+ }
+ if ((k & 3) > 0) string[j] = conv_to_hex(value);
+
+ printf("%s\n", string);
+ }
+
+ fflush(stdout);
+ }
+ else
+ {
+ size = (count + 3) / 4;
+ string[size] = '\0';
+ j = size - 1;
+ value = 0;
+
+ for (i = 0; i < count; ++i)
+ {
+ if (data[i >> 3] & (1 << (i & 7))) value |= (1 << (i & 3));
+ if ((i & 3) == 3)
+ {
+ string[j] = conv_to_hex(value);
+ value = 0;
+ --j;
+ }
+ }
+ if ((i & 3) > 0) string[j] = conv_to_hex(value);
+
+ printf("Export: key = \"%s\", %ld bits, value = HEX %s\n",
+ key, count, string);
+ fflush(stdout);
+ }
+ }
+}
+
+void jbi_delay(long microseconds)
+{
+#if PORT == WINDOWS
+ /* if Windows NT, flush I/O cache buffer before delay loop */
+ if (windows_nt && (port_io_count > 0)) flush_ports();
+#endif
+
+#ifdef OPENBMC
+ sleep_ns(microseconds * 1000);
+#else
+ delay_loop(microseconds *
+ ((one_ms_delay / 1000L) + ((one_ms_delay % 1000L) ? 1 : 0)));
+#endif
+}
+
+int jbi_vector_map
+(
+ int signal_count,
+ char **signals
+)
+{
+ int signal, vector, ch_index, diff;
+ int matched_count = 0;
+ char l, r;
+
+ for (vector = 0; (vector < VECTOR_SIGNAL_COUNT); ++vector)
+ {
+ vector_list[vector].vector_index = -1;
+ }
+
+ for (signal = 0; signal < signal_count; ++signal)
+ {
+ diff = 1;
+ for (vector = 0; (diff != 0) && (vector < VECTOR_SIGNAL_COUNT);
+ ++vector)
+ {
+ if (vector_list[vector].vector_index == -1)
+ {
+ ch_index = 0;
+ do
+ {
+ l = signals[signal][ch_index];
+ r = vector_list[vector].signal_name[ch_index];
+ diff = (((l >= 'a') && (l <= 'z')) ? (l - ('a' - 'A')) : l)
+ - (((r >= 'a') && (r <= 'z')) ? (r - ('a' - 'A')) : r);
+ ++ch_index;
+ }
+ while ((diff == 0) && (l != '\0') && (r != '\0'));
+
+ if (diff == 0)
+ {
+ vector_list[vector].vector_index = signal;
+ ++matched_count;
+ }
+ }
+ }
+ }
+
+ return (matched_count);
+}
+
+int jbi_vector_io
+(
+ int signal_count,
+ long *dir_vect,
+ long *data_vect,
+ long *capture_vect
+)
+{
+ int signal, vector, bit;
+ int matched_count = 0;
+ int data = 0;
+ int mask = 0;
+ int dir = 0;
+ int i = 0;
+ int result = 0;
+ char ch_data = 0;
+
+ if (!jtag_hardware_initialized)
+ {
+ initialize_jtag_hardware();
+ jtag_hardware_initialized = TRUE;
+ }
+
+ /*
+ * Collect information about output signals
+ */
+ for (vector = 0; vector < VECTOR_SIGNAL_COUNT; ++vector)
+ {
+ signal = vector_list[vector].vector_index;
+
+ if ((signal >= 0) && (signal < signal_count))
+ {
+ bit = (1 << vector_list[vector].hardware_bit);
+
+ mask |= bit;
+ if (data_vect[signal >> 5] & (1L << (signal & 0x1f))) data |= bit;
+ if (dir_vect[signal >> 5] & (1L << (signal & 0x1f))) dir |= bit;
+
+ ++matched_count;
+ }
+ }
+
+ /*
+ * Write outputs to hardware interface, if any
+ */
+ if (dir != 0)
+ {
+ if (specified_com_port)
+ {
+ ch_data = (char) (((data >> 6) & 0x01) | (data & 0x02) |
+ ((data << 2) & 0x04) | ((data << 3) & 0x08) | 0x60);
+ write(com_port, &ch_data, 1);
+ }
+ else
+ {
+#if PORT == WINDOWS || PORT == DOS
+
+ write_byteblaster(0, data);
+
+#endif
+ }
+ }
+
+ /*
+ * Read the input signals and save information in capture_vect[]
+ */
+ if ((dir != mask) && (capture_vect != NULL))
+ {
+ if (specified_com_port)
+ {
+ ch_data = 0x7e;
+ write(com_port, &ch_data, 1);
+ for (i = 0; (i < 100) && (result != 1); ++i)
+ {
+ result = read(com_port, &ch_data, 1);
+ }
+ if (result == 1)
+ {
+ data = ((ch_data << 7) & 0x80) | ((ch_data << 3) & 0x10);
+ }
+ else
+ {
+ fprintf(stderr, "Error: BitBlaster not responding\n");
+ }
+ }
+ else
+ {
+#if PORT == WINDOWS || PORT == DOS
+
+ data = read_byteblaster(1) ^ 0x80; /* parallel port inverts bit 7 */
+
+#endif
+ }
+
+ for (vector = 0; vector < VECTOR_SIGNAL_COUNT; ++vector)
+ {
+ signal = vector_list[vector].vector_index;
+
+ if ((signal >= 0) && (signal < signal_count))
+ {
+ bit = (1 << vector_list[vector].hardware_bit);
+
+ if ((dir & bit) == 0) /* if it is an input signal... */
+ {
+ if (data & bit)
+ {
+ capture_vect[signal >> 5] |= (1L << (signal & 0x1f));
+ }
+ else
+ {
+ capture_vect[signal >> 5] &= ~(unsigned long)
+ (1L << (signal & 0x1f));
+ }
+ }
+ }
+ }
+ }
+
+ return (matched_count);
+}
+
+void *jbi_malloc(unsigned int size)
+{
+ unsigned int n_bytes_to_allocate =
+#if defined(USE_STATIC_MEMORY) || defined(MEM_TRACKER)
+ sizeof(unsigned int) +
+#endif /* USE_STATIC_MEMORY || MEM_TRACKER */
+#if defined(MEM_TRACKER)
+ (2 * sizeof(DWORD)) +
+#endif /* MEM_TRACKER */
+ (POINTER_ALIGNMENT * ((size + POINTER_ALIGNMENT - 1) / POINTER_ALIGNMENT));
+
+ unsigned char *ptr = 0;
+
+
+#if defined(MEM_TRACKER)
+ if ((n_bytes_allocated + n_bytes_to_allocate) > peak_memory_usage)
+ {
+ peak_memory_usage = n_bytes_allocated + n_bytes_to_allocate;
+ }
+ if ((n_allocations + 1) > peak_allocations)
+ {
+ peak_allocations = n_allocations + 1;
+ }
+#endif /* MEM_TRACKER */
+
+#if defined(USE_STATIC_MEMORY)
+ if ((n_bytes_allocated + n_bytes_to_allocate) <= N_STATIC_MEMORY_BYTES)
+ {
+ ptr = (&(static_memory_heap[n_bytes_allocated]));
+ }
+#else /* USE_STATIC_MEMORY */
+ ptr = (unsigned char *) malloc(n_bytes_to_allocate);
+#endif /* USE_STATIC_MEMORY */
+
+#if defined(USE_STATIC_MEMORY) || defined(MEM_TRACKER)
+ if (ptr != 0)
+ {
+ unsigned int i = 0;
+
+#if defined(MEM_TRACKER)
+ for (i = 0; i < sizeof(DWORD); ++i)
+ {
+ *ptr = (unsigned char) (BEGIN_GUARD >> (8 * i));
+ ++ptr;
+ }
+#endif /* MEM_TRACKER */
+
+ for (i = 0; i < sizeof(unsigned int); ++i)
+ {
+ *ptr = (unsigned char) (size >> (8 * i));
+ ++ptr;
+ }
+
+#if defined(MEM_TRACKER)
+ for (i = 0; i < sizeof(DWORD); ++i)
+ {
+ *(ptr + size + i) = (unsigned char) (END_GUARD >> (8 * i));
+ /* don't increment ptr */
+ }
+
+ ++n_allocations;
+#endif /* MEM_TRACKER */
+
+ n_bytes_allocated += n_bytes_to_allocate;
+ }
+#endif /* USE_STATIC_MEMORY || MEM_TRACKER */
+
+ return ptr;
+}
+
+void jbi_free(void *ptr)
+{
+ if
+ (
+#if defined(MEM_TRACKER)
+ (n_allocations > 0) &&
+#endif /* MEM_TRACKER */
+ (ptr != 0)
+ )
+ {
+ unsigned char *tmp_ptr = (unsigned char *) ptr;
+
+#if defined(USE_STATIC_MEMORY) || defined(MEM_TRACKER)
+ unsigned int n_bytes_to_free = 0;
+ unsigned int i = 0;
+ unsigned int size = 0;
+#endif /* USE_STATIC_MEMORY || MEM_TRACKER */
+#if defined(MEM_TRACKER)
+ DWORD begin_guard = 0;
+ DWORD end_guard = 0;
+
+
+ tmp_ptr -= sizeof(DWORD);
+#endif /* MEM_TRACKER */
+#if defined(USE_STATIC_MEMORY) || defined(MEM_TRACKER)
+ tmp_ptr -= sizeof(unsigned int);
+#endif /* USE_STATIC_MEMORY || MEM_TRACKER */
+ ptr = tmp_ptr;
+
+#if defined(MEM_TRACKER)
+ for (i = 0; i < sizeof(DWORD); ++i)
+ {
+ begin_guard |= (((DWORD)(*tmp_ptr)) << (8 * i));
+ ++tmp_ptr;
+ }
+#endif /* MEM_TRACKER */
+
+#if defined(USE_STATIC_MEMORY) || defined(MEM_TRACKER)
+ for (i = 0; i < sizeof(unsigned int); ++i)
+ {
+ size |= (((unsigned int)(*tmp_ptr)) << (8 * i));
+ ++tmp_ptr;
+ }
+#endif /* USE_STATIC_MEMORY || MEM_TRACKER */
+
+#if defined(MEM_TRACKER)
+ tmp_ptr += size;
+
+ for (i = 0; i < sizeof(DWORD); ++i)
+ {
+ end_guard |= (((DWORD)(*tmp_ptr)) << (8 * i));
+ ++tmp_ptr;
+ }
+
+ if ((begin_guard != BEGIN_GUARD) || (end_guard != END_GUARD))
+ {
+ fprintf(stderr, "Error: memory corruption detected for allocation #%d... bad %s guard\n",
+ n_allocations, (begin_guard != BEGIN_GUARD) ? "begin" : "end");
+ }
+
+ --n_allocations;
+#endif /* MEM_TRACKER */
+
+#if defined(USE_STATIC_MEMORY) || defined(MEM_TRACKER)
+ n_bytes_to_free =
+#if defined(MEM_TRACKER)
+ (2 * sizeof(DWORD)) +
+#endif /* MEM_TRACKER */
+ sizeof(unsigned int) +
+ (POINTER_ALIGNMENT * ((size + POINTER_ALIGNMENT - 1) / POINTER_ALIGNMENT));
+#endif /* USE_STATIC_MEMORY || MEM_TRACKER */
+
+#if defined(USE_STATIC_MEMORY)
+ if ((((unsigned long) ptr - (unsigned long) static_memory_heap) + n_bytes_to_free) == (unsigned long) n_bytes_allocated)
+ {
+ n_bytes_allocated -= n_bytes_to_free;
+ }
+#if defined(MEM_TRACKER)
+ else
+ {
+ n_bytes_not_recovered += n_bytes_to_free;
+ }
+#endif /* MEM_TRACKER */
+#else /* USE_STATIC_MEMORY */
+#if defined(MEM_TRACKER)
+ n_bytes_allocated -= n_bytes_to_free;
+#endif /* MEM_TRACKER */
+ free(ptr);
+#endif /* USE_STATIC_MEMORY */
+ }
+#if defined(MEM_TRACKER)
+ else
+ {
+ if (ptr != 0)
+ {
+ fprintf(stderr, "Error: attempt to free unallocated memory\n");
+ }
+ }
+#endif /* MEM_TRACKER */
+}
+
+/************************************************************************
+*
+* get_tick_count() -- Get system tick count in milliseconds
+*
+* for DOS, use BIOS function _bios_timeofday()
+* for WINDOWS use GetTickCount() function
+* for UNIX use clock() system function
+*/
+DWORD get_tick_count(void)
+{
+ DWORD tick_count = 0L;
+
+#if PORT == WINDOWS
+ tick_count = GetTickCount();
+#elif PORT == DOS
+ _bios_timeofday(_TIME_GETCLOCK, (long *)&tick_count);
+ tick_count *= 55L; /* convert to milliseconds */
+#else
+ /* assume clock() function returns microseconds */
+ tick_count = (DWORD) (clock() / 1000L);
+#endif
+
+ return (tick_count);
+}
+
+#define DELAY_SAMPLES 10
+#define DELAY_CHECK_LOOPS 10000
+
+void calibrate_delay(void)
+{
+ int sample = 0;
+ int count = 0;
+ DWORD tick_count1 = 0L;
+ DWORD tick_count2 = 0L;
+
+ one_ms_delay = 0L;
+
+#if PORT == WINDOWS || PORT == DOS || defined(OPENBMC)
+ for (sample = 0; sample < DELAY_SAMPLES; ++sample)
+ {
+ count = 0;
+ tick_count1 = get_tick_count();
+ while ((tick_count2 = get_tick_count()) == tick_count1) {};
+ do { delay_loop(DELAY_CHECK_LOOPS); count++; } while
+ ((tick_count1 = get_tick_count()) == tick_count2);
+ one_ms_delay += ((DELAY_CHECK_LOOPS * (DWORD)count) /
+ (tick_count1 - tick_count2));
+ }
+
+ one_ms_delay /= DELAY_SAMPLES;
+#else
+ /* This is system-dependent! Update this number for target system */
+ one_ms_delay = 1000L;
+#endif
+}
+
+char *error_text[] =
+{
+/* JBIC_SUCCESS 0 */ "success",
+/* JBIC_OUT_OF_MEMORY 1 */ "out of memory",
+/* JBIC_IO_ERROR 2 */ "file access error",
+/* JAMC_SYNTAX_ERROR 3 */ "syntax error",
+/* JBIC_UNEXPECTED_END 4 */ "unexpected end of file",
+/* JBIC_UNDEFINED_SYMBOL 5 */ "undefined symbol",
+/* JAMC_REDEFINED_SYMBOL 6 */ "redefined symbol",
+/* JBIC_INTEGER_OVERFLOW 7 */ "integer overflow",
+/* JBIC_DIVIDE_BY_ZERO 8 */ "divide by zero",
+/* JBIC_CRC_ERROR 9 */ "CRC mismatch",
+/* JBIC_INTERNAL_ERROR 10 */ "internal error",
+/* JBIC_BOUNDS_ERROR 11 */ "bounds error",
+/* JAMC_TYPE_MISMATCH 12 */ "type mismatch",
+/* JAMC_ASSIGN_TO_CONST 13 */ "assignment to constant",
+/* JAMC_NEXT_UNEXPECTED 14 */ "NEXT unexpected",
+/* JAMC_POP_UNEXPECTED 15 */ "POP unexpected",
+/* JAMC_RETURN_UNEXPECTED 16 */ "RETURN unexpected",
+/* JAMC_ILLEGAL_SYMBOL 17 */ "illegal symbol name",
+/* JBIC_VECTOR_MAP_FAILED 18 */ "vector signal name not found",
+/* JBIC_USER_ABORT 19 */ "execution cancelled",
+/* JBIC_STACK_OVERFLOW 20 */ "stack overflow",
+/* JBIC_ILLEGAL_OPCODE 21 */ "illegal instruction code",
+/* JAMC_PHASE_ERROR 22 */ "phase error",
+/* JAMC_SCOPE_ERROR 23 */ "scope error",
+/* JBIC_ACTION_NOT_FOUND 24 */ "action not found",
+};
+
+#define MAX_ERROR_CODE (int)((sizeof(error_text)/sizeof(error_text[0]))+1)
+
+/************************************************************************/
+
+int main(int argc, char **argv)
+{
+ BOOL help = FALSE;
+ BOOL error = FALSE;
+ char *filename = NULL;
+ long offset = 0L;
+ long error_address = 0L;
+ JBI_RETURN_TYPE crc_result = JBIC_SUCCESS;
+ JBI_RETURN_TYPE exec_result = JBIC_SUCCESS;
+ unsigned short expected_crc = 0;
+ unsigned short actual_crc = 0;
+ char key[33] = {0};
+ char value[257] = {0};
+ int exit_status = 0;
+ int arg = 0;
+ int exit_code = 0;
+ int format_version = 0;
+ time_t start_time = 0;
+ time_t end_time = 0;
+ int time_delta = 0;
+ char *workspace = NULL;
+ char *action = NULL;
+ char *init_list[10];
+ int init_count = 0;
+ FILE *fp = NULL;
+ struct stat sbuf;
+ long workspace_size = 0;
+ char *exit_string = NULL;
+ int reset_jtag = 1;
+ int execute_program = 1;
+ int action_count = 0;
+ int procedure_count = 0;
+ int index = 0;
+ char *action_name = NULL;
+ char *description = NULL;
+ JBI_PROCINFO *procedure_list = NULL;
+ JBI_PROCINFO *procptr = NULL;
+
+ verbose = FALSE;
+
+ init_list[0] = NULL;
+
+ /* print out the version string and copyright message */
+ fprintf(stderr, "Jam STAPL ByteCode Player Version 2.2\nCopyright (C) 1998-2001 Altera Corporation\n\n");
+
+ for (arg = 1; arg < argc; arg++)
+ {
+#if PORT == UNIX
+ if (argv[arg][0] == '-')
+#else
+ if ((argv[arg][0] == '-') || (argv[arg][0] == '/'))
+#endif
+ {
+ switch(toupper(argv[arg][1]))
+ {
+ case 'A': /* set action name */
+ if (action == NULL)
+ {
+ action = &argv[arg][2];
+ }
+ else
+ {
+ error = TRUE;
+ }
+ break;
+
+#if PORT == WINDOWS || PORT == DOS
+ case 'C': /* Use alternative ISP download cable */
+ if(toupper(argv[arg][2]) == 'L')
+ alternative_cable_l = TRUE;
+ else if(toupper(argv[arg][2]) == 'X')
+ alternative_cable_x = TRUE;
+ break;
+#endif
+
+ case 'D': /* initialization list */
+ if (argv[arg][2] == '"')
+ {
+ init_list[init_count] = &argv[arg][3];
+ }
+ else
+ {
+ init_list[init_count] = &argv[arg][2];
+ }
+ init_list[++init_count] = NULL;
+ break;
+
+#if PORT == WINDOWS || PORT == DOS
+ case 'P': /* set LPT port address */
+ specified_lpt_port = TRUE;
+ if (sscanf(&argv[arg][2], "%d", &lpt_port) != 1) error = TRUE;
+ if ((lpt_port < 1) || (lpt_port > 3)) error = TRUE;
+ if (error)
+ {
+ if (sscanf(&argv[arg][2], "%x", &lpt_port) == 1)
+ {
+ if ((lpt_port == 0x3bc) ||
+ (lpt_port == 0x378) ||
+ (lpt_port == 0x278))
+ {
+ error = FALSE;
+ specified_lpt_addr = TRUE;
+ lpt_addr = (WORD) lpt_port;
+ lpt_port = 1;
+ }
+ }
+ }
+ break;
+#endif
+
+ case 'R': /* don't reset the JTAG chain after use */
+ reset_jtag = 0;
+ break;
+
+#ifdef OPENBMC
+ case 'G': /* GPIO directory */
+ switch (toupper(argv[arg][2])) {
+ case 'C':
+ g_tck = atoi(&argv[arg][3]);
+ break;
+ case 'S':
+ g_tms = atoi(&argv[arg][3]);
+ break;
+ case 'I':
+ g_tdi = atoi(&argv[arg][3]);
+ break;
+ case 'O':
+ g_tdo = atoi(&argv[arg][3]);
+ break;
+ }
+ break;
+#else
+ case 'S': /* set serial port address */
+ serial_port_name = &argv[arg][2];
+ specified_com_port = TRUE;
+ break;
+#endif
+
+ case 'M': /* set memory size */
+ if (sscanf(&argv[arg][2], "%ld", &workspace_size) != 1)
+ error = TRUE;
+ if (workspace_size == 0) error = TRUE;
+ break;
+
+ case 'H': /* help */
+ help = TRUE;
+ break;
+
+ case 'V': /* verbose */
+ verbose = TRUE;
+ break;
+
+ case 'I': /* show info only, do not execute */
+ verbose = TRUE;
+ execute_program = 0;
+ break;
+
+ default:
+ error = TRUE;
+ break;
+ }
+ }
+ else
+ {
+ /* it's a filename */
+ if (filename == NULL)
+ {
+ filename = argv[arg];
+ }
+ else
+ {
+ /* error -- we already found a filename */
+ error = TRUE;
+ }
+ }
+
+ if (error)
+ {
+ fprintf(stderr, "Illegal argument: \"%s\"\n", argv[arg]);
+ help = TRUE;
+ error = FALSE;
+ }
+ }
+
+#if PORT == WINDOWS || PORT == DOS
+ if (specified_lpt_port && specified_com_port)
+ {
+ fprintf(stderr, "Error: -s and -p options may not be used together\n\n");
+ help = TRUE;
+ }
+#endif
+
+#ifdef OPENBMC
+ if (execute_program) {
+ if (g_tck == -1 || g_tms == -1 || g_tdo == -1 || g_tdi == -1) {
+ fprintf(stderr, "Error: -gc, -gs, -gi, and -go must be specified\n");
+ help = TRUE;
+ }
+ }
+#endif
+
+ if (help || (filename == NULL))
+ {
+ fprintf(stderr, "Usage: jbi [options] <filename>\n");
+ fprintf(stderr, "\nAvailable options:\n");
+ fprintf(stderr, " -h : show help message\n");
+ fprintf(stderr, " -v : show verbose messages\n");
+ fprintf(stderr, " -i : show file info only - does not execute any action\n");
+ fprintf(stderr, " -a<action> : specify an action name (Jam STAPL)\n");
+ fprintf(stderr, " -d<var=val> : initialize variable to specified value (Jam 1.1)\n");
+ fprintf(stderr, " -d<proc=1> : enable optional procedure (Jam STAPL)\n");
+ fprintf(stderr, " -d<proc=0> : disable recommended procedure (Jam STAPL)\n");
+#if PORT == WINDOWS || PORT == DOS
+ fprintf(stderr, " -p<port> : parallel port number or address (for ByteBlaster)\n");
+ fprintf(stderr, " -c<cable> : alternative download cable compatibility: -cl or -cx\n");
+#endif
+#ifdef OPENBMC
+ fprintf(stderr, " -gc<clock> : GPIO directory for TCK\n");
+ fprintf(stderr, " -gs<clock> : GPIO directory for TMS\n");
+ fprintf(stderr, " -gi<clock> : GPIO directory for TDI\n");
+ fprintf(stderr, " -go<clock> : GPIO directory for TDO\n");
+#else
+ fprintf(stderr, " -s<port> : serial port name (for BitBlaster)\n");
+#endif
+ fprintf(stderr, " -r : don't reset JTAG TAP after use\n");
+ exit_status = 1;
+ }
+ else if ((workspace_size > 0) &&
+ ((workspace = (char *) jbi_malloc((size_t) workspace_size)) == NULL))
+ {
+ fprintf(stderr, "Error: can't allocate memory (%d Kbytes)\n",
+ (int) (workspace_size / 1024L));
+ exit_status = 1;
+ }
+ else if (access(filename, 0) != 0)
+ {
+ fprintf(stderr, "Error: can't access file \"%s\"\n", filename);
+ exit_status = 1;
+ }
+ else
+ {
+ /* get length of file */
+ if (stat(filename, &sbuf) == 0) file_length = sbuf.st_size;
+
+ if ((fp = fopen(filename, "rb")) == NULL)
+ {
+ fprintf(stderr, "Error: can't open file \"%s\"\n", filename);
+ exit_status = 1;
+ }
+ else
+ {
+ /*
+ * Read entire file into a buffer
+ */
+#if PORT == DOS
+ int pages = 1 + (int) (file_length >> 14L);
+ int page;
+ file_buffer = (unsigned char **) jbi_malloc(
+ (size_t) (pages * sizeof(char *)));
+
+ for (page = 0; page < pages; ++page)
+ {
+ /* allocate enough 16K blocks to store the file */
+ file_buffer[page] = (unsigned char *) jbi_malloc (0x4000);
+ if (file_buffer[page] == NULL)
+ {
+ /* flag error and break out of loop */
+ file_buffer = NULL;
+ page = pages;
+ }
+ }
+#else
+ file_buffer = (unsigned char *) jbi_malloc((size_t) file_length);
+#endif
+
+ if (file_buffer == NULL)
+ {
+ fprintf(stderr, "Error: can't allocate memory (%d Kbytes)\n",
+ (int) (file_length / 1024L));
+ exit_status = 1;
+ }
+ else
+ {
+#if PORT == DOS
+ int pages = 1 + (int) (file_length >> 14L);
+ int page;
+ size_t page_size = 0x4000;
+ for (page = 0; (page < pages) && (exit_status == 0); ++page)
+ {
+ if (page == (pages - 1))
+ {
+ /* last page may not be full 16K bytes */
+ page_size = (size_t) (file_length & 0x3fffL);
+ }
+ if (fread(file_buffer[page], 1, page_size, fp) != page_size)
+ {
+ fprintf(stderr, "Error reading file \"%s\"\n", filename);
+ exit_status = 1;
+ }
+ }
+#else
+ if (fread(file_buffer, 1, (size_t) file_length, fp) !=
+ (size_t) file_length)
+ {
+ fprintf(stderr, "Error reading file \"%s\"\n", filename);
+ exit_status = 1;
+ }
+#endif
+ }
+
+ fclose(fp);
+ }
+
+ if (exit_status == 0)
+ {
+ /*
+ * Get Operating System type
+ */
+#if PORT == WINDOWS
+ windows_nt = !(GetVersion() & 0x80000000);
+#endif
+
+ /*
+ * Calibrate the delay loop function
+ */
+ calibrate_delay();
+
+ /*
+ * Check CRC
+ */
+ crc_result = jbi_check_crc(file_buffer, file_length,
+ &expected_crc, &actual_crc);
+
+ if (verbose || (crc_result == JBIC_CRC_ERROR))
+ {
+ switch (crc_result)
+ {
+ case JBIC_SUCCESS:
+ printf("CRC matched: CRC value = %04X\n", actual_crc);
+ break;
+
+ case JBIC_CRC_ERROR:
+ printf("CRC mismatch: expected %04X, actual %04X\n",
+ expected_crc, actual_crc);
+ break;
+
+ case JBIC_UNEXPECTED_END:
+ printf("Expected CRC not found, actual CRC value = %04X\n",
+ actual_crc);
+ break;
+
+ case JBIC_IO_ERROR:
+ printf("Error: File format is not recognized.\n");
+ exit(1);
+ break;
+
+ default:
+ printf("CRC function returned error code %d\n", crc_result);
+ break;
+ }
+ }
+
+ if (verbose)
+ {
+ /*
+ * Display file format version
+ */
+ jbi_get_file_info(file_buffer, file_length,
+ &format_version, &action_count, &procedure_count);
+
+ printf("File format is %s ByteCode format\n",
+ (format_version == 2) ? "Jam STAPL" : "pre-standardized Jam 1.1");
+
+ /*
+ * Dump out NOTE fields
+ */
+ while (jbi_get_note(file_buffer, file_length,
+ &offset, key, value, 256) == 0)
+ {
+ printf("NOTE \"%s\" = \"%s\"\n", key, value);
+ }
+
+ /*
+ * Dump the action table
+ */
+ if ((format_version == 2) && (action_count > 0))
+ {
+ printf("\nActions available in this file:\n");
+
+ for (index = 0; index < action_count; ++index)
+ {
+ jbi_get_action_info(file_buffer, file_length,
+ index, &action_name, &description, &procedure_list);
+
+ if (description == NULL)
+ {
+ printf("%s\n", action_name);
+ }
+ else
+ {
+ printf("%s \"%s\"\n", action_name, description);
+ }
+
+#if PORT == DOS
+ if (action_name != NULL) jbi_free(action_name);
+ if (description != NULL) jbi_free(description);
+#endif
+
+ procptr = procedure_list;
+ while (procptr != NULL)
+ {
+ if (procptr->attributes != 0)
+ {
+ printf(" %s (%s)\n", procptr->name,
+ (procptr->attributes == 1) ?
+ "optional" : "recommended");
+ }
+
+#if PORT == DOS
+ if (procptr->name != NULL) jbi_free(procptr->name);
+#endif
+
+ procedure_list = procptr->next;
+ jbi_free(procptr);
+ procptr = procedure_list;
+ }
+ }
+
+ /* add a blank line before execution messages */
+ if (execute_program) printf("\n");
+ }
+ }
+
+ if (execute_program)
+ {
+ /*
+ * Execute the Jam STAPL ByteCode program
+ */
+ time(&start_time);
+ exec_result = jbi_execute(file_buffer, file_length, workspace,
+ workspace_size, action, init_list, reset_jtag,
+ &error_address, &exit_code, &format_version);
+ time(&end_time);
+
+ if (exec_result == JBIC_SUCCESS)
+ {
+ if (format_version == 2)
+ {
+ switch (exit_code)
+ {
+ case 0: exit_string = "Success"; break;
+ case 1: exit_string = "Checking chain failure"; break;
+ case 2: exit_string = "Reading IDCODE failure"; break;
+ case 3: exit_string = "Reading USERCODE failure"; break;
+ case 4: exit_string = "Reading UESCODE failure"; break;
+ case 5: exit_string = "Entering ISP failure"; break;
+ case 6: exit_string = "Unrecognized device"; break;
+ case 7: exit_string = "Device revision is not supported"; break;
+ case 8: exit_string = "Erase failure"; break;
+ case 9: exit_string = "Device is not blank"; break;
+ case 10: exit_string = "Device programming failure"; break;
+ case 11: exit_string = "Device verify failure"; break;
+ case 12: exit_string = "Read failure"; break;
+ case 13: exit_string = "Calculating checksum failure"; break;
+ case 14: exit_string = "Setting security bit failure"; break;
+ case 15: exit_string = "Querying security bit failure"; break;
+ case 16: exit_string = "Exiting ISP failure"; break;
+ case 17: exit_string = "Performing system test failure"; break;
+ default: exit_string = "Unknown exit code"; break;
+ }
+ }
+ else
+ {
+ switch (exit_code)
+ {
+ case 0: exit_string = "Success"; break;
+ case 1: exit_string = "Illegal initialization values"; break;
+ case 2: exit_string = "Unrecognized device"; break;
+ case 3: exit_string = "Device revision is not supported"; break;
+ case 4: exit_string = "Device programming failure"; break;
+ case 5: exit_string = "Device is not blank"; break;
+ case 6: exit_string = "Device verify failure"; break;
+ case 7: exit_string = "SRAM configuration failure"; break;
+ default: exit_string = "Unknown exit code"; break;
+ }
+ }
+
+ printf("Exit code = %d... %s\n", exit_code, exit_string);
+ }
+ else if ((format_version == 2) &&
+ (exec_result == JBIC_ACTION_NOT_FOUND))
+ {
+ if ((action == NULL) || (*action == '\0'))
+ {
+ printf("Error: no action specified for Jam STAPL file.\nProgram terminated.\n");
+ }
+ else
+ {
+ printf("Error: action \"%s\" is not supported for this Jam STAPL file.\nProgram terminated.\n", action);
+ }
+ }
+ else if (exec_result < MAX_ERROR_CODE)
+ {
+ printf("Error at address %ld: %s.\nProgram terminated.\n",
+ error_address, error_text[exec_result]);
+ }
+ else
+ {
+ printf("Unknown error code %ld\n", exec_result);
+ }
+
+ /*
+ * Print out elapsed time
+ */
+ if (verbose)
+ {
+ time_delta = (int) (end_time - start_time);
+ printf("Elapsed time = %02u:%02u:%02u\n",
+ time_delta / 3600, /* hours */
+ (time_delta % 3600) / 60, /* minutes */
+ time_delta % 60); /* seconds */
+ }
+ }
+ }
+ }
+
+ if (jtag_hardware_initialized) close_jtag_hardware();
+
+ if (workspace != NULL) jbi_free(workspace);
+ if (file_buffer != NULL) jbi_free(file_buffer);
+
+#if defined(MEM_TRACKER)
+ if (verbose)
+ {
+#if defined(USE_STATIC_MEMORY)
+ fprintf(stdout, "Memory Usage Info: static memory size = %ud (%dKB)\n", N_STATIC_MEMORY_BYTES, N_STATIC_MEMORY_KBYTES);
+#endif /* USE_STATIC_MEMORY */
+ fprintf(stdout, "Memory Usage Info: peak memory usage = %ud (%dKB)\n", peak_memory_usage, (peak_memory_usage + 1023) / 1024);
+ fprintf(stdout, "Memory Usage Info: peak allocations = %d\n", peak_allocations);
+#if defined(USE_STATIC_MEMORY)
+ if ((n_bytes_allocated - n_bytes_not_recovered) != 0)
+ {
+ fprintf(stdout, "Memory Usage Info: bytes still allocated = %d (%dKB)\n", (n_bytes_allocated - n_bytes_not_recovered), ((n_bytes_allocated - n_bytes_not_recovered) + 1023) / 1024);
+ }
+#else /* USE_STATIC_MEMORY */
+ if (n_bytes_allocated != 0)
+ {
+ fprintf(stdout, "Memory Usage Info: bytes still allocated = %d (%dKB)\n", n_bytes_allocated, (n_bytes_allocated + 1023) / 1024);
+ }
+#endif /* USE_STATIC_MEMORY */
+ if (n_allocations != 0)
+ {
+ fprintf(stdout, "Memory Usage Info: allocations not freed = %d\n", n_allocations);
+ }
+ }
+#endif /* MEM_TRACKER */
+
+ return (exit_status);
+}
+
+#if PORT==WINDOWS
+#ifndef __BORLANDC__
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+*
+* SEARCH_DYN_DATA
+*
+* Searches recursively in Windows 95/98 Registry for parallel port info
+* under HKEY_DYN_DATA registry key. Called by search_local_machine().
+*/
+void search_dyn_data
+(
+ char *dd_path,
+ char *hardware_key,
+ int lpt
+)
+{
+ DWORD index;
+ DWORD size;
+ DWORD type;
+ LONG result;
+ HKEY key;
+ int length;
+ WORD address;
+ char buffer[1024];
+ FILETIME last_write = {0};
+ WORD *word_ptr;
+ int i;
+
+ length = strlen(dd_path);
+
+ if (RegOpenKeyEx(
+ HKEY_DYN_DATA,
+ dd_path,
+ 0L,
+ KEY_READ,
+ &key)
+ == ERROR_SUCCESS)
+ {
+ size = 1023;
+
+ if (RegQueryValueEx(
+ key,
+ "HardWareKey",
+ NULL,
+ &type,
+ (unsigned char *) buffer,
+ &size)
+ == ERROR_SUCCESS)
+ {
+ if ((type == REG_SZ) && (stricmp(buffer, hardware_key) == 0))
+ {
+ size = 1023;
+
+ if (RegQueryValueEx(
+ key,
+ "Allocation",
+ NULL,
+ &type,
+ (unsigned char *) buffer,
+ &size)
+ == ERROR_SUCCESS)
+ {
+ /*
+ * By "inspection", I have found five cases: size 32, 48,
+ * 56, 60, and 80 bytes. The port address seems to be
+ * located at different offsets in the buffer for these
+ * five cases, as shown below. If a valid port address
+ * is not found, or the size is not one of these known
+ * sizes, then I search through the entire buffer and
+ * look for a value which is a valid port address.
+ */
+
+ word_ptr = (WORD *) buffer;
+
+ if ((type == REG_BINARY) && (size == 32))
+ {
+ address = word_ptr[10];
+ }
+ else if ((type == REG_BINARY) && (size == 48))
+ {
+ address = word_ptr[18];
+ }
+ else if ((type == REG_BINARY) && (size == 56))
+ {
+ address = word_ptr[22];
+ }
+ else if ((type == REG_BINARY) && (size == 60))
+ {
+ address = word_ptr[24];
+ }
+ else if ((type == REG_BINARY) && (size == 80))
+ {
+ address = word_ptr[24];
+ }
+ else address = 0;
+
+ /* if not found, search through entire buffer */
+ i = 0;
+ while ((i < (int) (size / 2)) &&
+ (address != 0x278) &&
+ (address != 0x27C) &&
+ (address != 0x378) &&
+ (address != 0x37C) &&
+ (address != 0x3B8) &&
+ (address != 0x3BC))
+ {
+ if ((word_ptr[i] == 0x278) ||
+ (word_ptr[i] == 0x27C) ||
+ (word_ptr[i] == 0x378) ||
+ (word_ptr[i] == 0x37C) ||
+ (word_ptr[i] == 0x3B8) ||
+ (word_ptr[i] == 0x3BC))
+ {
+ address = word_ptr[i];
+ }
+ ++i;
+ }
+
+ if ((address == 0x278) ||
+ (address == 0x27C) ||
+ (address == 0x378) ||
+ (address == 0x37C) ||
+ (address == 0x3B8) ||
+ (address == 0x3BC))
+ {
+ lpt_addresses_from_registry[lpt] = address;
+ }
+ }
+ }
+ }
+
+ index = 0;
+
+ do
+ {
+ size = 1023;
+
+ result = RegEnumKeyEx(
+ key,
+ index++,
+ buffer,
+ &size,
+ NULL,
+ NULL,
+ NULL,
+ &last_write);
+
+ if (result == ERROR_SUCCESS)
+ {
+ dd_path[length] = '\\';
+ dd_path[length + 1] = '\0';
+ strcpy(&dd_path[length + 1], buffer);
+
+ search_dyn_data(dd_path, hardware_key, lpt);
+
+ dd_path[length] = '\0';
+ }
+ }
+ while (result == ERROR_SUCCESS);
+
+ RegCloseKey(key);
+ }
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+*
+* SEARCH_LOCAL_MACHINE
+*
+* Searches recursively in Windows 95/98 Registry for parallel port info
+* under HKEY_LOCAL_MACHINE\Enum. When parallel port is found, calls
+* search_dyn_data() to get the port address.
+*/
+void search_local_machine
+(
+ char *lm_path,
+ char *dd_path
+)
+{
+ DWORD index;
+ DWORD size;
+ DWORD type;
+ LONG result;
+ HKEY key;
+ int length;
+ char buffer[1024];
+ FILETIME last_write = {0};
+
+ length = strlen(lm_path);
+
+ if (RegOpenKeyEx(
+ HKEY_LOCAL_MACHINE,
+ lm_path,
+ 0L,
+ KEY_READ,
+ &key)
+ == ERROR_SUCCESS)
+ {
+ size = 1023;
+
+ if (RegQueryValueEx(
+ key,
+ "PortName",
+ NULL,
+ &type,
+ (unsigned char *) buffer,
+ &size)
+ == ERROR_SUCCESS)
+ {
+ if ((type == REG_SZ) &&
+ (size == 5) &&
+ (buffer[0] == 'L') &&
+ (buffer[1] == 'P') &&
+ (buffer[2] == 'T') &&
+ (buffer[3] >= '1') &&
+ (buffer[3] <= '4') &&
+ (buffer[4] == '\0'))
+ {
+ /* we found the entry in HKEY_LOCAL_MACHINE, now we need to */
+ /* find the corresponding entry under HKEY_DYN_DATA. */
+ /* add 5 to lm_path to skip over "Enum" and backslash */
+ search_dyn_data(dd_path, &lm_path[5], (buffer[3] - '1'));
+ }
+ }
+
+ index = 0;
+
+ do
+ {
+ size = 1023;
+
+ result = RegEnumKeyEx(
+ key,
+ index++,
+ buffer,
+ &size,
+ NULL,
+ NULL,
+ NULL,
+ &last_write);
+
+ if (result == ERROR_SUCCESS)
+ {
+ lm_path[length] = '\\';
+ lm_path[length + 1] = '\0';
+ strcpy(&lm_path[length + 1], buffer);
+
+ search_local_machine(lm_path, dd_path);
+
+ lm_path[length] = '\0';
+ }
+ }
+ while (result == ERROR_SUCCESS);
+
+ RegCloseKey(key);
+ }
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+*
+* GET_LPT_ADDRESSES_FROM_REGISTRY
+*
+* Searches Win95/98 registry recursively to get I/O port addresses for
+* parallel ports.
+*/
+void get_lpt_addresses_from_registry()
+{
+ char lm_path[1024];
+ char dd_path[1024];
+
+ strcpy(lm_path, "Enum");
+ strcpy(dd_path, "Config Manager");
+ search_local_machine(lm_path, dd_path);
+}
+#endif
+#endif
+
+void initialize_jtag_hardware()
+{
+ if (specified_com_port)
+ {
+ com_port = open(serial_port_name, O_RDWR);
+ if (com_port == -1)
+ {
+ fprintf(stderr, "Error: can't open serial port \"%s\"\n",
+ serial_port_name);
+ }
+ else
+ {
+ int i = 0, result = 0;
+ char data = 0;
+
+ data = 0x7e;
+ write(com_port, &data, 1);
+
+ for (i = 0; (i < 100) && (result != 1); ++i)
+ {
+ result = read(com_port, &data, 1);
+ }
+
+ if (result == 1)
+ {
+ data = 0x70; write(com_port, &data, 1); /* TDO echo off */
+ data = 0x72; write(com_port, &data, 1); /* auto LEDs off */
+ data = 0x74; write(com_port, &data, 1); /* ERROR LED off */
+ data = 0x76; write(com_port, &data, 1); /* DONE LED off */
+ data = 0x60; write(com_port, &data, 1); /* signals low */
+ }
+ else
+ {
+ fprintf(stderr, "Error: BitBlaster is not responding on %s\n",
+ serial_port_name);
+ close(com_port);
+ com_port = -1;
+ }
+ }
+ }
+ else
+ {
+#if PORT == WINDOWS || PORT == DOS
+
+#if PORT == WINDOWS
+ if (windows_nt)
+ {
+ initialize_nt_driver();
+ }
+ else
+ {
+#ifdef __BORLANDC__
+ fprintf(stderr, "Error: parallel port access is not available\n");
+#else
+ if (!specified_lpt_addr)
+ {
+ get_lpt_addresses_from_registry();
+
+ lpt_addr = 0;
+
+ if (specified_lpt_port)
+ {
+ lpt_addr = lpt_addresses_from_registry[lpt_port - 1];
+ }
+
+ if (lpt_addr == 0)
+ {
+ if (lpt_addresses_from_registry[3] != 0)
+ lpt_addr = lpt_addresses_from_registry[3];
+ if (lpt_addresses_from_registry[2] != 0)
+ lpt_addr = lpt_addresses_from_registry[2];
+ if (lpt_addresses_from_registry[1] != 0)
+ lpt_addr = lpt_addresses_from_registry[1];
+ if (lpt_addresses_from_registry[0] != 0)
+ lpt_addr = lpt_addresses_from_registry[0];
+ }
+
+ if (lpt_addr == 0)
+ {
+ if (specified_lpt_port)
+ {
+ lpt_addr = lpt_addr_table[lpt_port - 1];
+ }
+ else
+ {
+ lpt_addr = lpt_addr_table[0];
+ }
+ }
+ }
+ initial_lpt_ctrl = windows_nt ? 0x0c : read_byteblaster(2);
+#endif
+ }
+#endif
+
+#if PORT == DOS
+ /*
+ * Read word at specific memory address to get the LPT port address
+ */
+ WORD *bios_address = (WORD *) 0x00400008;
+
+ if (!specified_lpt_addr)
+ {
+ lpt_addr = bios_address[lpt_port - 1];
+
+ if ((lpt_addr != 0x278) &&
+ (lpt_addr != 0x27c) &&
+ (lpt_addr != 0x378) &&
+ (lpt_addr != 0x37c) &&
+ (lpt_addr != 0x3b8) &&
+ (lpt_addr != 0x3bc))
+ {
+ lpt_addr = lpt_addr_table[lpt_port - 1];
+ }
+ }
+ initial_lpt_ctrl = read_byteblaster(2);
+#endif
+
+ /* set AUTO-FEED low to enable ByteBlaster (value to port inverted) */
+ /* set DIRECTION low for data output from parallel port */
+ write_byteblaster(2, (initial_lpt_ctrl | 0x02) & 0xDF);
+#endif
+ }
+}
+
+void close_jtag_hardware()
+{
+ if (specified_com_port)
+ {
+ if (com_port != -1) close(com_port);
+ }
+ else
+ {
+#if PORT == WINDOWS || PORT == DOS
+ /* set AUTO-FEED high to disable ByteBlaster */
+ write_byteblaster(2, initial_lpt_ctrl & 0xfd);
+
+#if PORT == WINDOWS
+ if (windows_nt && (nt_device_handle != INVALID_HANDLE_VALUE))
+ {
+ if (port_io_count > 0) flush_ports();
+
+ CloseHandle(nt_device_handle);
+ }
+#endif
+#endif
+ }
+}
+
+#if PORT == WINDOWS
+/**************************************************************************/
+/* */
+
+BOOL initialize_nt_driver()
+
+/* */
+/* Uses CreateFile() to open a connection to the Windows NT device */
+/* driver. */
+/* */
+/**************************************************************************/
+{
+ BOOL status = FALSE;
+
+ ULONG buffer[1];
+ ULONG returned_length = 0;
+ char nt_lpt_str[] = { '\\', '\\', '.', '\\',
+ 'A', 'L', 'T', 'L', 'P', 'T', '1', '\0' };
+
+
+ nt_lpt_str[10] = (char) ('1' + (lpt_port - 1));
+
+ nt_device_handle = CreateFile(
+ nt_lpt_str,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (nt_device_handle == INVALID_HANDLE_VALUE)
+ {
+ fprintf(stderr,
+ "I/O error: cannot open device %s\nCheck port number and device driver installation",
+ nt_lpt_str);
+ }
+ else
+ {
+ if (DeviceIoControl(
+ nt_device_handle, /* Handle to device */
+ PGDC_IOCTL_GET_DEVICE_INFO_PP, /* IO Control code */
+ (ULONG *)NULL, /* Buffer to driver. */
+ 0, /* Length of buffer in bytes. */
+ &buffer, /* Buffer from driver. */
+ sizeof(ULONG), /* Length of buffer in bytes. */
+ &returned_length, /* Bytes placed in data_buffer. */
+ NULL)) /* Wait for operation to complete */
+ {
+ if (returned_length == sizeof(ULONG))
+ {
+ if (buffer[0] == PGDC_HDLC_NTDRIVER_VERSION)
+ {
+ status = TRUE;
+ }
+ else
+ {
+ fprintf(stderr,
+ "I/O error: device driver %s is not compatible\n(Driver version is %lu, expected version %lu.\n",
+ nt_lpt_str,
+ (unsigned long) buffer[0],
+ (unsigned long) PGDC_HDLC_NTDRIVER_VERSION);
+ }
+ }
+ else
+ {
+ fprintf(stderr, "I/O error: device driver %s is not compatible.\n",
+ nt_lpt_str);
+ }
+ }
+
+ if (!status)
+ {
+ CloseHandle(nt_device_handle);
+ nt_device_handle = INVALID_HANDLE_VALUE;
+ }
+ }
+
+ if (!status)
+ {
+ /* error message already given */
+ exit(1);
+ }
+
+ return (status);
+}
+#endif
+
+#if PORT == WINDOWS || PORT == DOS
+/**************************************************************************/
+/* */
+
+void write_byteblaster
+(
+ int port,
+ int data
+)
+
+/* */
+/**************************************************************************/
+{
+#if PORT == WINDOWS
+ BOOL status = FALSE;
+
+ int returned_length = 0;
+ int buffer[2];
+
+
+ if (windows_nt)
+ {
+ /*
+ * On Windows NT, access hardware through device driver
+ */
+ if (port == 0)
+ {
+ port_io_buffer[port_io_count].data = (USHORT) data;
+ port_io_buffer[port_io_count].command = PGDC_WRITE_PORT;
+ ++port_io_count;
+
+ if (port_io_count >= PORT_IO_BUFFER_SIZE) flush_ports();
+ }
+ else
+ {
+ if (port_io_count > 0) flush_ports();
+
+ buffer[0] = port;
+ buffer[1] = data;
+
+ status = DeviceIoControl(
+ nt_device_handle, /* Handle to device */
+ PGDC_IOCTL_WRITE_PORT_PP, /* IO Control code for write */
+ (ULONG *)&buffer, /* Buffer to driver. */
+ 2 * sizeof(int), /* Length of buffer in bytes. */
+ (ULONG *)NULL, /* Buffer from driver. Not used. */
+ 0, /* Length of buffer in bytes. */
+ (ULONG *)&returned_length, /* Bytes returned. Should be zero. */
+ NULL); /* Wait for operation to complete */
+
+ if ((!status) || (returned_length != 0))
+ {
+ fprintf(stderr, "I/O error: Cannot access ByteBlaster hardware\n");
+ CloseHandle(nt_device_handle);
+ exit(1);
+ }
+ }
+ }
+ else
+#endif
+ {
+ /*
+ * On Windows 95, access hardware directly
+ */
+ outp((WORD)(port + lpt_addr), (WORD)data);
+ }
+}
+
+/**************************************************************************/
+/* */
+
+int read_byteblaster
+(
+ int port
+)
+
+/* */
+/**************************************************************************/
+{
+ int data = 0;
+
+#if PORT == WINDOWS
+
+ BOOL status = FALSE;
+
+ int returned_length = 0;
+
+
+ if (windows_nt)
+ {
+ /* flush output cache buffer before reading from device */
+ if (port_io_count > 0) flush_ports();
+
+ /*
+ * On Windows NT, access hardware through device driver
+ */
+ status = DeviceIoControl(
+ nt_device_handle, /* Handle to device */
+ PGDC_IOCTL_READ_PORT_PP, /* IO Control code for Read */
+ (ULONG *)&port, /* Buffer to driver. */
+ sizeof(int), /* Length of buffer in bytes. */
+ (ULONG *)&data, /* Buffer from driver. */
+ sizeof(int), /* Length of buffer in bytes. */
+ (ULONG *)&returned_length, /* Bytes placed in data_buffer. */
+ NULL); /* Wait for operation to complete */
+
+ if ((!status) || (returned_length != sizeof(int)))
+ {
+ fprintf(stderr, "I/O error: Cannot access ByteBlaster hardware\n");
+ CloseHandle(nt_device_handle);
+ exit(1);
+ }
+ }
+ else
+#endif
+ {
+ /*
+ * On Windows 95, access hardware directly
+ */
+ data = inp((WORD)(port + lpt_addr));
+ }
+
+ return (data & 0xff);
+}
+
+#if PORT == WINDOWS
+void flush_ports(void)
+{
+ ULONG n_writes = 0L;
+ BOOL status;
+
+ status = DeviceIoControl(
+ nt_device_handle, /* handle to device */
+ PGDC_IOCTL_PROCESS_LIST_PP, /* IO control code */
+ (LPVOID)port_io_buffer, /* IN buffer (list buffer) */
+ port_io_count * sizeof(struct PORT_IO_LIST_STRUCT),/* length of IN buffer in bytes */
+ (LPVOID)port_io_buffer, /* OUT buffer (list buffer) */
+ port_io_count * sizeof(struct PORT_IO_LIST_STRUCT),/* length of OUT buffer in bytes */
+ &n_writes, /* number of writes performed */
+ 0); /* wait for operation to complete */
+
+ if ((!status) || ((port_io_count * sizeof(struct PORT_IO_LIST_STRUCT)) != n_writes))
+ {
+ fprintf(stderr, "I/O error: Cannot access ByteBlaster hardware\n");
+ CloseHandle(nt_device_handle);
+ exit(1);
+ }
+
+ port_io_count = 0;
+}
+#endif /* PORT == WINDOWS */
+#endif /* PORT == WINDOWS || PORT == DOS */
+
+#if !defined (DEBUG)
+#pragma optimize ("ceglt", off)
+#endif
+
+void delay_loop(long count)
+{
+ while (count != 0L) count--;
+}
diff --git a/common/recipes-utils/jbi/files/make/Microsoft/nmake.mak b/common/recipes-utils/jbi/files/make/Microsoft/nmake.mak
new file mode 100644
index 0000000..352a9c5
--- /dev/null
+++ b/common/recipes-utils/jbi/files/make/Microsoft/nmake.mak
@@ -0,0 +1,65 @@
+#
+# Module: makefile
+#
+# Copyright (C) Altera Corporation 1998-2001
+#
+# Description: Makefile for JAM Bytecode Player
+#
+
+OBJS = \
+ jbistub.obj \
+ jbimain.obj \
+ jbicomp.obj \
+ jbijtag.obj
+
+
+!IF "$(MEM_TRACKER)" != ""
+!IF "$(STATIC_MEMORY_SIZE)" != ""
+# MEMORY TRACKER ON, USE 'STATIC_MEMORY_SIZE' KB OF STATIC MEMORY
+.c.obj::
+ cl /W4 /c /O2 /ML /DWINNT /DMEM_TRACKER /DUSE_STATIC_MEMORY=$(STATIC_MEMORY_SIZE) $<
+!ELSE
+# MEMORY TRACKER ON, USE DYNAMIC MEMORY
+.c.obj::
+ cl /W4 /c /O2 /ML /DWINNT /DMEM_TRACKER $<
+!ENDIF
+!ELSE
+!IF "$(STATIC_MEMORY_SIZE)" != ""
+# MEMORY TRACKER OFF, USE 'STATIC_MEMORY_SIZE' KB OF STATIC MEMORY
+.c.obj::
+ cl /W4 /c /O2 /ML /DWINNT /DUSE_STATIC_MEMORY=$(STATIC_MEMORY_SIZE) $<
+!ELSE
+# MEMORY TRACKER OFF, USE DYNAMIC MEMORY
+.c.obj::
+ cl /W4 /c /O2 /ML /DWINNT $<
+!ENDIF
+!ENDIF
+
+jbi.exe : $(OBJS)
+ link $(OBJS) advapi32.lib /out:jbi.exe
+
+# Dependencies:
+
+jbistub.obj : \
+ jbistub.c \
+ jbiport.h \
+ jbiexprt.h
+
+jbimain.obj : \
+ jbimain.c \
+ jbiport.h \
+ jbiexprt.h \
+ jbijtag.h \
+ jbicomp.h
+
+jamcomp.obj : \
+ jamcomp.c \
+ jbiport.h \
+ jbiexprt.h \
+ jbicomp.h
+
+jbijtag.obj : \
+ jbijtag.c \
+ jbiport.h \
+ jbiexprt.h \
+ jbijtag.h
diff --git a/common/recipes-utils/jbi/files/make/PCVS/PVCS16.MAK b/common/recipes-utils/jbi/files/make/PCVS/PVCS16.MAK
new file mode 100644
index 0000000..e943aa4
--- /dev/null
+++ b/common/recipes-utils/jbi/files/make/PCVS/PVCS16.MAK
@@ -0,0 +1,61 @@
+#
+# Module: makefile
+#
+# Copyright (C) Altera Corporation 1998-2001
+#
+# Description: Makefile for JAM Bytecode Player
+#
+
+OBJS = \
+ jbistub.obj \
+ jbimain.obj \
+ jbicomp.obj \
+ jbijtag.obj
+
+
+%if "$(MEM_TRACKER)" && "$(STATIC_MEMORY_SIZE)"
+# MEMORY TRACKER ON, USE 'STATIC_MEMORY_SIZE' KB OF STATIC MEMORY
+.c.obj :
+ cl /W4 /AL /c /O2 /Zp1 /DPORT=DOS /DMEM_TRACKER /DUSE_STATIC_MEMORY=$(STATIC_MEMORY_SIZE) $<
+%elseif "$(MEM_TRACKER)" && !"$(STATIC_MEMORY_SIZE)"
+# MEMORY TRACKER ON, USE DYNAMIC MEMORY
+.c.obj :
+ cl /W4 /AL /c /O2 /Zp1 /DPORT=DOS /DMEM_TRACKER $<
+%elseif !"$(MEM_TRACKER)" && "$(STATIC_MEMORY_SIZE)"
+# MEMORY TRACKER OFF, USE 'STATIC_MEMORY_SIZE' KB OF STATIC MEMORY
+.c.obj :
+ cl /W4 /AL /c /O2 /Zp1 /DPORT=DOS /DUSE_STATIC_MEMORY=$(STATIC_MEMORY_SIZE) $<
+%else !"$(MEM_TRACKER)" && !"$(STATIC_MEMORY_SIZE)"
+# MEMORY TRACKER OFF, USE DYNAMIC MEMORY
+.c.obj :
+ cl /W4 /AL /c /O2 /Zp1 /DPORT=DOS $<
+%endif
+
+jbi.exe : $(OBJS)
+ link /STACK:0x8000 $(OBJS), jbi.exe,,,,
+
+# Dependencies:
+
+jbistub.obj : \
+ jbistub.c \
+ jbiport.h \
+ jbiexprt.h
+
+jbimain.obj : \
+ jbimain.c \
+ jbiport.h \
+ jbiexprt.h \
+ jbijtag.h \
+ jbicomp.h
+
+jamcomp.obj : \
+ jamcomp.c \
+ jbiport.h \
+ jbiexprt.h \
+ jbicomp.h
+
+jbijtag.obj : \
+ jbijtag.c \
+ jbiport.h \
+ jbiexprt.h \
+ jbijtag.h
diff --git a/common/recipes-utils/jbi/files/make/PCVS/pvcs32.mak b/common/recipes-utils/jbi/files/make/PCVS/pvcs32.mak
new file mode 100644
index 0000000..409ef47
--- /dev/null
+++ b/common/recipes-utils/jbi/files/make/PCVS/pvcs32.mak
@@ -0,0 +1,61 @@
+#
+# Module: makefile
+#
+# Copyright (C) Altera Corporation 1998-2001
+#
+# Description: Makefile for JAM Bytecode Player
+#
+
+OBJS = \
+ jbistub.obj \
+ jbimain.obj \
+ jbicomp.obj \
+ jbijtag.obj
+
+
+%if "$(MEM_TRACKER)" && "$(STATIC_MEMORY_SIZE)"
+# MEMORY TRACKER ON, USE 'STATIC_MEMORY_SIZE' KB OF STATIC MEMORY
+.c.obj :
+ cl /W4 /c /O2 /ML /DWINNT /DMEM_TRACKER /DUSE_STATIC_MEMORY=$(STATIC_MEMORY_SIZE) $<
+%elseif "$(MEM_TRACKER)" && !"$(STATIC_MEMORY_SIZE)"
+# MEMORY TRACKER ON, USE DYNAMIC MEMORY
+.c.obj :
+ cl /W4 /c /O2 /ML /DWINNT /DMEM_TRACKER $<
+%elseif !"$(MEM_TRACKER)" && "$(STATIC_MEMORY_SIZE)"
+# MEMORY TRACKER OFF, USE 'STATIC_MEMORY_SIZE' KB OF STATIC MEMORY
+.c.obj :
+ cl /W4 /c /O2 /ML /DWINNT /DUSE_STATIC_MEMORY=$(STATIC_MEMORY_SIZE) $<
+%else !"$(MEM_TRACKER)" && !"$(STATIC_MEMORY_SIZE)"
+# MEMORY TRACKER OFF, USE DYNAMIC MEMORY
+.c.obj :
+ cl /W4 /c /O2 /ML /DWINNT $<
+%endif
+
+jbi.exe : $(OBJS)
+ link $(OBJS) advapi32.lib /out:jbi.exe
+
+# Dependencies:
+
+jbistub.obj : \
+ jbistub.c \
+ jbiport.h \
+ jbiexprt.h
+
+jbimain.obj : \
+ jbimain.c \
+ jbiport.h \
+ jbiexprt.h \
+ jbijtag.h \
+ jbicomp.h
+
+jamcomp.obj : \
+ jamcomp.c \
+ jbiport.h \
+ jbiexprt.h \
+ jbicomp.h
+
+jbijtag.obj : \
+ jbijtag.c \
+ jbiport.h \
+ jbiexprt.h \
+ jbijtag.h
diff --git a/common/recipes-utils/jbi/files/readme.openbmc b/common/recipes-utils/jbi/files/readme.openbmc
new file mode 100644
index 0000000..f8620f7
--- /dev/null
+++ b/common/recipes-utils/jbi/files/readme.openbmc
@@ -0,0 +1,5 @@
+Changeset from the original jdi_22.exe
+
+1. removed all files in 'exe/'
+2. renamed all files in 'code' to lower case
+3. converted all files in 'code' from DOS style to UNIX style \ No newline at end of file
diff --git a/common/recipes-utils/jbi/files/readme.txt b/common/recipes-utils/jbi/files/readme.txt
new file mode 100644
index 0000000..813d88d
--- /dev/null
+++ b/common/recipes-utils/jbi/files/readme.txt
@@ -0,0 +1,464 @@
+********************************************************************************************
+ Jam STAPL Byte-Code Player Version 2.2 README 7/15/2002
+********************************************************************************************
+
+CONTENTS
+
+A. DESCRIPTION
+B. INCLUDED IN THIS RELEASE
+C. NEW IN VERSION 2.2
+D. RUNNING THE PLAYER IN COMMAND-LINE MODE
+E. PORTING THE JAM STAPL BYTE-CODE PLAYER
+F. JAM STAPL BYTE-CODE PLAYER API
+G. MEMORY USAGE
+H. SUPPORT
+
+A. DESCRIPTION
+--------------
+The Jam STAPL Byte-Code Player is a software driver that allows test and programming algorithms
+for IEEE 1149.1 Joint Test Action Group (JTAG)-compliant devices to be asserted via the
+JTAG port. The Jam STAPL Byte-Code Player reads and decodes information in Jam STAPL
+Byte-Code Files (.jbc) to program and test programmable logic devices (PLDs), memories,
+and other devices in a JTAG chain. The Jam STAPL Byte-Code Player complies with STAPL
+(Standard Test and Programming Language) Specification JESD-71. The construction of the
+Player permits fast programming times, small programming files, and easy in-field upgrades.
+Upgrades are simplified, because all programming/test algorithms and data are confined to the
+Jam STAPL Byte-Code File. Version 2.2 supports Jam STAPL Byte-Code Files (.jbc) that have been
+compiled using the Jam STAPL Byte-Code Compiler. The Player is also able to read and "play"
+older Jam Byte-Code files based on Jam v1.1 syntax.
+ The .jbc File is a binary version of the ASCII Jam File (.jam). The Jam STAPL Byte-Code
+format consists, among other things, of a "byte code" representation of Jam commands, as
+they are defined in STAPL Specification JESD-71. This means that the .jbc File is simply a
+different implementation of the .jam file. This binary implementation results in smaller
+file sizes and shorter programming times.
+ This document should be used together with AN 122 (Using STAPL for ISP & ICR via
+an Embedded Processor).
+
+B. INCLUDED IN THIS RELEASE
+---------------------------
+The following tables provide the directory structure of the files on this CD-ROM:
+
+Directory Filename Description
+--------- -------- -----------------------
+\exe \16-bit-DOS\jbi16.exe Supports the BitBlaster serial,
+ ByteBlaster parallel, Xilinx
+ Parallel Download Cable III, and
+ Lattice ispDOWNLOAD cables for
+ PCs running 16-bit DOS platforms.
+
+ \Win9598-WinNT\jbi32.exe Supports the BitBlaster serial
+ ByteBlaster parallel, Xilinx
+ Parallel Download Cable III, and
+ Lattice ispDOWNLOAD cables for
+ PCs running 32-bit Windows
+ (Windows 95, Windows 98 and Windows NT)
+
+
+Directory Filename Description
+--------- -------- ------------------------------------------
+\code jbicomp.h Source code for the Jam STAPL Byte-Code Player
+ jbiexprt.h
+ jbijtag.h
+ jbiport.h
+ jbicomp.c
+ jbijtag.c
+ jbimain.c
+ jbistub.c
+
+Directory Filename Description
+--------- -------- ------------------------------------------
+\make \microsoft\makefile.mak Make file compatible with Microsoft Visual
+ C++ compiler v5.0. Builds a 32-bit windows
+ console executable.
+
+\make \pvcs\pvcs32.mak Builds a 32-bit executable.
+
+\make \pvcs\pvcs16.mak Builds a 16-bit executable.
+
+
+C. NEW IN VERSION 2.2
+---------------------
+Updates in the Jam STAPL Byte-Code Player version 2.2 include:
+
+* fixed /W4 warnings
+* updated JTAG state transition paths
+
+
+D. RUNNING THE JAM STAPL BYTE-CODE PLAYER IN COMMAND-LINE MODE
+--------------------------------------------------------------
+If the Player is going to be run on a PC or a workstation, the following commands can be
+used to execute programming or other tasks:
+
+Jam STAPL Byte-Code Player Version 2.2
+Copyright (C) 1998-2000 Altera Corporation
+
+Usage: jbi [options] <filename>
+
+Available options:
+ -h : show help message
+ -v : show verbose messages
+ -i : show file info only - do not execute
+ -a<action> : specify action name (Jam STAPL)
+ -d<var=val> : initialize variable to specified value (Jam 1.1)
+ -d<proc=1> : enable optional procedure (Jam STAPL)
+ -d<proc=0> : disable recommended procedure (Jam STAPL)
+ -p<port> : parallel port number or address (for ByteBlaster)
+ -c<cable> : alternative download cable compatibility: -cl or -cx
+ -s<port> : serial port name (for BitBlaster)
+ -r : don't reset JTAG TAP after use
+
+Command line text is not case-sensitive.
+
+Use the -a flag when applying Jam STAPL Byte-Code files. Use the -d flag when applying Jam v1.1
+Byte-Code files.
+
+Valid action names, as specified by JEDEC Standard JESD-71 are:
+
+ Action Name Description
+ ----------- -----------
+ CHECKCHAIN Verify the continuity of the IEEE 1149.1 JTAG scan chain
+ READ_IDCODE Read the IEEE 1149.1 IDCODE and EXPORT it (print it)
+ READ_USERCODE Read the IEEE 1149.1 USERCODE and EXPORT it (print it)
+ READ_UES Read the IEEE 1149.1 UESCODE and EXPORT it (print it)
+ ERASE Perform a bulk erase of the device(s)
+ BLANKCHECK Check the erased state of the device(s)
+ PROGRAM Program the device
+ VERIFY Verify the programming data of the device(s)
+ READ Read the programming data of the device(s)
+ CHECKSUM Calculate one fuse checksum of the programming data of the device(s)
+ SECURE Set the security bit of the device(s)
+ QUERY_SECURITY Check whether the security bit is set
+ TEST Perform a test. This test can include tests such as boundary-scan,
+ internal, vector, and built-in self tests
+
+Valid initialization variables and values for the -d flag are:
+
+ Initialization String Value Action
+ --------------------- ----- ------
+ DO_PROGRAM 0 Do not program the device
+ DO_PROGRAM 1 Program the device
+ DO_VERIFY 0 Do not verify the device
+ DO_VERIFY 1 Verify the device
+ DO_BLANKCHECK 0 Do not check the erased state of the device
+ DO_BLANKCHECK 1 Check the erased state of the device
+ READ_UESCODE 0 Do not read the JTAG UESCODE
+ READ_UESCODE 1 Read UESCODE and export it
+ DO_SECURE 0 Do not set the security bit
+ DO_SECURE 1 Set the security bit
+
+
+E. PORTING THE JAM STAPL BYTE-CODE PLAYER
+-----------------------------------------
+The Jam STAPL Byte-Code Player is designed to be easily ported to any processor-based hardware
+system. All platform-specific code is placed in the jbistub.c and jbimain.c files. Routines
+that perform any interaction with the outside world are confined to the jbistub.c source
+file. Preprocessor statements encase operating system-specific code and code pertaining to
+specific hardware. All changes to the source code for porting are mostly confined to the
+jbistub.c file and in some cases porting the Jam Player is as simple as changing a
+single #define statement. This process also makes debugging simple. For example, if
+the jbistub.c file has been customized for a particular embedded application, but is
+not working, the equivalent DOS Jam STAPL Byte-Code Player and a download cable can be used to
+check the hardware continuity and provide a "known good" starting point from which to attack
+the problem.
+
+The jbistub.c and jbimain.c files in this release target the DOS operating system, by default.
+To change the targeted platform, edit the following line in the jbistub.c and jbimain.c files:
+
+ #define PORT DOS
+
+The preprocessor statement takes the form:
+
+ #define PORT [PLATFORM]
+
+Change the [PLATFORM] field to one of the supported platforms: EMBEDDED, DOS, WINDOWS,
+or UNIX. The following table explains how to port the Jam STAPL Byte-Code Player for each of the
+supported platforms:
+
+PLATFORM COMPILER ACTIONS
+-------- -------- ---------------------------------------------
+EMBEDDED 16 or 32-bit Change #define and see EMBEDDED PLATFORM below
+DOS 16-bit Change #define and compile
+WINDOWS 32-bit Change #define and compile
+UNIX 32-bit Change #define and compile
+
+The source code supplied in this release is ANSI C source. In cases where a different
+download cable or other hardware is used, the DOS, WINDOWS, and UNIX platforms will require
+additional code customization, which is described below.
+
+EMBEDDED PLATFORM
+Because there are many different kinds of embedded systems, each with different hardware and
+software requirements, some additional customization must be done to port the Jam STAPL
+Byte-Code Player for embedded systems. To port the Player, the following functions may
+need to be customized:
+
+FUNCTION DESCRIPTION
+--------- ------------------------------------------------------------------
+jbi_jtag_io() Interface to the IEEE 1149.1 JTAG signals, TDI, TMS, TCK, and TDO.
+jbi_message() Prints information and error text to standard output, when available.
+jbi_export() Passes information such as the User Electronic Signature (UES) back to the
+ calling program.
+jbi_delay() Implements the programming pulses or delays needed during execution.
+
+Miscellaneous
+jbi_vector_map() Processes signal-to-pin map for non-IEEE 1149.1 JTAG signals.
+jbi_vector_io() Asserts non-IEEE 1149.1 JTAG signals as defined in the VECTOR MAP.
+
+jbi_jtag_io()
+-------------
+int jbi_jtag_io(int tms, int tdi, int read_tdo)
+
+This function provides exclusive access to the IEEE 1149.1 JTAG signals. You must always
+customize this function to write to the proper hardware port.
+
+The code in this release supports a serial mode specific to the Altera BitBlaster download
+cable. If a serial interface is required, this code can be customized for that purpose.
+However, this customization would require some additional processing external to the
+embedded processor to turn the serial data stream into valid JTAG vectors. This readme file
+does not discuss customization of serial mode. Contact Altera Applications at (800) 800-EPLD
+for more information.
+
+In most cases a parallel byte mode is used. When in byte mode, jbi_jtag_io() is passed
+the values of TMS and TDI. Likewise, the variable read_tdo tells the function whether
+reading TDO is required. (Because TCK is a clock and is always written, it is written
+implicitly within the function.) If requested, jbi_jtag_io() returns the value of TDO read.
+Sample code is shown below:
+
+int jbi_jtag_io(int tms, int tdi, int read_tdo)
+{
+ int data = 0;
+ int tdo = 0;
+
+ if (!jtag_hardware_initialized)
+ {
+ initialize_jtag_hardware();
+ jtag_hardware_initialized = TRUE;
+ }
+
+ data = ((tdi ? 0x40 : 0) | (tms ? 0x02 : 0));
+
+ write_byteblaster(0, data);
+
+ if (read_tdo)
+ {
+ tdo = (read_byteblaster(1) & 0x80) ? 0 : 1;
+ }
+
+ write_byteblaster(0, data | 0x01);
+
+ write_byteblaster(0, data);
+
+ return (tdo);
+}
+
+The code, as shown above, is configured to read/write to a PC parallel port.
+initialize_jtag_hardware() sets the control register of the port for byte mode. As shown
+above, jbi_jtag_io() reads and writes to the port as follows:
+
+|---------------------------------------------------------------|
+| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | I/O Port
+|---------------------------------------------------------------|
+| 0 | TDI | 0 | 0 | 0 | 0 | TMS | TCK | OUTPUT DATA - Base Address
+|---------------------------------------------------------------|
+| !TDO | X | X | X | X | --- | --- | --- | INPUT DATA - Base Address + 1
+|---------------------------------------------------------------|
+
+The PC parallel port inverts the actual value of TDO. Thus, jbi_jtag_io() inverts
+it again to retrieve the original data. Inverted:
+
+ tdo = (read_byteblaster(1) & 0x80) ? 0 : 1;
+
+If the target processor does not invert TDO, the code should look like:
+
+ tdo = (read_byteblaster(1) & 0x80) ? 1 : 0;
+
+To map the signals to the correct addresses simply use the left shift (<<) or right shift
+(>>) operators. For example, if TMS and TDI are at ports 2 and 3, respectively, then the
+code would be as shown below:
+
+ data = (((tdi ? 0x40 : 0)>>3) | ((tms ? 0x02 : 0)<<1));
+
+The same process applies to TCK and TDO.
+
+read_byteblaster() and write_byteblaster() use the inp() and outp() <conio.h> functions,
+respectively, to read and write to the port. If these functions are not available,
+equivalent functions should be substituted.
+
+jbi_message()
+--------------
+void jam_message(char *message_text)
+
+When the Jam STAPL Byte-Code Player encounters a PRINT command within the .jbc File, it processes
+the message text and passes it to jbi_message(). The text is sent to stdio. If a standard
+output device is not available, jbi_message() does nothing and returns. The Jam STAPL
+Byte-Code Player does not append a newline character to the end of the text message.
+This function should append a newline character for those systems that require one.
+
+jbi_export()
+------------
+void jbi_export(char *key, long value)
+
+The jbi_export() function sends information to the calling program in the form of a text
+string and associated integer value. The text string is called the key string and it
+determines the significance and interpretation of the integer value. An example use of this
+function would be to report the device USERCODE back to the calling program.
+
+jbi_delay()
+-----------
+void jbi_delay(long microseconds)
+
+jbi_delay() is used to implement programming pulse widths necessary for programming PLDs,
+memories, and configuring SRAM-based devices. These delays are implemented using software
+loops calibrated to the speed of the targeted embedded processor. The Jam STAPL Byte-Code
+Player is told how long to delay with the .jbc File WAIT command. This function can be
+customized easily to measure the passage of time via a hardware-based timer. jbi_delay()
+must perform accurately over the range of one millisecond to one second. The function can
+take as much as 10% more time than is specified, but cannot return in less time. To minimize
+the time to execute the Jam statements, it is generally recommended to calibrate the delay as
+accurately as possible.
+
+Miscellaneous Functions
+------------------------
+jbi_vector_map() and jbi_vector_io()
+
+The VMAP and VECTOR Jam commands are translated by these functions to assert signals to
+non-JTAG ports. Altera .jbc Files do not use these commands. If the Jam STAPL Byte-Code Player
+will be used only to program Altera devices, these routines can be removed. In the event
+that the Jam Player does encounter the VMAP and VECTOR commands, it will process the
+information so that non-JTAG signals can be written and read as defined by JEDEC Specification
+JESD-71.
+
+jbi_malloc()
+
+void *jam_malloc(unsigned int size)
+
+During execution, the Jam STAPL Byte-Code Player will allocate memory to perform its tasks. When
+it allocates memory, it calls the jbi_malloc() function. If malloc() is not available to the
+embedded system it must be replaced with an equivalent function.
+
+jbi_free()
+
+void jbi_free(void *ptr)
+
+This function is called when the Jam STAPL Byte-Code Player frees memory. If free() is not
+available to the embedded system, it must be replaced with an equivalent function.
+
+F. JAM STAPL Byte-Code Player API
+---------------------------------
+The main entry point for the Jam Player is the jbi_execute function:
+
+JAM_RETURN_TYPE jbi_execute
+(
+ PROGRAM_PTR program,
+ long program_size,
+ char *workspace,
+ long workspace_size,
+ char *action,
+ char **init_list,
+ long *error_line,
+ int *exit_code,
+ int *format_version
+)
+
+This routine recieves 6 parameters, passes back 2 parameters, and returns a status
+code (of JAM_RETURN_TYPE). This function is called once in main(), which is coded in the
+jbistub.c file (jbi_execute() is defined in the jbimain.c file). Some processing is done in
+main() to check for valid data being passed to jbi_execute(), and to set up some of the
+buffering required to store the .jbc File.
+
+The program parameter is a pointer to the memory location where the .jbc File is stored
+(memory space previously malloc'd and assigned in main()). jbi_execute() assigns this
+pointer to the global variable jbi_program, which provides the rest of the Jam STAPL
+Byte-Code Player with access to the .jbc File via the GET_BYTE, GET_WORD, and
+GET_DWORD macros.
+
+program_size provides the number of bytes stored in the memory buffer occupied
+by the .jbc File.
+
+workspace points to memory previously allocated in main(). This space is the sum of all
+memory reserved for all of the processing that the Jam STAPL Byte-Code Player must do, including
+the space taken by the .jbc File. Memory is only used in this way when the Jam STAPL Byte-Code
+Player is executed using the -m console option. If the -m option is not used, the Jam Byte
+Code Player is free to allocate memory dynamically as it is needed. In this case, workspace
+points to NULL. jbi_execute() assigns the workspace pointer to the global variable,
+jbi_workspace, giving the rest of the Jam STAPL Byte-Code Player access to this block of memory.
+
+workspace_size provides the size of the workspace in bytes. If the workspace pointer points
+to NULL this parameter is ignored. jbi_execute() assigns workspace_size to the global
+variable, jbi_workspace_size.
+
+action is the way the Player is told what function should be performed, as defined
+by STAPL. (i.e. PROGRAM, READ_USERCODE, etc) The action pointer points to the string
+that tells the Player what functions to execute within the .jbc file. Each action can
+contain "recommended" and "optional" sub-actions. "Recommended" sub-actions are those
+that will be executed by default, while "optional" sub-actions will be skipped.
+For example, passing "PROGRAM\0" will result in the following steps for an Altera .jbc
+file:
+ - ERASE (recommended)
+ - BLANKCHECK (optional)
+ - PROGRAM (recommended)
+ - VERIFY (recommended)
+
+So, by simply passing "PROGRAM\0" the device will be programmed and verified. This is the
+action Altera recommends using with it's .jbc files. If you want to add the BLANKCHECK step
+you must pass "DO_BLANKCHECK=1\0" via the init_list pointer. See Section D for other valid
+action strings. Note that the action string must be NULL terminated.
+
+init_list is a parameter that is used when applying pre-JEDEC, Jam v1.1 .jbc files, or when
+overriding optional sub-actions, as in the example above. While older pre-JEDEC .jbc files
+can be played, it is strongly recommended that STAPL-based .jbc files be used. When using
+STAPL-based .jbc files, init_list should point to NULL. If an older .jbc file must be used,
+see AN 88 for more details on the parameters that init_list can point to.
+
+If an error occurs during execution of the .jbc File, error_line provides the
+line number of the .jbc File where the error occured. This error is associated
+with the function of the device, as opposed to a syntax or software error in the .jbc File.
+
+exit_code provides general information about the nature of an error associated with a
+malfunction of the device or a functional error:
+
+ exit_code Description
+ --------- -----------
+ 0 Success
+ 1 Checking chain failure
+ 2 Reading IDCODE failure
+ 3 Reading USERCODE failure
+ 4 Reading UESCODE failure
+ 5 Entering ISP failure
+ 6 Unrecognized device
+ 7 Device version is not supported
+ 8 Erase failure
+ 9 Device is not blank
+ 10 Device programming failure
+ 11 Device verify failure
+ 12 Read failure
+ 13 Calculating checksum failure
+ 14 Setting security bit failure
+ 15 Querying security bit failure
+ 16 Exiting ISP failure
+ 17 Performing system test failure
+
+These codes are intended to provide general information about the nature of the failure.
+Additional analysis would need to be done to determine the root cause of any one of these
+errors. In most cases, if there is any device-related problem or hardware continuity
+problem, the "Unrecognized device" error will be issued. In this case, first take the
+steps outlined in Section D for debugging the Jam Player. If debugging is unsuccessful,
+contact Altera for support.
+
+If the "Device version is not supported" error is issued, it is most likely due to a
+.jbc File that is older than the current device revision. Always use the latest version of
+MAX+PLUS II to generate the .jbc File. For more support, see Section G.
+
+jbi_execute() returns with a code indicating the success or failure of the execution. This
+code is confined to errors associated with the syntax and structural accuracy of the .jbc
+File. These codes are defined in the jbistub.c file, where the array variable "error_text[]".
+
+format_version should be set equal to "2" when calling jbi_execute. This means that the
+Player will expect a STAPL-based .jbc file.
+
+G. MEMORY USAGE
+Memory usage is documented in detail in AN 122 (Using the Jam Language for ISP via an
+Embedded Processor).
+
+H. SUPPORT
+For additional support, submit a Service Request at http://www.altera.com/mysupport. Bugs or
+suggested enhancements can also be communicated via this channel. \ No newline at end of file
diff --git a/common/recipes-utils/jbi/jbi_2.2.bb b/common/recipes-utils/jbi/jbi_2.2.bb
new file mode 100644
index 0000000..947dbac
--- /dev/null
+++ b/common/recipes-utils/jbi/jbi_2.2.bb
@@ -0,0 +1,41 @@
+# 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
+
+SUMMARY = "ALTERA Jam STAPL Byte-Code Player"
+SECTION = "utils"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://COPYING;md5=eb723b61539feef013de476e68b5c50a"
+
+SRC_URI = "file://code \
+ "
+
+S = "${WORKDIR}/code"
+
+DEPENDS += "liblog libgpio"
+
+do_install() {
+ bin="${D}/usr/local/bin"
+ install -d ${bin}
+ install -m 755 jbi ${bin}/jbi
+}
+
+FILES_${PN} = "/usr/local/bin"
+
+FILES_${PN}-dbg += "/usr/local/bin/.debug"
+
+INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
+INHIBIT_PACKAGE_STRIP = "1"
diff --git a/common/recipes-utils/openbmc-gpio/files/COPYING b/common/recipes-utils/openbmc-gpio/files/COPYING
new file mode 100644
index 0000000..3912109
--- /dev/null
+++ b/common/recipes-utils/openbmc-gpio/files/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/common/recipes-utils/openbmc-gpio/files/board_gpio_table.py b/common/recipes-utils/openbmc-gpio/files/board_gpio_table.py
new file mode 100644
index 0000000..3261f51
--- /dev/null
+++ b/common/recipes-utils/openbmc-gpio/files/board_gpio_table.py
@@ -0,0 +1,23 @@
+# 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
+
+# This is an dummy board GPIO table. If this is included in the final image,
+# please double check the configuration of your image to define the correct
+# GPIO table to be used for your board.
+
+board_gpio_table = [
+]
diff --git a/common/recipes-utils/openbmc-gpio/files/openbmc_gpio.py b/common/recipes-utils/openbmc-gpio/files/openbmc_gpio.py
new file mode 100644
index 0000000..9e92324
--- /dev/null
+++ b/common/recipes-utils/openbmc-gpio/files/openbmc_gpio.py
@@ -0,0 +1,164 @@
+# 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
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+from __future__ import unicode_literals
+
+import logging
+import os
+import string
+
+
+_gpio_shadow = '/tmp/gpionames'
+
+
+def setup_shadow(shadow=None):
+ global _gpio_shadow
+ if shadow is not None:
+ _gpio_shadow = shadow
+ if not os.path.exists(_gpio_shadow):
+ os.makedirs(_gpio_shadow)
+
+
+def gpio_name2value(name):
+ name = str(name).lower()
+ if name.startswith('gpio'):
+ name = name[4:]
+ try:
+ return int(name)
+ except:
+ # it is not just value, try treat it as name like 'A0'
+ pass
+ val = 0
+ try:
+ if len(name) != 2 and len(name) != 3:
+ raise
+ for idx in range(0, len(name)):
+ ch = name[idx]
+ if ch in string.ascii_lowercase:
+ # letter cannot be the last character
+ if idx == len(name) - 1:
+ raise
+ tmp = ord(ch) - ord('a') + 1
+ val = val * 26 + tmp
+ elif ch in string.digits:
+ # digit must be the last character
+ if idx != len(name) - 1:
+ raise
+ # the digit must be 0-7
+ tmp = ord(ch) - ord('0')
+ if tmp > 7:
+ raise
+ # 'A4' is value 4
+ if val > 0:
+ val -= 1
+ val = val * 8 + tmp
+ else:
+ raise
+ except:
+ logging.exception('Invalid GPIO name "%s"' % name)
+ return val
+
+
+def gpio_dir(name, check_shadow=True):
+ GPIODIR_FMT = '/sys/class/gpio/gpio{gpio}'
+ if check_shadow:
+ shadowdir = os.path.join(_gpio_shadow, name)
+ if os.path.isdir(shadowdir):
+ return shadowdir
+ val = gpio_name2value(name)
+ return GPIODIR_FMT.format(gpio=val)
+
+
+def gpio_get_shadow(name):
+ path = gpio_dir(name, check_shadow=False)
+ for child in os.listdir(_gpio_shadow):
+ try:
+ child = os.path.join(_gpio_shadow, child)
+ if os.readlink(child) == path:
+ return child
+ except:
+ pass
+ return None
+
+
+def gpio_export(name, shadow=None):
+ GPIOEXPORT = '/sys/class/gpio/export'
+ if shadow is not None or shadow != '':
+ shadowdir = os.path.join(_gpio_shadow, shadow)
+ if os.path.exists(shadowdir):
+ raise Exception('Shadow "%s" exists already' % shadowdir)
+ old_shadow = gpio_get_shadow(name)
+ if old_shadow is not None:
+ raise Exception('Shadow "%s" already exists for %s'
+ % (old_shadow, name))
+
+ val = gpio_name2value(name)
+ try:
+ with open(GPIOEXPORT, 'w') as f:
+ f.write('%d\n' % val)
+ except:
+ # in case the GPIO has been exported already
+ pass
+ if shadow is not None:
+ gpiodir = gpio_dir(val, check_shadow=False)
+ os.symlink(gpiodir, shadowdir)
+
+
+def gpio_get(name, change_direction=True):
+ path = gpio_dir(name)
+ if change_direction:
+ with open(os.path.join(path, 'direction'), 'w') as f:
+ f.write('in\n')
+ with open(os.path.join(path, 'value'), 'r') as f:
+ val = int(f.read().rstrip('\n'))
+ return val
+
+
+def gpio_set(name, value, change_direction=True):
+ path = gpio_dir(name)
+ with open(os.path.join(path, 'value'), 'w') as f:
+ f.write('%d\n' % (1 if value else 0))
+ if change_direction:
+ with open(os.path.join(path, 'direction'), 'w') as f:
+ f.write('out\n')
+
+
+def gpio_info(name):
+ res = {}
+ # first check if name is shadow
+ path = None
+ shadow = os.path.join(_gpio_shadow, name)
+ if os.path.exists(shadow):
+ if not os.path.islink(shadow) or not os.path.isdir(shadow):
+ raise Exception('Path "%s" is not a valid shadow path' % shadow)
+ path = os.readlink(shadow)
+ else:
+ path = gpio_dir(name, check_shadow=False)
+ shadow = gpio_get_shadow(name)
+ res['path'] = path
+ res['shadow'] = shadow
+ if os.path.isdir(path):
+ with open(os.path.join(path, 'direction'), 'r') as f:
+ res['direction'] = f.read().rstrip('\n')
+ with open(os.path.join(path, 'value'), 'r') as f:
+ res['value'] = int(f.read().rstrip('\n'))
+ else:
+ res['direction'] = None
+ res['value'] = None
+ return res
diff --git a/common/recipes-utils/openbmc-gpio/files/openbmc_gpio_setup.py b/common/recipes-utils/openbmc-gpio/files/openbmc_gpio_setup.py
new file mode 100644
index 0000000..7c126d9
--- /dev/null
+++ b/common/recipes-utils/openbmc-gpio/files/openbmc_gpio_setup.py
@@ -0,0 +1,76 @@
+#!/usr/bin/python -tt
+# 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
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+from __future__ import unicode_literals
+
+from board_gpio_table import board_gpio_table
+from soc_gpio_table import soc_gpio_table
+
+import openbmc_gpio
+import openbmc_gpio_table
+
+import logging
+import sys
+
+
+def setup_board_gpio(soc_gpio_table, board_gpio_table, validate=True):
+ soc = openbmc_gpio_table.SocGPIOTable(soc_gpio_table)
+ gpio_configured = []
+ for gpio in board_gpio_table:
+ try:
+ soc.config_function(gpio.gpio, write_through=False)
+ gpio_configured.append(gpio.gpio)
+ except openbmc_gpio_table.ConfigUnknownFunction as e:
+ # not multiple-function GPIO pin
+ pass
+ except openbmc_gpio_table.NotSmartEnoughException as e:
+ logging.error('Failed to configure "%s" for "%s": %s'
+ % (gpio.gpio, gpio.shadow, str(e)))
+
+ soc.write_to_hw()
+
+ if validate:
+ all_functions = set(soc.get_active_functions(refresh=True))
+ for gpio in gpio_configured:
+ if gpio not in all_functions:
+ raise Exception('Failed to configure function "%s"' % gpio)
+
+ for gpio in board_gpio_table:
+ openbmc_gpio.gpio_export(gpio.gpio, gpio.shadow)
+ if gpio.value == openbmc_gpio_table.GPIO_INPUT:
+ continue
+ elif gpio.value == openbmc_gpio_table.GPIO_OUT_HIGH:
+ openbmc_gpio.gpio_set(gpio.gpio, 1)
+ elif gpio.value == openbmc_gpio_table.GPIO_OUT_LOW:
+ openbmc_gpio.gpio_set(gpio.gpio, 0)
+ else:
+ raise Exception('Invalid value "%s"' % gpio.value)
+
+def main():
+ print('Setting up GPIOs ... ', end='')
+ sys.stdout.flush()
+ openbmc_gpio.setup_shadow()
+ setup_board_gpio(soc_gpio_table, board_gpio_table)
+ print('Done')
+ sys.stdout.flush()
+ return 0
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/common/recipes-utils/openbmc-gpio/files/openbmc_gpio_table.py b/common/recipes-utils/openbmc-gpio/files/openbmc_gpio_table.py
new file mode 100644
index 0000000..dda8a98
--- /dev/null
+++ b/common/recipes-utils/openbmc-gpio/files/openbmc_gpio_table.py
@@ -0,0 +1,269 @@
+# 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
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+from __future__ import unicode_literals
+
+from soc_gpio import soc_get_register
+
+import logging
+import os
+import sys
+
+
+class NotSmartEnoughException(Exception):
+ '''There are few cases the code cannot make good decision on how to configure
+ the registers automatically. In such cases, this exception is thrown.
+ '''
+ pass
+
+
+class ConfigUnknownFunction(Exception):
+ '''Unknown function to configure exception'''
+ pass
+
+
+class BitsEqual(object):
+ def __init__(self, register, bits, value):
+ self.register = register
+ self.bits = bits
+ self.value = value
+
+ def __str__(self):
+ return '%s[%s]==0x%x' \
+ % (str(soc_get_register(self.register)), self.bits, self.value)
+
+ def get_registers(self):
+ return set([self.register])
+
+ def check(self):
+ return soc_get_register(self.register).bits_value(self.bits) \
+ == self.value
+
+ def satisfy(self, **kwargs):
+ if BitsEqual.check(self):
+ return
+ reg = soc_get_register(self.register)
+ value = self.value
+ for bit in sorted(self.bits):
+ if value & 0x1 == 0x1:
+ reg.set_bit(bit, **kwargs)
+ else:
+ reg.clear_bit(bit, **kwargs)
+ value >>= 1
+
+ def unsatisfy(self, **kwargs):
+ if not BitsEqual.check(self):
+ return
+ if len(self.bits) > 1:
+ raise NotSmartEnoughException('Not able to unsatisfy '
+ 'multi-bits equal')
+ bit = self.bits[0]
+ reg = soc_get_register(self.register)
+ value = self.value
+ if value & 0x1 == 0x1:
+ reg.clear_bit(bit, **kwargs)
+ else:
+ reg.set_bit(bit, **kwargs)
+
+
+class BitsNotEqual(BitsEqual):
+ def __str__(self):
+ return '%s[%s]!=0x%x' \
+ % (str(soc_get_register(self.register)), self.bits, self.value)
+
+ def check(self):
+ return not BitsEqual.check(self)
+
+ def satisfy(self, **kwargs):
+ BitsEqual.unsatisfy(self, **kwargs)
+
+ def unsatisfy(self, **kwargs):
+ BitsEqual.satisfy(self, **kwargs)
+
+
+class AndOrBase(object):
+ def __init__(self, left, right):
+ self.left = left
+ self.right = right
+
+ def get_registers(self):
+ return self.left.get_registers() | self.right.get_registers()
+
+ def check(self):
+ raise Exception('This method must be implemented in subclass')
+
+
+class And(AndOrBase):
+ def __str__(self):
+ return 'AND(%s, %s)' % (str(self.left), str(self.right))
+
+ def check(self):
+ return self.left.check() and self.right.check()
+
+ def satisfy(self, **kwargs):
+ if self.check():
+ return
+ self.left.satisfy(**kwargs)
+ self.right.satisfy(**kwargs)
+
+ def unsatisfy(self, **kwargs):
+ if not self.check():
+ return
+ raise NotSmartEnoughException('Not able to unsatisfy an AND condition')
+
+
+class Or(AndOrBase):
+ def __str__(self):
+ return 'OR(%s, %s)' % (str(self.left), str(self.right))
+
+ def check(self):
+ return self.left.check() or self.right.check()
+
+ def satisfy(self, **kwargs):
+ if self.check():
+ return
+ raise NotSmartEnoughException('Not able to satisfy an OR condition')
+
+ def unsatisfy(self, **kwargs):
+ if not self.check():
+ return
+ self.left.unsatisfy(**kwargs)
+ self.right.unsatisfy(**kwargs)
+
+
+class Function(object):
+ def __init__(self, name, condition=None):
+ self.name = name
+ self.condition = condition
+
+ def __str__(self):
+ return 'Function(\'%s\', %s)' % (self.name, str(self.condition))
+
+
+class SocGPIOTable(object):
+ def __init__(self, gpio_table):
+ self.soc_gpio_table = gpio_table
+ self.registers = set([]) # all HW registers used for GPIO control
+ self.functions = {}
+
+ self._parse_gpio_table()
+ self._sync_from_hw()
+
+ def _parse_gpio_table(self):
+ # first get list of registers based on the SoC GPIO table
+ for pin, funcs in self.soc_gpio_table.iteritems():
+ for func in funcs:
+ assert func.name not in self.functions
+ self.functions[func.name] = pin
+ if func.condition is not None:
+ self.registers |= func.condition.get_registers()
+
+ def _sync_from_hw(self):
+ # for each register, create an object and read the value from HW
+ for reg in self.registers:
+ soc_get_register(reg).read(refresh=True)
+
+ def write_to_hw(self):
+ for reg in self.registers:
+ soc_get_register(reg).write()
+
+ def config_function(self, func_name, write_through=True):
+ logging.debug('Configure function "%s"' % func_name)
+ if func_name not in self.functions:
+ # The function is not multi-function pin
+ raise ConfigUnknownFunction('Unknown function "%s" ' % func_name)
+ funcs = self.soc_gpio_table[self.functions[func_name]]
+ for func in funcs:
+ cond = func.condition
+ if func.name == func_name:
+ # this is the function we want to configure.
+ # if the condition is None, we are good to go,
+ # otherwiset, satisfy the condition
+ if cond is not None:
+ cond.satisfy(write_through=write_through)
+ break
+ else:
+ # this is not the funciton we want to configure.
+ # have to make this condition unsatisfied, so that we can go
+ # to the next function
+ assert cond is not None
+ cond.unsatisfy(write_through=write_through)
+
+ def _get_one_pin(self, pin, refresh):
+ if refresh:
+ self._sync_from_hw()
+ funcs = self.soc_gpio_table[pin]
+ active_func = None
+ all_funcs = []
+ for func in funcs:
+ cond = func.condition
+ all_funcs.append('%s:%s' % (func.name, str(cond)))
+ if active_func is None and (cond is None or cond.check()):
+ active_func = func.name
+
+ if active_func is None:
+ logging.error('Pin "%s" has no function set up. '
+ 'All possibile functions are %s.'
+ % (pin, ', '.join(all_funcs)))
+ return ('', '')
+ else:
+ desc = '%s => %s, functions: %s' \
+ % (pin, active_func, ', '.join(all_funcs))
+ return (active_func, desc)
+
+ def dump_pin(self, pin, out=sys.stdout, refresh=False):
+ if pin not in self.soc_gpio_table:
+ raise Exception('"%s" is not a valid pin' % pin)
+
+ _, desc = self._get_one_pin(pin, refresh)
+ out.write('%s\n' % desc)
+
+ def dump_function(self, func_name, out=sys.stdout, refresh=False):
+ if func_name not in self.functions:
+ raise Exception('"%s" is not a valid function name' % func_name)
+ pin = self.functions[func_name]
+ self.dump_pin(pin, out=out, refresh=refresh)
+
+ def dump_functions(self, out=sys.stdout, refresh=False):
+ if refresh:
+ self._sync_from_hw()
+
+ for pin in self.soc_gpio_table:
+ self.dump_pin(pin, out=out, refresh=False)
+
+ def get_active_functions(self, refresh=False):
+ if refresh:
+ self._sync_from_hw()
+
+ all = []
+ for pin in self.soc_gpio_table:
+ active, _ = self._get_one_pin(pin, False)
+ all.append(active)
+ return all
+
+
+GPIO_INPUT = 'input'
+GPIO_OUT_HIGH = 'high'
+GPIO_OUT_LOW = 'low'
+
+class BoardGPIO(object):
+ def __init__(self, gpio, shadow, value=GPIO_INPUT):
+ self.gpio = gpio
+ self.shadow = shadow
+ self.value = value
diff --git a/common/recipes-utils/openbmc-gpio/files/openbmc_gpio_util.py b/common/recipes-utils/openbmc-gpio/files/openbmc_gpio_util.py
new file mode 100644
index 0000000..e4b40b0
--- /dev/null
+++ b/common/recipes-utils/openbmc-gpio/files/openbmc_gpio_util.py
@@ -0,0 +1,153 @@
+#!/usr/bin/python -tt
+# 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
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+from __future__ import unicode_literals
+
+from soc_gpio_table import soc_gpio_table
+
+import openbmc_gpio
+import openbmc_gpio_table
+
+import argparse
+import logging
+import sys
+
+
+def _get_gpio_table():
+ gpio = openbmc_gpio_table.SocGPIOTable(soc_gpio_table)
+ return gpio
+
+
+def dump_func(args):
+ gpio = _get_gpio_table()
+ gpio.dump_functions()
+ return 0
+
+
+def config_func(args):
+ gpio = _get_gpio_table()
+ try:
+ gpio.config_function(args.function)
+ except openbmc_gpio_table.NotSmartEnoughException as e:
+ print('The code is not smart enough to set function "%s": %s\n'
+ 'Please set the function manually.'
+ % (args.function, str(e)))
+ print('The current HW setting for this function is:')
+ gpio.dump_function(args.function)
+ return -1
+ except Exception as e:
+ print('Failed to set function "%s": %s\n'
+ 'Please set the function manually.'
+ % (args.function, str(e)))
+ print('The current HW setting for this function is:')
+ gpio.dump_function(args.function)
+ logging.exception('Exception:')
+ return -2
+
+ print('Function "%s" is set' % args.function)
+ return 0
+
+
+def export_func(args):
+ openbmc_gpio.gpio_export(args.gpio, args.shadow)
+
+
+def set_func(args):
+ openbmc_gpio.gpio_set(args.gpio, args.value,
+ change_direction=False if args.keep else True)
+
+
+def get_func(args):
+ val = openbmc_gpio.gpio_get(
+ args.gpio, change_direction=False if args.keep else True)
+ print('%d' % val)
+
+
+def info_func(args):
+ res = openbmc_gpio.gpio_info(args.gpio)
+ print('GPIO info for %s:' % args.gpio)
+ print('Path: %s\nShadow: %s\nDirection: %s\nValue: %s'
+ % (res['path'], res['shadow'], res['direction'], res['value']))
+
+
+def main():
+ ap = argparse.ArgumentParser()
+ ap.add_argument('--debug', action='store_true',
+ help='Enable debug messages')
+
+ subparser = ap.add_subparsers()
+
+ dump_parser = subparser.add_parser(
+ 'dump', help='Dump the current HW GPIO settings')
+ dump_parser.set_defaults(func=dump_func)
+
+ config_parser = subparser.add_parser(
+ 'config', help='Configure one HW pin to a function')
+ config_parser.add_argument(
+ 'function', help='The function name to set')
+ config_parser.set_defaults(func=config_func)
+
+ export_parser = subparser.add_parser(
+ 'export', help='Export a GPIO directory')
+ export_parser.add_argument(
+ 'gpio', help='The GPIO name, i.e. "A4", or "GPIOD2"')
+ export_parser.add_argument(
+ 'shadow', default=None,
+ help='The shadow name given to this GPIO')
+ export_parser.set_defaults(func=export_func)
+
+
+ set_parser = subparser.add_parser(
+ 'set', help='Set a value for a GPIO')
+ set_parser.add_argument(
+ 'gpio', help='The GPIO name or number')
+ set_parser.add_argument(
+ 'value', type=int, choices=[0, 1],
+ help='The value to set')
+ set_parser.add_argument(
+ '-k', '--keep', action='store_true',
+ help='Keep the GPIO direction')
+ set_parser.set_defaults(func=set_func)
+
+ get_parser = subparser.add_parser(
+ 'get', help='Get a GPIO\'s value')
+ get_parser.add_argument(
+ 'gpio', help='The GPIO name or number')
+ get_parser.add_argument(
+ '-k', '--keep', action='store_true',
+ help='Keep the GPIO direction')
+ get_parser.set_defaults(func=get_func)
+
+ info_parser = subparser.add_parser(
+ 'info', help='Get a GPIO\'s info')
+ info_parser.add_argument(
+ 'gpio', help='The GPIO name or number')
+ info_parser.set_defaults(func=info_func)
+
+ args = ap.parse_args()
+
+ logging.basicConfig(level=logging.DEBUG if args.debug else logging.INFO,
+ format='%(asctime)s: %(message)s')
+
+ return args.func(args)
+
+
+rc = main()
+sys.exit(rc)
diff --git a/common/recipes-utils/openbmc-gpio/files/phymemory.py b/common/recipes-utils/openbmc-gpio/files/phymemory.py
new file mode 100644
index 0000000..97a0d6e
--- /dev/null
+++ b/common/recipes-utils/openbmc-gpio/files/phymemory.py
@@ -0,0 +1,100 @@
+# 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
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+from __future__ import unicode_literals
+
+import subprocess
+import logging
+
+
+class PhyMemory(object):
+ def __init__(self, addr, name=''):
+ self.addr = addr
+ self.name = name
+ self.write_pending = False
+ self.value = 0
+
+ def __del__(self):
+ if self.write_pending:
+ logging.warning('Value (0x%x) is not wrote back to address (0x%x)'
+ % (self.value, self.addr))
+
+ def __str__(self):
+ if self.name == '':
+ return '0x%x' % self.addr
+ else:
+ return self.name
+
+ def _read_hw(self):
+ if self.write_pending:
+ raise Exception('Value (0x%x) is not wrote back to address (0x%x) '
+ 'before reading HW' % (self.value, self.addr))
+ cmd = ['devmem', '0x%x' % self.addr]
+ out = subprocess.check_output(cmd)
+ self.value = int(out, 16)
+ logging.debug('Read from %s @0x%x, got value (0x%x)'
+ % (str(self), self.addr, self.value))
+
+ def read(self, refresh=True):
+ if refresh:
+ self._read_hw()
+ return self.value
+
+ def write(self, force=False):
+ if not force and not self.write_pending:
+ return
+ cmd = ['devmem', '0x%x' % self.addr, '32', '0x%x' % self.value]
+ subprocess.check_call(cmd)
+ self.write_pending = False
+ logging.debug('Wrote to %s address @0x%x with value (0x%x)'
+ % (str(self), self.addr, self.value))
+
+ def set_bit(self, bit, write_through=True):
+ assert 0 <= bit <= 31
+ self.value |= 1 << bit
+ self.write_pending = True
+ logging.debug('Set bit %s[%d] (0x%x)' % (str(self), bit, self.value))
+ if write_through:
+ self.write()
+
+ def clear_bit(self, bit, write_through=True):
+ assert 0 <= bit <= 31
+ self.value &= ~(1 << bit)
+ self.write_pending = True
+ logging.debug('Clear bit %s[%d] (0x%x)' % (str(self), bit, self.value))
+ if write_through:
+ self.write()
+
+ def is_bit_set(self, bit, refresh=False):
+ assert 0 <= bit <= 31
+ self.read(refresh=refresh)
+ rc = True if self.value & (0x1 << bit) else False
+ logging.debug('Test bit %s[%d](0x%x): %s'
+ % (str(self), bit, self.value, rc))
+ return rc
+
+ def bits_value(self, bits, refresh=False):
+ self.read(refresh=refresh)
+ value = 0
+ for bit in sorted(bits, reverse=True):
+ assert 0 <= bit <= 31
+ value = (value << 1) | ((self.value >> bit) & 0x1)
+ logging.debug('%s%s is 0x%x (0x%x)'
+ % (str(self), bits, value, self.value))
+ return value
diff --git a/common/recipes-utils/openbmc-gpio/files/setup.py b/common/recipes-utils/openbmc-gpio/files/setup.py
new file mode 100644
index 0000000..59c7de4
--- /dev/null
+++ b/common/recipes-utils/openbmc-gpio/files/setup.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+# 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
+
+
+from distutils.core import setup
+
+setup(
+ name = 'openbmc-gpio',
+ version = '1.0',
+ description = 'OpenBMC GPIO utilities',
+ author = 'Tian Fang',
+ author_email = 'tfang@fb.com',
+ license = 'GPLv2',
+ py_modules=['openbmc_gpio',
+ 'openbmc_gpio_table',
+ 'phymemory',
+ 'soc_gpio',
+ 'soc_gpio_table',
+ 'board_gpio_table',
+ ],
+)
diff --git a/common/recipes-utils/openbmc-gpio/files/soc_gpio.py b/common/recipes-utils/openbmc-gpio/files/soc_gpio.py
new file mode 100644
index 0000000..2718af8
--- /dev/null
+++ b/common/recipes-utils/openbmc-gpio/files/soc_gpio.py
@@ -0,0 +1,19 @@
+# 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
+
+def soc_get_register(addr):
+ raise Exception('Virtual function. Not implemented')
diff --git a/common/recipes-utils/openbmc-gpio/files/soc_gpio_table.py b/common/recipes-utils/openbmc-gpio/files/soc_gpio_table.py
new file mode 100644
index 0000000..45713e9
--- /dev/null
+++ b/common/recipes-utils/openbmc-gpio/files/soc_gpio_table.py
@@ -0,0 +1,23 @@
+# 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
+
+# This is an dummy SoC GPIO table. If this is included in the final image,
+# please double check the configuration of your image to define the correct
+# SoC GPIO table to be used for your board.
+
+soc_gpio_table = {
+}
diff --git a/common/recipes-utils/openbmc-gpio/openbmc-gpio_0.1.bb b/common/recipes-utils/openbmc-gpio/openbmc-gpio_0.1.bb
new file mode 100644
index 0000000..6bf4cc1
--- /dev/null
+++ b/common/recipes-utils/openbmc-gpio/openbmc-gpio_0.1.bb
@@ -0,0 +1,75 @@
+# 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
+
+SUMMARY = "OpenBMC GPIO utilies"
+SECTION = "base"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://COPYING;md5=eb723b61539feef013de476e68b5c50a"
+
+SRC_URI = " \
+ file://COPYING \
+ file://board_gpio_table.py \
+ file://openbmc_gpio.py \
+ file://openbmc_gpio_table.py \
+ file://openbmc_gpio_setup.py \
+ file://openbmc_gpio_util.py \
+ file://phymemory.py \
+ file://setup.py \
+ file://soc_gpio.py \
+ file://soc_gpio_table.py \
+ "
+
+S = "${WORKDIR}"
+
+OPENBMC_GPIO_UTILS = " \
+ openbmc_gpio_util.py \
+ "
+
+OPENBMC_GPIO_SOC_TABLE = "soc_gpio_table.py"
+
+# Change OPENBMC_GPIO_SETUP to "0" to exclude openbmc_gpio_setup.py from the image
+OPENBMC_GPIO_SETUP = "1"
+
+inherit distutils
+
+DEPENDS_${PN} = "python python-distribute update-rc.d-native"
+
+RDEPENDS_${PN} = "python-core python-argparse python-subprocess"
+
+do_board_defined_soc_table() {
+ if [ "${OPENBMC_GPIO_SOC_TABLE}" != "soc_gpio_table.py" ]; then
+ mv -f "${S}/${OPENBMC_GPIO_SOC_TABLE}" "${S}/soc_gpio_table.py"
+ fi
+}
+addtask board_defined_soc_table after do_unpack before do_build
+
+do_install_append() {
+ localbindir="${D}/usr/local/bin"
+ install -d ${localbindir}
+ for f in ${OPENBMC_GPIO_UTILS}; do
+ install -m 755 $f ${localbindir}/${f}
+ done
+
+ install -d ${D}${sysconfdir}/init.d
+ install -d ${D}${sysconfdir}/rcS.d
+ if [ "${OPENBMC_GPIO_SETUP}" == "1" ]; then
+ install -m 755 openbmc_gpio_setup.py ${D}${sysconfdir}/init.d/openbmc_gpio_setup.py
+ update-rc.d -r ${D} openbmc_gpio_setup.py start 59 S .
+ fi
+}
+
+FILES_${PN} += "/usr/local/bin ${sysconfdir}"
diff --git a/common/recipes-utils/openbmc-utils/files/COPYING b/common/recipes-utils/openbmc-utils/files/COPYING
new file mode 100644
index 0000000..3912109
--- /dev/null
+++ b/common/recipes-utils/openbmc-utils/files/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/common/recipes-utils/openbmc-utils/files/openbmc-utils.sh b/common/recipes-utils/openbmc-utils/files/openbmc-utils.sh
new file mode 100644
index 0000000..885a6eb
--- /dev/null
+++ b/common/recipes-utils/openbmc-utils/files/openbmc-utils.sh
@@ -0,0 +1,133 @@
+# 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
+
+DEVMEM=/sbin/devmem
+SHADOW_GPIO=/tmp/gpionames
+
+devmem_set_bit() {
+ local addr
+ local val
+ addr=$1
+ val=$($DEVMEM $addr)
+ val=$((val | (0x1 << $2)))
+ $DEVMEM $addr 32 $val
+}
+
+devmem_clear_bit() {
+ local addr
+ local val
+ addr=$1
+ val=$($DEVMEM $addr)
+ val=$((val & ~(0x1 << $2)))
+ $DEVMEM $addr 32 $val
+}
+
+GPIODIR="/sys/class/gpio"
+GPIOEXPORT="$GPIODIR/export"
+
+gpio_dir() {
+ echo "$GPIODIR/gpio$1"
+}
+
+gpio_name2value() {
+ local first remaining base val
+ remaining=$1
+ base="${SHADOW_GPIO}/${remaining}"
+ if [ -L "${base}" ]; then
+ val=$(readlink -f ${base} 2>/dev/null)
+ if [ -n "${val}" ]; then
+ val=${val##*gpio}
+ if [ -n "${val}" ]; then
+ echo "$val"
+ return
+ fi
+ fi
+ fi
+ val=0
+ while [ -n "$remaining" ]; do
+ first=${remaining:0:1}
+ case "$first" in
+ [[:lower:]])
+ base=$(printf "%d" "'$first'")
+ base=$((base - 96))
+ val=$((val * 26 + base))
+ ;;
+ [[:upper:]])
+ base=$(printf "%d" "'$first'")
+ base=$((base - 64))
+ val=$((val * 26 + base))
+ ;;
+ *)
+ if [ $val -gt 0 ]; then
+ val=$((val-1))
+ fi
+ val=$((val * 8 + $remaining))
+ break
+ ;;
+ esac
+ remaining=${remaining:1}
+ done
+ echo "$val"
+}
+
+gpio_export() {
+ local gpio
+ gpio=$(gpio_name2value $1)
+ dir=$(gpio_dir $gpio)
+ if [ ! -d ${dir} ]; then
+ echo $gpio > $GPIOEXPORT
+ fi
+ if [ $# -gt 1 ]; then
+ if [ ! -d $SHADOW_GPIO ]; then
+ mkdir -p $SHADOW_GPIO
+ fi
+ ln -s $dir $SHADOW_GPIO/$2
+ fi
+}
+
+gpio_set() {
+ local gpio
+ local val
+ gpio=$(gpio_name2value $1)
+ val=$2
+ dir=$(gpio_dir $gpio)
+ if [ ! -d ${dir} ]; then
+ echo $gpio > $GPIOEXPORT
+ fi
+ echo $val > ${dir}/value
+ echo out > ${dir}/direction
+}
+
+gpio_get() {
+ local gpio
+ local val
+ gpio=$(gpio_name2value $1)
+ dir=$(gpio_dir $gpio)
+ if [ ! -d ${dir} ]; then
+ echo $gpio > $GPIOEXPORT
+ fi
+ echo in > ${dir}/direction
+ cat ${dir}/value
+}
+
+if [ -f "/usr/local/bin/soc-utils.sh" ]; then
+ source "/usr/local/bin/soc-utils.sh"
+fi
+
+if [ -f "/usr/local/bin/board-utils.sh" ]; then
+ source "/usr/local/bin/board-utils.sh"
+fi
diff --git a/common/recipes-utils/openbmc-utils/openbmc-utils_0.1.bb b/common/recipes-utils/openbmc-utils/openbmc-utils_0.1.bb
new file mode 100644
index 0000000..f40d48b
--- /dev/null
+++ b/common/recipes-utils/openbmc-utils/openbmc-utils_0.1.bb
@@ -0,0 +1,48 @@
+# 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
+
+SUMMARY = "OpenBMC Utilities"
+DESCRIPTION = "Various OpenBMC utilities"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://COPYING;md5=eb723b61539feef013de476e68b5c50a"
+
+SRC_URI = " \
+ file://COPYING \
+ file://openbmc-utils.sh \
+ "
+
+OPENBMC_UTILS_FILES = " \
+ openbmc-utils.sh \
+ "
+
+S = "${WORKDIR}"
+
+do_install() {
+ pkgdir="/usr/local/packages/utils"
+ dstdir="${D}${pkgdir}"
+ install -d $dstdir
+ localbindir="${D}/usr/local/bin"
+ install -d ${localbindir}
+ for f in ${OPENBMC_UTILS_FILES}; do
+ install -m 755 $f ${dstdir}/${f}
+ ln -s ${pkgdir}/${f} ${localbindir}
+ done
+}
+
+FILES_${PN} += "/usr/local"
diff --git a/common/recipes-utils/spatula/files/setup-spatula.sh b/common/recipes-utils/spatula/files/setup-spatula.sh
new file mode 100644
index 0000000..391a212
--- /dev/null
+++ b/common/recipes-utils/spatula/files/setup-spatula.sh
@@ -0,0 +1,80 @@
+#!/bin/sh
+#
+# 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
+#
+
+### BEGIN INIT INFO
+# Provides: setup-spatula-wrapper
+# Required-Start:
+# Required-Stop:
+# Default-Start: S
+# Default-Stop:
+# Short-Description: Set Spatula Wrapper
+### END INIT INFO
+
+# source function library
+. /etc/init.d/functions
+
+ACTION="$1"
+CMD="/usr/local/bin/spatula_wrapper.py"
+case "$ACTION" in
+ start)
+ echo -n "Setting up Spatula: "
+ pid=$(ps | grep -v grep | grep $CMD | awk '{print $1}')
+ if [ $pid ]; then
+ echo "already running"
+ else
+ $CMD > /var/log/spatula.log 2>&1 &
+ echo "done."
+ fi
+ ;;
+ stop)
+ echo -n "Stopping Spatula: "
+ pid=$(ps | grep -v grep | grep $CMD | awk '{print $1}')
+ if [ $pid ]; then
+ kill $pid
+ fi
+ echo "done."
+ ;;
+ restart)
+ echo -n "Restarting Spatula: "
+ pid=$(ps | grep -v grep | grep $CMD | awk '{print $1}')
+ if [ $pid ]; then
+ kill $pid
+ fi
+ sleep 1
+ $CMD > /var/log/spatula.log 2>&1 &
+ echo "done."
+ ;;
+ status)
+ if [[ -n $(ps | grep -v grep | grep $CMD | awk '{print $1}') ]]; then
+ echo "Spatula is running"
+ else
+ echo "Spatula is stopped"
+ fi
+ ;;
+ *)
+ N=${0##*/}
+ N=${N#[SK]??}
+ echo "Usage: $N {start|stop|status|restart}" >&2
+ exit 1
+ ;;
+esac
+
+exit 0
+
diff --git a/common/recipes-utils/spatula/files/spatula_wrapper.py b/common/recipes-utils/spatula/files/spatula_wrapper.py
new file mode 100644
index 0000000..2717bef
--- /dev/null
+++ b/common/recipes-utils/spatula/files/spatula_wrapper.py
@@ -0,0 +1,120 @@
+#!/usr/bin/env python
+#
+# 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
+#
+
+import urllib2, urllib
+import logging
+import os
+import subprocess
+import time
+import argparse
+
+SPATULA_FILE = '/etc/spatula/spatula'
+LOG_FORMAT = '[%(levelname)s] %(asctime)s: %(message)s'
+DATE_FORMAT = '%Y-%m-%d %H:%M:%S'
+DEFAULT_SLEEP = 900 # default sleep 15 mins
+
+class SpatulaWrapper(object):
+ def __init__(self, address='fe80::2', interface='usb0',
+ port=8087, ssl=False):
+ proto = 'http'
+ if ssl:
+ proto = 'https'
+ self.url = '{proto}://{address}%{iface}:{port}'.format(
+ proto = proto,
+ address = address,
+ iface = interface,
+ port = port)
+
+ def _getSpatula(self, endpoint='/spatula'):
+ '''
+ Get the executable spatula script from the host.
+ '''
+ url = '{}{}'.format(self.url, endpoint)
+ try:
+ request = urllib2.Request(url)
+ response = urllib2.urlopen(request)
+ return response.read()
+ except Exception as err:
+ raise Exception('failed getting Spatula {}: {}'.format(url, err))
+
+ def _success(self, endpoint='/success'):
+ '''
+ Api to report the timestamp of a successful run
+ '''
+ query = urllib.urlencode({'timestamp': time.time()})
+ url = '{}{}?{}'.format(self.url, endpoint, query)
+ try:
+ request = urllib2.Request(url)
+ response = urllib2.urlopen(request)
+ return response.read()
+ except Exception as err:
+ raise Exception('failed report success {}: {}'.format(url, err))
+
+ def _error(self, error, endpoint='/error'):
+ '''
+ Api to report the timestamp and the error when spatula fails
+ '''
+ query = urllib.urlencode({'timestamp': time.time(), 'error': error})
+ url = '{}{}?{}'.format(self.url, endpoint, query)
+ try:
+ request = urllib2.Request(url)
+ response = urllib2.urlopen(request)
+ return response.read()
+ except Exception as err:
+ raise Exception('failed report error [{}]: {}'.format(url, err))
+
+ def _execute(self):
+ try:
+ # get the executable from host
+ if not os.path.exists(os.path.dirname(SPATULA_FILE)):
+ os.makedirs(os.path.dirname(SPATULA_FILE))
+ with open(SPATULA_FILE, 'w+') as file:
+ file.write(self._getSpatula())
+ file.close()
+ # set the permission
+ os.chmod(SPATULA_FILE, 0755)
+ # run the executable file
+ spatula = subprocess.Popen([SPATULA_FILE],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ out, err = spatula.communicate()
+ if spatula.returncode != 0:
+ raise Exception('spatula failed: {}'.format(err))
+ self._success()
+ except Exception as err:
+ self._error(err)
+ raise err
+
+ def run(self, sleep):
+ while True:
+ try:
+ self._execute()
+ except Exception as err:
+ logging.error(err)
+ time.sleep(sleep)
+
+if __name__ == '__main__':
+ args = argparse.ArgumentParser()
+ args.add_argument('-s', '--sleep', default=DEFAULT_SLEEP,
+ help='Sleep time between spatula runs (default=%(default)s)')
+ params = args.parse_args()
+ logging.basicConfig(format=LOG_FORMAT, datefmt=DATE_FORMAT)
+ wrapper = SpatulaWrapper()
+ wrapper.run(params.sleep)
diff --git a/common/recipes-utils/spatula/spatula_0.1.bb b/common/recipes-utils/spatula/spatula_0.1.bb
new file mode 100644
index 0000000..dd54ccd
--- /dev/null
+++ b/common/recipes-utils/spatula/spatula_0.1.bb
@@ -0,0 +1,47 @@
+# 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
+SUMMARY = "Configure the BMC"
+DESCRIPTION = "The script communicates with host and configures BMC."
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://spatula_wrapper.py;beginline=5;endline=18;md5=0b1ee7d6f844d472fa306b2fee2167e0"
+
+
+DEPENDS_append = " update-rc.d-native"
+
+SRC_URI = "file://setup-spatula.sh \
+ file://spatula_wrapper.py \
+ "
+
+S = "${WORKDIR}"
+
+binfiles = "spatula_wrapper.py"
+
+do_install() {
+ bin="${D}/usr/local/bin"
+ install -d $bin
+ for f in ${binfiles}; do
+ install -m 755 $f ${bin}/$f
+ done
+ install -d ${D}${sysconfdir}/init.d
+ install -d ${D}${sysconfdir}/rcS.d
+ install -m 755 setup-spatula.sh ${D}${sysconfdir}/init.d/setup-spatula.sh
+ update-rc.d -r ${D} setup-spatula.sh start 95 2 3 4 5 .
+}
+
+FILES_${PN} = "${prefix}/local/bin ${sysconfdir} "
diff --git a/meta-aspeed/recipes-bsp/u-boot/files/patch-2013.07/0002-Create-snapshot-of-OpenBMC.patch b/meta-aspeed/recipes-bsp/u-boot/files/patch-2013.07/0002-Create-snapshot-of-OpenBMC.patch
new file mode 100644
index 0000000..779d9a7
--- /dev/null
+++ b/meta-aspeed/recipes-bsp/u-boot/files/patch-2013.07/0002-Create-snapshot-of-OpenBMC.patch
@@ -0,0 +1,1234 @@
+From 19459c799ac0a521082d6d79e68ffc3decb18ea2 Mon Sep 17 00:00:00 2001
+From: Ori Bernstein <orib@fb.com>
+Date: Thu, 3 Sep 2015 11:28:27 -0700
+Subject: [PATCH] Create snapshot of OpenBMC
+
+---
+ .../u-boot-v2013.07/board/aspeed/ast2400/ast2400.c | 20 +-
+ .../board/aspeed/ast2400/platform.S | 35 ++
+ .../u-boot/files/u-boot-v2013.07/boards.cfg | 3 +
+ .../files/u-boot-v2013.07/drivers/net/aspeednic.c | 3 +-
+ .../u-boot-v2013.07/include/configs/ast2400.h | 1 +
+ .../u-boot-v2013.07/include/configs/fbplatform1.h | 353 ++++++++++++++++++++
+ .../u-boot-v2013.07/include/configs/fbyosemite.h | 353 ++++++++++++++++++++
+ .../u-boot-v2013.07/include/configs/wedge100.h | 354 +++++++++++++++++++++
+ 8 files changed, 1117 insertions(+), 5 deletions(-)
+ create mode 100644 meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/include/configs/fbplatform1.h
+ create mode 100644 meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/include/configs/fbyosemite.h
+ create mode 100644 meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/include/configs/wedge100.h
+
+diff --git a/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/board/aspeed/ast2400/ast2400.c b/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/board/aspeed/ast2400/ast2400.c
+index 55ed6b7..125957e 100644
+--- a/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/board/aspeed/ast2400/ast2400.c
++++ b/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/board/aspeed/ast2400/ast2400.c
+@@ -194,15 +194,27 @@ int ast1070_calibration()
+ static void watchdog_init()
+ {
+ #ifdef CONFIG_ASPEED_ENABLE_WATCHDOG
+-#define AST_WDT_BASE 0x1e785000
++#define AST_WDT1_BASE 0x1e785000
++#define AST_WDT2_BASE 0x1e785020
+ #define AST_WDT_CLK (1*1000*1000) /* 1M clock source */
+ u32 reload = AST_WDT_CLK * CONFIG_ASPEED_WATCHDOG_TIMEOUT;
++#ifdef CONFIG_ASPEED_ENABLE_DUAL_BOOT_WATCHDOG
++ /* dual boot watchdog is enabled */
+ /* set the reload value */
+- __raw_writel(reload, AST_WDT_BASE + 0x04);
++ reload = AST_WDT_CLK * CONFIG_ASPEED_WATCHDOG_DUAL_BOOT_TIMEOUT;
++ /* set the reload value */
++ __raw_writel(reload, AST_WDT2_BASE + 0x04);
++ /* magic word to reload */
++ __raw_writel(0x4755, AST_WDT2_BASE + 0x08);
++ printf("Dual boot watchdog: %us\n", CONFIG_ASPEED_WATCHDOG_DUAL_BOOT_TIMEOUT);
++#endif
++ reload = AST_WDT_CLK * CONFIG_ASPEED_WATCHDOG_TIMEOUT;
++ /* set the reload value */
++ __raw_writel(reload, AST_WDT1_BASE + 0x04);
+ /* magic word to reload */
+- __raw_writel(0x4755, AST_WDT_BASE + 0x08);
++ __raw_writel(0x4755, AST_WDT1_BASE + 0x08);
+ /* start the watchdog with 1M clk src and reset whole chip */
+- __raw_writel(0x33, AST_WDT_BASE + 0x0c);
++ __raw_writel(0x33, AST_WDT1_BASE + 0x0c);
+ printf("Watchdog: %us\n", CONFIG_ASPEED_WATCHDOG_TIMEOUT);
+ #endif
+ }
+diff --git a/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/board/aspeed/ast2400/platform.S b/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/board/aspeed/ast2400/platform.S
+index dd94da0..64967f4 100644
+--- a/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/board/aspeed/ast2400/platform.S
++++ b/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/board/aspeed/ast2400/platform.S
+@@ -333,10 +333,45 @@ set_MPLL:
+ and r1, r2, r1
+ str r1, [r0]
+
++/* Yosemite Platform specific Initialization */
++#ifdef CONFIG_YOSEMITE
++/*
++ * Disable WDT2 before the 2nd SPI flash is tried
++ * TODO: Need to detect booting from 2nd flash and recover
++ */
++ ldr r0, =0x1e78502c
++ mov r1, #0x0
++ str r1, [r0]
++
++/* Use GPIOE2/GPIOE3 to select BMC Output on debug console */
++ ldr r1, =0x0C
++ ldr r0, =0x1e780024
++ str r1, [r0]
++
++ ldr r0, =0x1e780020
++ str r1, [r0]
++
++ ldr r1, = 0x80
++ ldr r0, =0x1e780084
++ str r1, [r0]
++
++
++ ldr r1, = 0x80
++ ldr r0, =0x1e780080
++ str r1, [r0]
++
++ ldr r1, = 0x0
++ ldr r0, =0x1e780080
++ str r1, [r0]
++#endif
++
+ /* Debug - UART console message */
++// Enable UART3/4 only for non-yosemite platform
++#ifndef CONFIG_YOSEMITE
+ ldr r0, =0x1e6e2080
+ ldr r1, =0xFFFF0000 @ enable UART3 and UART4
+ str r1, [r0]
++#endif
+
+ ldr r0, =CONFIG_ASPEED_COM_LCR
+ mov r1, #0x83
+diff --git a/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/boards.cfg b/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/boards.cfg
+index ce6bff1..556de75 100644
+--- a/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/boards.cfg
++++ b/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/boards.cfg
+@@ -73,6 +73,9 @@ VCMA9 arm arm920t vcma9 mpl
+ smdk2410 arm arm920t - samsung s3c24x0
+ omap1510inn arm arm925t - ti
+ wedge arm arm926ejs ast2400 aspeed aspeed
++wedge100 arm arm926ejs ast2400 aspeed aspeed
++fbyosemite arm arm926ejs ast2400 aspeed aspeed
++fbplatform1 arm arm926ejs ast2400 aspeed aspeed
+ integratorap_cm926ejs arm arm926ejs integrator armltd - integratorap:CM926EJ_S
+ integratorcp_cm926ejs arm arm926ejs integrator armltd - integratorcp:CM924EJ_S
+ aspenite arm arm926ejs - Marvell armada100
+diff --git a/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/drivers/net/aspeednic.c b/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/drivers/net/aspeednic.c
+index d75ef67..86f6dec 100644
+--- a/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/drivers/net/aspeednic.c
++++ b/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/drivers/net/aspeednic.c
+@@ -471,8 +471,8 @@ int aspeednic_initialize(bd_t *bis)
+ struct eth_device* dev;
+
+ #if defined(CONFIG_AST2300_FPGA_2) || defined(CONFIG_AST2300) || defined(CONFIG_AST3100) || defined(CONFIG_AST2400)
+-//AST2300
+ //MAC1 CLOCK/RESET/PHY_LINK/MDC_MDIO in SCU
++#ifdef CONFIG_MAC1_ENABLE
+ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL));
+ *(volatile u_long *)(SCU_BASE + SCU_RESET_CONTROL) = cpu_to_le32(SCURegister | 0x800);
+ udelay(100);
+@@ -494,6 +494,7 @@ int aspeednic_initialize(bd_t *bis)
+ SCURegister = le32_to_cpu(*(volatile u_long *)(SCU_BASE + SCU_MULTIFUNCTION_PIN_CTL1_REG));
+ *(volatile u_long *)(SCU_BASE + SCU_MULTIFUNCTION_PIN_CTL1_REG) = cpu_to_le32(SCURegister | (MAC1_PHY_LINK));
+ #endif
++#endif
+
+ //MAC2 CLOCK/RESET/PHY_LINK/MDC_MDIO
+ #ifdef CONFIG_MAC2_ENABLE
+diff --git a/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/include/configs/ast2400.h b/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/include/configs/ast2400.h
+index 670fcfd..4c43d6f 100644
+--- a/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/include/configs/ast2400.h
++++ b/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/include/configs/ast2400.h
+@@ -284,6 +284,7 @@
+ #define __LITTLE_ENDIAN_BITFIELD
+ #define CONFIG_MAC_PARTITION
+ #define CONFIG_ASPEEDNIC
++#define CONFIG_MAC1_ENABLE
+ #define CONFIG_MAC1_PHY_LINK_INTERRUPT
+ #define CONFIG_MAC2_ENABLE
+ #define CONFIG_MAC2_PHY_LINK_INTERRUPT
+diff --git a/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/include/configs/fbplatform1.h b/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/include/configs/fbplatform1.h
+new file mode 100644
+index 0000000..22718fb
+--- /dev/null
++++ b/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/include/configs/fbplatform1.h
+@@ -0,0 +1,353 @@
++/*
++ * Copyright 2015-present Facebook. All Rights Reserved.
++ *
++ * 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., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++/* Uncommit the following line to enable JTAG in u-boot */
++//#define CONFIG_ASPEED_ENABLE_JTAG
++
++/*
++ * High Level Configuration Options
++ * (easy to change)
++ */
++//#define CONFIG_INIT_CRITICAL /* define for U-BOOT 1.1.1 */
++#undef CONFIG_INIT_CRITICAL /* undef for U-BOOT 1.1.4 */
++//#define CONFIG_FPGA_ASPEED 1
++#define CONFIG_ARM926EJS 1 /* This is an arm926ejs CPU */
++#define CONFIG_ASPEED 1
++#define CONFIG_AST2400 1
++//#define CONFIG_AST1070 1
++//#define CONFIG_SYS_FLASH_CFI /* CONFIG_FLASH_CFI, CONFIG_FLASH_SPI is exclusive*/
++#define CONFIG_FLASH_SPI
++//#define CONFIG_2SPIFLASH /* Boot SPI: CS2, 2nd SPI: CS0 */
++#undef CONFIG_2SPIFLASH
++#undef CONFIG_ASPEED_SLT
++#define CONFIG_FLASH_AST2300
++//#define CONFIG_FLASH_AST2300_DMA
++//#define CONFIG_FLASH_SPIx2_Dummy
++//#define CONFIG_FLASH_SPIx4_Dummy
++#define CONFIG_CRT_DISPLAY 1 /* undef if not support CRT */
++
++//#define CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
++#define CONFIG_MISC_INIT_R
++
++#define CONFIG_FBPLATFORM1
++
++/*
++ * DRAM Config
++ *
++ * 1. DRAM Size //
++ * CONFIG_DRAM_512MBIT // 512M bit
++ * CONFIG_DRAM_1GBIT // 1G bit (default)
++ * CONFIG_DRAM_2GBIT // 2G bit
++ * CONFIG_DRAM_4GBIT // 4G bit
++ * 2. DRAM Speed //
++ * CONFIG_DRAM_336 // 336MHz (DDR-667)
++ * CONFIG_DRAM_408 // 408MHz (DDR-800) (default)
++ * 3. VGA Mode
++ * CONFIG_CRT_DISPLAY // define to disable VGA function
++ * 4. ECC Function enable
++ * CONFIG_DRAM_ECC // define to enable ECC function
++ * 5. UART Debug Message
++ * CONFIG_DRAM_UART_OUT // enable output message at UART5
++ * CONFIG_DRAM_UART_38400 // set the UART baud rate to 38400, default is 115200
++ */
++
++//1. DRAM Size
++//#define CONFIG_DRAM_512MBIT
++#define CONFIG_DRAM_1GBIT
++//#define CONFIG_DRAM_2GBIT
++//#define CONFIG_DRAM_4GBIT
++//2. DRAM Speed
++//#define CONFIG_DRAM_336
++#define CONFIG_DRAM_408
++//3. VGA Mode
++//#define CONFIG_CRT_DISPLAY
++//4. ECC Function enable
++//#define CONFIG_DRAM_ECC
++//5. UART Debug Message
++#define CONFIG_DRAM_UART_OUT
++//#define CONFIG_DRAM_UART_38400
++
++
++
++/*
++ * Environment Config
++ */
++#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
++#define CONFIG_SETUP_MEMORY_TAGS 1
++#define CONFIG_INITRD_TAG 1
++#define CONFIG_BOOTARGS "debug console=ttyS0,57600n8 root=/dev/ram rw"
++#define CONFIG_UPDATE "tftp 40800000 ast2400.scr; so 40800000'"
++
++#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
++#define CONFIG_AUTOBOOT_KEYED
++#define CONFIG_AUTOBOOT_PROMPT \
++ "autoboot in %d seconds (stop with 'Delete' key)...\n", bootdelay
++#define CONFIG_AUTOBOOT_STOP_STR "\x1b\x5b\x33\x7e" /* 'Delete', ESC[3~ */
++#define CONFIG_ZERO_BOOTDELAY_CHECK
++
++#ifdef CONFIG_FLASH_AST2300
++#define CONFIG_BOOTCOMMAND "bootm 20080000 20300000"
++#else
++#ifdef CONFIG_SYS_FLASH_CFI
++#define CONFIG_BOOTCOMMAND "bootm 10080000 10300000"
++#else
++#define CONFIG_BOOTCOMMAND "bootm 14080000 14300000"
++#endif
++#endif
++#define CONFIG_BOOTFILE "all.bin"
++#define CONFIG_ENV_OVERWRITE
++
++/*
++ * Command line configuration.
++ */
++#include <config_cmd_default.h>
++
++#define CONFIG_CMD_DFL
++#define CONFIG_CMD_ENV
++#define CONFIG_CMD_FLASH
++#define CONFIG_CMD_MII
++#define CONFIG_CMD_NET
++#define CONFIG_CMD_PING
++#define CONFIG_CMD_I2C
++#define CONFIG_CMD_EEPROM
++#define CONFIG_CMD_NETTEST
++#define CONFIG_CMD_SLT
++
++/*
++ * CPU Setting
++ */
++#define CPU_CLOCK_RATE 18000000 /* 16.5 MHz clock for the ARM core */
++
++/*
++ * Size of malloc() pool
++ */
++#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 768*1024)
++#define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
++
++/*
++ * Stack sizes, The stack sizes are set up in start.S using the settings below
++ */
++#define CONFIG_STACKSIZE (128*1024) /* regular stack */
++#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
++#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
++
++/*
++ * Memory Configuration
++ */
++#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
++#define PHYS_SDRAM_1 0x40000000 /* SDRAM Bank #1 */
++#define PHYS_SDRAM_1_SIZE 0x8000000 /* 128 MB */
++
++#define CONFIG_SYS_SDRAM_BASE 0x40000000
++
++/*
++ * FLASH Configuration
++ */
++#ifdef CONFIG_SYS_FLASH_CFI /* NOR Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x10000000 /* Flash Bank #1 */
++#endif
++
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (256) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x60000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
++
++#define CONFIG_SYS_FLASH_CFI_AMD_RESET
++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++
++#else /* SPI Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x14000000 /* Flash Bank #1 */
++#define PHYS_FLASH_2 0x14800000 /* Flash Bank #2 */
++#define PHYS_FLASH_2_BASE 0x10000000
++#endif
++
++#ifdef CONFIG_2SPIFLASH
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_2_BASE
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1, PHYS_FLASH_2 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 2
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#else
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x60000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
++#define CONFIG_ASPEED_WRITE_DEFAULT_ENV
++#endif
++
++#endif
++
++#define __LITTLE_ENDIAN 1
++
++#define CONFIG_MONITOR_BASE TEXT_BASE
++#define CONFIG_MONITOR_LEN (192 << 10)
++
++/* timeout values are in ticks */
++#define CONFIG_SYS_FLASH_ERASE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Erase */
++#define CONFIG_SYS_FLASH_WRITE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Write */
++
++/*
++ * Miscellaneous configurable options
++ */
++#define CONFIG_SYS_LONGHELP /* undef to save memory */
++
++#define CONFIG_SYS_PROMPT "boot# " /* Monitor Command Prompt */
++#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print Buffer Size */
++#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
++
++#define CONFIG_SYS_MEMTEST_START 0x40000000 /* memtest works on */
++#define CONFIG_SYS_MEMTEST_END 0x44FFFFFF /* 256 MB in DRAM */
++
++#define CONFIG_SYS_LOAD_ADDR 0x43000000 /* default load address */
++
++#define CONFIG_SYS_TIMERBASE 0x1E782000 /* use timer 1 */
++#define CONFIG_SYS_HZ 1000
++#define CONFIG_ASPEED_TIMER_CLK (1*1000*1000) /* use external clk (1M) */
++
++/*
++ * Serial Configuration
++ */
++#define CONFIG_SYS_NS16550
++#define CONFIG_SYS_NS16550_SERIAL
++#define CONFIG_SYS_NS16550_MEM32
++#define CONFIG_SYS_NS16550_REG_SIZE -4
++#define CONFIG_SYS_NS16550_CLK 24000000
++#define CONFIG_SYS_NS16550_COM1 0x1e783000
++#define CONFIG_SYS_NS16550_COM2 0x1e784000
++#define CONFIG_SYS_NS16550_COM3 0x1e78e000
++#define CONFIG_SYS_LOADS_BAUD_CHANGE
++#define CONFIG_CONS_INDEX 2
++#define CONFIG_BAUDRATE 57600
++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++#define CONFIG_ASPEED_COM 0x1e784000 // COM2(UART5)
++#define CONFIG_ASPEED_COM_IER (CONFIG_ASPEED_COM + 0x4)
++#define CONFIG_ASPEED_COM_IIR (CONFIG_ASPEED_COM + 0x8)
++#define CONFIG_ASPEED_COM_LCR (CONFIG_ASPEED_COM + 0xc)
++
++/*
++ * USB device configuration
++ */
++/*
++#define CONFIG_USB_DEVICE 1
++#define CONFIG_USB_TTY 1
++
++#define CONFIG_USBD_VENDORID 0x1234
++#define CONFIG_USBD_PRODUCTID 0x5678
++#define CONFIG_USBD_MANUFACTURER "Siemens"
++#define CONFIG_USBD_PRODUCT_NAME "SX1"
++*/
++
++/*
++ * I2C configuration
++ */
++#define CONFIG_HARD_I2C
++#define CONFIG_SYS_I2C_SPEED 100000
++#define CONFIG_SYS_I2C_SLAVE 1
++#define CONFIG_DRIVER_ASPEED_I2C
++
++/*
++* EEPROM configuration
++*/
++#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
++#define CONFIG_SYS_I2C_EEPROM_ADDR 0xa0
++
++#define __BYTE_ORDER __LITTLE_ENDIAN
++#define __LITTLE_ENDIAN_BITFIELD
++
++/*
++ * NIC configuration
++ */
++#define CONFIG_ASPEEDNIC
++#define CONFIG_NET_MULTI
++#define CONFIG_MAC1_ENABLE
++//#define CONFIG_MAC1_PHY_LINK_INTERRUPT
++//#define CONFIG_MAC2_ENABLE
++//#define CONFIG_MAC2_PHY_LINK_INTERRUPT
++/*
++*-------------------------------------------------------------------------------
++* NOTICE: MAC1 and MAC2 now have their own seperate PHY configuration.
++* We use 2 bits for each MAC in the scratch register(D[15:11] in 0x1E6E2040) to
++* inform kernel driver.
++* The meanings of the 2 bits are:
++* 00(0): Dedicated PHY
++* 01(1): ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 10(2): ASPEED's MAC is connected to NC-SI PHY chip directly
++* 11: Reserved
++*
++* We use CONFIG_MAC1_PHY_SETTING and CONFIG_MAC2_PHY_SETTING in U-Boot
++* 0: Dedicated PHY
++* 1: ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 2: ASPEED's MAC is connected to NC-SI PHY chip directly
++* 3: Reserved
++*-------------------------------------------------------------------------------
++*/
++#define CONFIG_MAC1_PHY_SETTING 2
++#define CONFIG_MAC2_PHY_SETTING 0
++#define CONFIG_ASPEED_MAC_NUMBER 1
++#define CONFIG_ASPEED_MAC_CONFIG 1 // config MAC1
++#define _PHY_SETTING_CONCAT(mac) CONFIG_MAC##mac##_PHY_SETTING
++#define _GET_MAC_PHY_SETTING(mac) _PHY_SETTING_CONCAT(mac)
++#define CONFIG_ASPEED_MAC_PHY_SETTING \
++ _GET_MAC_PHY_SETTING(CONFIG_ASPEED_MAC_CONFIG)
++#define CONFIG_MAC_INTERFACE_CLOCK_DELAY 0x2255
++#define CONFIG_RANDOM_MACADDR
++//#define CONFIG_GATEWAYIP 192.168.0.1
++//#define CONFIG_NETMASK 255.255.255.0
++//#define CONFIG_IPADDR 192.168.0.45
++//#define CONFIG_SERVERIP 192.168.0.81
++
++/*
++ * SLT
++ */
++/*
++#define CONFIG_SLT
++#define CFG_CMD_SLT (CFG_CMD_VIDEOTEST | CFG_CMD_MACTEST | CFG_CMD_HACTEST | CFG_CMD_MICTEST)
++*/
++
++#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x1000 - GENERATED_GBL_DATA_SIZE)
++
++#define CONFIG_ASPEED_ENABLE_WATCHDOG
++#define CONFIG_ASPEED_WATCHDOG_TIMEOUT (5*60) // 5m
++
++#endif /* __CONFIG_H */
+diff --git a/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/include/configs/fbyosemite.h b/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/include/configs/fbyosemite.h
+new file mode 100644
+index 0000000..73a3cf9
+--- /dev/null
++++ b/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/include/configs/fbyosemite.h
+@@ -0,0 +1,353 @@
++/*
++ * Copyright 2015-present Facebook. All Rights Reserved.
++ *
++ * 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., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++/* Uncommit the following line to enable JTAG in u-boot */
++//#define CONFIG_ASPEED_ENABLE_JTAG
++
++/*
++ * High Level Configuration Options
++ * (easy to change)
++ */
++//#define CONFIG_INIT_CRITICAL /* define for U-BOOT 1.1.1 */
++#undef CONFIG_INIT_CRITICAL /* undef for U-BOOT 1.1.4 */
++//#define CONFIG_FPGA_ASPEED 1
++#define CONFIG_ARM926EJS 1 /* This is an arm926ejs CPU */
++#define CONFIG_ASPEED 1
++#define CONFIG_AST2400 1
++//#define CONFIG_AST1070 1
++//#define CONFIG_SYS_FLASH_CFI /* CONFIG_FLASH_CFI, CONFIG_FLASH_SPI is exclusive*/
++#define CONFIG_FLASH_SPI
++//#define CONFIG_2SPIFLASH /* Boot SPI: CS2, 2nd SPI: CS0 */
++#undef CONFIG_2SPIFLASH
++#undef CONFIG_ASPEED_SLT
++#define CONFIG_FLASH_AST2300
++//#define CONFIG_FLASH_AST2300_DMA
++//#define CONFIG_FLASH_SPIx2_Dummy
++//#define CONFIG_FLASH_SPIx4_Dummy
++#define CONFIG_CRT_DISPLAY 1 /* undef if not support CRT */
++
++//#define CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
++#define CONFIG_MISC_INIT_R
++
++#define CONFIG_YOSEMITE
++
++/*
++ * DRAM Config
++ *
++ * 1. DRAM Size //
++ * CONFIG_DRAM_512MBIT // 512M bit
++ * CONFIG_DRAM_1GBIT // 1G bit (default)
++ * CONFIG_DRAM_2GBIT // 2G bit
++ * CONFIG_DRAM_4GBIT // 4G bit
++ * 2. DRAM Speed //
++ * CONFIG_DRAM_336 // 336MHz (DDR-667)
++ * CONFIG_DRAM_408 // 408MHz (DDR-800) (default)
++ * 3. VGA Mode
++ * CONFIG_CRT_DISPLAY // define to disable VGA function
++ * 4. ECC Function enable
++ * CONFIG_DRAM_ECC // define to enable ECC function
++ * 5. UART Debug Message
++ * CONFIG_DRAM_UART_OUT // enable output message at UART5
++ * CONFIG_DRAM_UART_38400 // set the UART baud rate to 38400, default is 115200
++ */
++
++//1. DRAM Size
++//#define CONFIG_DRAM_512MBIT
++#define CONFIG_DRAM_1GBIT
++//#define CONFIG_DRAM_2GBIT
++//#define CONFIG_DRAM_4GBIT
++//2. DRAM Speed
++//#define CONFIG_DRAM_336
++#define CONFIG_DRAM_408
++//3. VGA Mode
++//#define CONFIG_CRT_DISPLAY
++//4. ECC Function enable
++//#define CONFIG_DRAM_ECC
++//5. UART Debug Message
++#define CONFIG_DRAM_UART_OUT
++//#define CONFIG_DRAM_UART_38400
++
++
++
++/*
++ * Environment Config
++ */
++#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
++#define CONFIG_SETUP_MEMORY_TAGS 1
++#define CONFIG_INITRD_TAG 1
++#define CONFIG_BOOTARGS "debug console=ttyS0,57600n8 root=/dev/ram rw"
++#define CONFIG_UPDATE "tftp 40800000 ast2400.scr; so 40800000'"
++
++#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
++#define CONFIG_AUTOBOOT_KEYED
++#define CONFIG_AUTOBOOT_PROMPT \
++ "autoboot in %d seconds (stop with 'Delete' key)...\n", bootdelay
++#define CONFIG_AUTOBOOT_STOP_STR "\x1b\x5b\x33\x7e" /* 'Delete', ESC[3~ */
++#define CONFIG_ZERO_BOOTDELAY_CHECK
++
++#ifdef CONFIG_FLASH_AST2300
++#define CONFIG_BOOTCOMMAND "bootm 20080000 20300000"
++#else
++#ifdef CONFIG_SYS_FLASH_CFI
++#define CONFIG_BOOTCOMMAND "bootm 10080000 10300000"
++#else
++#define CONFIG_BOOTCOMMAND "bootm 14080000 14300000"
++#endif
++#endif
++#define CONFIG_BOOTFILE "all.bin"
++#define CONFIG_ENV_OVERWRITE
++
++/*
++ * Command line configuration.
++ */
++#include <config_cmd_default.h>
++
++#define CONFIG_CMD_DFL
++#define CONFIG_CMD_ENV
++#define CONFIG_CMD_FLASH
++#define CONFIG_CMD_MII
++#define CONFIG_CMD_NET
++#define CONFIG_CMD_PING
++#define CONFIG_CMD_I2C
++#define CONFIG_CMD_EEPROM
++#define CONFIG_CMD_NETTEST
++#define CONFIG_CMD_SLT
++
++/*
++ * CPU Setting
++ */
++#define CPU_CLOCK_RATE 18000000 /* 16.5 MHz clock for the ARM core */
++
++/*
++ * Size of malloc() pool
++ */
++#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 768*1024)
++#define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
++
++/*
++ * Stack sizes, The stack sizes are set up in start.S using the settings below
++ */
++#define CONFIG_STACKSIZE (128*1024) /* regular stack */
++#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
++#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
++
++/*
++ * Memory Configuration
++ */
++#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
++#define PHYS_SDRAM_1 0x40000000 /* SDRAM Bank #1 */
++#define PHYS_SDRAM_1_SIZE 0x8000000 /* 128 MB */
++
++#define CONFIG_SYS_SDRAM_BASE 0x40000000
++
++/*
++ * FLASH Configuration
++ */
++#ifdef CONFIG_SYS_FLASH_CFI /* NOR Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x10000000 /* Flash Bank #1 */
++#endif
++
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (256) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x60000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
++
++#define CONFIG_SYS_FLASH_CFI_AMD_RESET
++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++
++#else /* SPI Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x14000000 /* Flash Bank #1 */
++#define PHYS_FLASH_2 0x14800000 /* Flash Bank #2 */
++#define PHYS_FLASH_2_BASE 0x10000000
++#endif
++
++#ifdef CONFIG_2SPIFLASH
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_2_BASE
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1, PHYS_FLASH_2 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 2
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#else
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x60000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
++#define CONFIG_ASPEED_WRITE_DEFAULT_ENV
++#endif
++
++#endif
++
++#define __LITTLE_ENDIAN 1
++
++#define CONFIG_MONITOR_BASE TEXT_BASE
++#define CONFIG_MONITOR_LEN (192 << 10)
++
++/* timeout values are in ticks */
++#define CONFIG_SYS_FLASH_ERASE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Erase */
++#define CONFIG_SYS_FLASH_WRITE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Write */
++
++/*
++ * Miscellaneous configurable options
++ */
++#define CONFIG_SYS_LONGHELP /* undef to save memory */
++
++#define CONFIG_SYS_PROMPT "boot# " /* Monitor Command Prompt */
++#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print Buffer Size */
++#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
++
++#define CONFIG_SYS_MEMTEST_START 0x40000000 /* memtest works on */
++#define CONFIG_SYS_MEMTEST_END 0x44FFFFFF /* 256 MB in DRAM */
++
++#define CONFIG_SYS_LOAD_ADDR 0x43000000 /* default load address */
++
++#define CONFIG_SYS_TIMERBASE 0x1E782000 /* use timer 1 */
++#define CONFIG_SYS_HZ 1000
++#define CONFIG_ASPEED_TIMER_CLK (1*1000*1000) /* use external clk (1M) */
++
++/*
++ * Serial Configuration
++ */
++#define CONFIG_SYS_NS16550
++#define CONFIG_SYS_NS16550_SERIAL
++#define CONFIG_SYS_NS16550_MEM32
++#define CONFIG_SYS_NS16550_REG_SIZE -4
++#define CONFIG_SYS_NS16550_CLK 24000000
++#define CONFIG_SYS_NS16550_COM1 0x1e783000
++#define CONFIG_SYS_NS16550_COM2 0x1e784000
++#define CONFIG_SYS_NS16550_COM3 0x1e78e000
++#define CONFIG_SYS_LOADS_BAUD_CHANGE
++#define CONFIG_CONS_INDEX 2
++#define CONFIG_BAUDRATE 57600
++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++#define CONFIG_ASPEED_COM 0x1e784000 // COM2(UART5)
++#define CONFIG_ASPEED_COM_IER (CONFIG_ASPEED_COM + 0x4)
++#define CONFIG_ASPEED_COM_IIR (CONFIG_ASPEED_COM + 0x8)
++#define CONFIG_ASPEED_COM_LCR (CONFIG_ASPEED_COM + 0xc)
++
++/*
++ * USB device configuration
++ */
++/*
++#define CONFIG_USB_DEVICE 1
++#define CONFIG_USB_TTY 1
++
++#define CONFIG_USBD_VENDORID 0x1234
++#define CONFIG_USBD_PRODUCTID 0x5678
++#define CONFIG_USBD_MANUFACTURER "Siemens"
++#define CONFIG_USBD_PRODUCT_NAME "SX1"
++*/
++
++/*
++ * I2C configuration
++ */
++#define CONFIG_HARD_I2C
++#define CONFIG_SYS_I2C_SPEED 100000
++#define CONFIG_SYS_I2C_SLAVE 1
++#define CONFIG_DRIVER_ASPEED_I2C
++
++/*
++* EEPROM configuration
++*/
++#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
++#define CONFIG_SYS_I2C_EEPROM_ADDR 0xa0
++
++#define __BYTE_ORDER __LITTLE_ENDIAN
++#define __LITTLE_ENDIAN_BITFIELD
++
++/*
++ * NIC configuration
++ */
++#define CONFIG_ASPEEDNIC
++#define CONFIG_NET_MULTI
++#define CONFIG_MAC1_ENABLE
++//#define CONFIG_MAC1_PHY_LINK_INTERRUPT
++//#define CONFIG_MAC2_ENABLE
++//#define CONFIG_MAC2_PHY_LINK_INTERRUPT
++/*
++*-------------------------------------------------------------------------------
++* NOTICE: MAC1 and MAC2 now have their own seperate PHY configuration.
++* We use 2 bits for each MAC in the scratch register(D[15:11] in 0x1E6E2040) to
++* inform kernel driver.
++* The meanings of the 2 bits are:
++* 00(0): Dedicated PHY
++* 01(1): ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 10(2): ASPEED's MAC is connected to NC-SI PHY chip directly
++* 11: Reserved
++*
++* We use CONFIG_MAC1_PHY_SETTING and CONFIG_MAC2_PHY_SETTING in U-Boot
++* 0: Dedicated PHY
++* 1: ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 2: ASPEED's MAC is connected to NC-SI PHY chip directly
++* 3: Reserved
++*-------------------------------------------------------------------------------
++*/
++#define CONFIG_MAC1_PHY_SETTING 2
++#define CONFIG_MAC2_PHY_SETTING 0
++#define CONFIG_ASPEED_MAC_NUMBER 1
++#define CONFIG_ASPEED_MAC_CONFIG 1 // config MAC1
++#define _PHY_SETTING_CONCAT(mac) CONFIG_MAC##mac##_PHY_SETTING
++#define _GET_MAC_PHY_SETTING(mac) _PHY_SETTING_CONCAT(mac)
++#define CONFIG_ASPEED_MAC_PHY_SETTING \
++ _GET_MAC_PHY_SETTING(CONFIG_ASPEED_MAC_CONFIG)
++#define CONFIG_MAC_INTERFACE_CLOCK_DELAY 0x2255
++#define CONFIG_RANDOM_MACADDR
++//#define CONFIG_GATEWAYIP 192.168.0.1
++//#define CONFIG_NETMASK 255.255.255.0
++//#define CONFIG_IPADDR 192.168.0.45
++//#define CONFIG_SERVERIP 192.168.0.81
++
++/*
++ * SLT
++ */
++/*
++#define CONFIG_SLT
++#define CFG_CMD_SLT (CFG_CMD_VIDEOTEST | CFG_CMD_MACTEST | CFG_CMD_HACTEST | CFG_CMD_MICTEST)
++*/
++
++#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x1000 - GENERATED_GBL_DATA_SIZE)
++
++#define CONFIG_ASPEED_ENABLE_WATCHDOG
++#define CONFIG_ASPEED_WATCHDOG_TIMEOUT (5*60) // 5m
++
++#endif /* __CONFIG_H */
+diff --git a/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/include/configs/wedge100.h b/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/include/configs/wedge100.h
+new file mode 100644
+index 0000000..1aa3260
+--- /dev/null
++++ b/meta-aspeed/recipes-bsp/u-boot/files/u-boot-v2013.07/include/configs/wedge100.h
+@@ -0,0 +1,354 @@
++/*
++ * Copyright 2004-present Facebook. All Rights Reserved.
++ *
++ * 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., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++/* Uncommit the following line to enable JTAG in u-boot */
++//#define CONFIG_ASPEED_ENABLE_JTAG
++
++/*
++ * High Level Configuration Options
++ * (easy to change)
++ */
++//#define CONFIG_INIT_CRITICAL /* define for U-BOOT 1.1.1 */
++#undef CONFIG_INIT_CRITICAL /* undef for U-BOOT 1.1.4 */
++//#define CONFIG_FPGA_ASPEED 1
++#define CONFIG_ARM926EJS 1 /* This is an arm926ejs CPU */
++#define CONFIG_ASPEED 1
++#define CONFIG_AST2400 1
++#define CONFIG_WEDGE100 1
++//#define CONFIG_AST1070 1
++//#define CONFIG_SYS_FLASH_CFI /* CONFIG_FLASH_CFI, CONFIG_FLASH_SPI is exclusive*/
++#define CONFIG_FLASH_SPI
++//#define CONFIG_2SPIFLASH /* Boot SPI: CS2, 2nd SPI: CS0 */
++#undef CONFIG_2SPIFLASH
++#undef CONFIG_ASPEED_SLT
++#define CONFIG_FLASH_AST2300
++//#define CONFIG_FLASH_AST2300_DMA
++//#define CONFIG_FLASH_SPIx2_Dummy
++//#define CONFIG_FLASH_SPIx4_Dummy
++#define CONFIG_CRT_DISPLAY 1 /* undef if not support CRT */
++
++//#define CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
++#define CONFIG_MISC_INIT_R
++
++/*
++ * DRAM Config
++ *
++ * 1. DRAM Size //
++ * CONFIG_DRAM_512MBIT // 512M bit
++ * CONFIG_DRAM_1GBIT // 1G bit (default)
++ * CONFIG_DRAM_2GBIT // 2G bit
++ * CONFIG_DRAM_4GBIT // 4G bit
++ * 2. DRAM Speed //
++ * CONFIG_DRAM_336 // 336MHz (DDR-667)
++ * CONFIG_DRAM_408 // 408MHz (DDR-800) (default)
++ * 3. VGA Mode
++ * CONFIG_CRT_DISPLAY // define to disable VGA function
++ * 4. ECC Function enable
++ * CONFIG_DRAM_ECC // define to enable ECC function
++ * 5. UART Debug Message
++ * CONFIG_DRAM_UART_OUT // enable output message at UART5
++ * CONFIG_DRAM_UART_38400 // set the UART baud rate to 38400, default is 115200
++ */
++
++//1. DRAM Size
++//#define CONFIG_DRAM_512MBIT
++#define CONFIG_DRAM_1GBIT
++//#define CONFIG_DRAM_2GBIT
++//#define CONFIG_DRAM_4GBIT
++//2. DRAM Speed
++//#define CONFIG_DRAM_336
++#define CONFIG_DRAM_408
++//3. VGA Mode
++//#define CONFIG_CRT_DISPLAY
++//4. ECC Function enable
++//#define CONFIG_DRAM_ECC
++//5. UART Debug Message
++#define CONFIG_DRAM_UART_OUT
++//#define CONFIG_DRAM_UART_38400
++
++
++
++/*
++ * Environment Config
++ */
++#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
++#define CONFIG_SETUP_MEMORY_TAGS 1
++#define CONFIG_INITRD_TAG 1
++#define CONFIG_BOOTARGS "debug console=ttyS2,9600n8 root=/dev/ram rw"
++#define CONFIG_UPDATE "tftp 40800000 ast2400.scr; so 40800000'"
++
++#define CONFIG_BOOTDELAY 3 /* autoboot after 3 seconds */
++#define CONFIG_AUTOBOOT_KEYED
++#define CONFIG_AUTOBOOT_PROMPT \
++ "autoboot in %d seconds (stop with 'Delete' key)...\n", bootdelay
++#define CONFIG_AUTOBOOT_STOP_STR "\x1b\x5b\x33\x7e" /* 'Delete', ESC[3~ */
++#define CONFIG_ZERO_BOOTDELAY_CHECK
++
++#ifdef CONFIG_FLASH_AST2300
++#define CONFIG_BOOTCOMMAND "bootm 20080000 20300000"
++#else
++#ifdef CONFIG_SYS_FLASH_CFI
++#define CONFIG_BOOTCOMMAND "bootm 10080000 10300000"
++#else
++#define CONFIG_BOOTCOMMAND "bootm 14080000 14300000"
++#endif
++#endif
++#define CONFIG_BOOTFILE "all.bin"
++#define CONFIG_ENV_OVERWRITE
++
++/*
++ * Command line configuration.
++ */
++#include <config_cmd_default.h>
++
++#define CONFIG_CMD_DFL
++#define CONFIG_CMD_ENV
++#define CONFIG_CMD_FLASH
++#define CONFIG_CMD_MII
++#define CONFIG_CMD_NET
++#define CONFIG_CMD_PING
++#define CONFIG_CMD_I2C
++#define CONFIG_CMD_EEPROM
++#define CONFIG_CMD_NETTEST
++#define CONFIG_CMD_SLT
++
++/*
++ * CPU Setting
++ */
++#define CPU_CLOCK_RATE 18000000 /* 16.5 MHz clock for the ARM core */
++
++/*
++ * Size of malloc() pool
++ */
++#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 768*1024)
++#define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
++
++/*
++ * Stack sizes, The stack sizes are set up in start.S using the settings below
++ */
++#define CONFIG_STACKSIZE (128*1024) /* regular stack */
++#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */
++#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
++
++/*
++ * Memory Configuration
++ */
++#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
++#define PHYS_SDRAM_1 0x40000000 /* SDRAM Bank #1 */
++#define PHYS_SDRAM_1_SIZE 0x10000000 /* 256 MB */
++
++#define CONFIG_SYS_SDRAM_BASE 0x40000000
++
++/*
++ * FLASH Configuration
++ */
++#ifdef CONFIG_SYS_FLASH_CFI /* NOR Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x10000000 /* Flash Bank #1 */
++#endif
++
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (256) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x60000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
++
++#define CONFIG_SYS_FLASH_CFI_AMD_RESET
++#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
++
++#else /* SPI Flash */
++
++#ifdef CONFIG_FLASH_AST2300
++#define PHYS_FLASH_1 0x20000000 /* Flash Bank #1 */
++#else
++#define PHYS_FLASH_1 0x14000000 /* Flash Bank #1 */
++#define PHYS_FLASH_2 0x14800000 /* Flash Bank #2 */
++#define PHYS_FLASH_2_BASE 0x10000000
++#endif
++
++#ifdef CONFIG_2SPIFLASH
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_2_BASE
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1, PHYS_FLASH_2 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 2
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x7F0000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x010000 /* Total Size of Environment Sector */
++#else
++#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
++#define CONFIG_FLASH_BANKS_LIST { PHYS_FLASH_1 }
++#define CONFIG_SYS_MAX_FLASH_BANKS 1
++#define CONFIG_SYS_MAX_FLASH_SECT (1024) /* max number of sectors on one chip */
++
++#define CONFIG_ENV_IS_IN_FLASH 1
++#define CONFIG_ENV_OFFSET 0x60000 /* environment starts here */
++#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
++#define CONFIG_ASPEED_WRITE_DEFAULT_ENV
++#endif
++
++#endif
++
++#define __LITTLE_ENDIAN 1
++
++#define CONFIG_MONITOR_BASE TEXT_BASE
++#define CONFIG_MONITOR_LEN (192 << 10)
++
++/* timeout values are in ticks */
++#define CONFIG_SYS_FLASH_ERASE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Erase */
++#define CONFIG_SYS_FLASH_WRITE_TOUT (20*CONFIG_SYS_HZ) /* Timeout for Flash Write */
++
++/*
++ * Miscellaneous configurable options
++ */
++#define CONFIG_SYS_LONGHELP /* undef to save memory */
++
++#define CONFIG_SYS_PROMPT "boot# " /* Monitor Command Prompt */
++#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
++#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print Buffer Size */
++#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
++#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
++
++#define CONFIG_SYS_MEMTEST_START 0x40000000 /* memtest works on */
++#define CONFIG_SYS_MEMTEST_END 0x44FFFFFF /* 256 MB in DRAM */
++
++#define CONFIG_SYS_LOAD_ADDR 0x43000000 /* default load address */
++
++#define CONFIG_SYS_TIMERBASE 0x1E782000 /* use timer 1 */
++#define CONFIG_SYS_HZ 1000
++#define CONFIG_ASPEED_TIMER_CLK (1*1000*1000) /* use external clk (1M) */
++
++/*
++ * Serial Configuration
++ */
++#define CONFIG_SYS_NS16550
++#define CONFIG_SYS_NS16550_SERIAL
++#define CONFIG_SYS_NS16550_MEM32
++#define CONFIG_SYS_NS16550_REG_SIZE -4
++#define CONFIG_SYS_NS16550_CLK 24000000
++#define CONFIG_SYS_NS16550_COM1 0x1e783000
++#define CONFIG_SYS_NS16550_COM2 0x1e784000
++#define CONFIG_SYS_NS16550_COM3 0x1e78e000
++#define CONFIG_SYS_LOADS_BAUD_CHANGE
++#define CONFIG_CONS_INDEX 3
++#define CONFIG_BAUDRATE 9600
++#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
++#define CONFIG_ASPEED_COM 0x1e78e000 // COM3
++#define CONFIG_ASPEED_COM_IER (CONFIG_ASPEED_COM + 0x4)
++#define CONFIG_ASPEED_COM_IIR (CONFIG_ASPEED_COM + 0x8)
++#define CONFIG_ASPEED_COM_LCR (CONFIG_ASPEED_COM + 0xc)
++
++/*
++ * USB device configuration
++ */
++/*
++#define CONFIG_USB_DEVICE 1
++#define CONFIG_USB_TTY 1
++
++#define CONFIG_USBD_VENDORID 0x1234
++#define CONFIG_USBD_PRODUCTID 0x5678
++#define CONFIG_USBD_MANUFACTURER "Siemens"
++#define CONFIG_USBD_PRODUCT_NAME "SX1"
++*/
++
++/*
++ * I2C configuration
++ */
++#define CONFIG_HARD_I2C
++#define CONFIG_SYS_I2C_SPEED 100000
++#define CONFIG_SYS_I2C_SLAVE 1
++#define CONFIG_DRIVER_ASPEED_I2C
++
++/*
++* EEPROM configuration
++*/
++#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
++#define CONFIG_SYS_I2C_EEPROM_ADDR 0xa0
++
++#define __BYTE_ORDER __LITTLE_ENDIAN
++#define __LITTLE_ENDIAN_BITFIELD
++
++/*
++ * NIC configuration
++ */
++#define CONFIG_ASPEEDNIC
++#define CONFIG_NET_MULTI
++#define CONFIG_MAC1_PHY_LINK_INTERRUPT
++#define CONFIG_MAC2_ENABLE
++#define CONFIG_MAC2_PHY_LINK_INTERRUPT
++/*
++*-------------------------------------------------------------------------------
++* NOTICE: MAC1 and MAC2 now have their own seperate PHY configuration.
++* We use 2 bits for each MAC in the scratch register(D[15:11] in 0x1E6E2040) to
++* inform kernel driver.
++* The meanings of the 2 bits are:
++* 00(0): Dedicated PHY
++* 01(1): ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 10(2): ASPEED's MAC is connected to NC-SI PHY chip directly
++* 11: Reserved
++*
++* We use CONFIG_MAC1_PHY_SETTING and CONFIG_MAC2_PHY_SETTING in U-Boot
++* 0: Dedicated PHY
++* 1: ASPEED's EVA + INTEL's NC-SI PHY chip EVA
++* 2: ASPEED's MAC is connected to NC-SI PHY chip directly
++* 3: Reserved
++*-------------------------------------------------------------------------------
++*/
++#define CONFIG_MAC1_PHY_SETTING 0
++#define CONFIG_MAC2_PHY_SETTING 0
++#define CONFIG_ASPEED_MAC_NUMBER 2
++#define CONFIG_ASPEED_MAC_CONFIG 2 // config MAC2
++#define _PHY_SETTING_CONCAT(mac) CONFIG_MAC##mac##_PHY_SETTING
++#define _GET_MAC_PHY_SETTING(mac) _PHY_SETTING_CONCAT(mac)
++#define CONFIG_ASPEED_MAC_PHY_SETTING \
++ _GET_MAC_PHY_SETTING(CONFIG_ASPEED_MAC_CONFIG)
++#define CONFIG_MAC_INTERFACE_CLOCK_DELAY 0x2255
++#define CONFIG_RANDOM_MACADDR
++//#define CONFIG_GATEWAYIP 192.168.0.1
++//#define CONFIG_NETMASK 255.255.255.0
++//#define CONFIG_IPADDR 192.168.0.45
++//#define CONFIG_SERVERIP 192.168.0.81
++
++/*
++ * SLT
++ */
++/*
++#define CONFIG_SLT
++#define CFG_CMD_SLT (CFG_CMD_VIDEOTEST | CFG_CMD_MACTEST | CFG_CMD_HACTEST | CFG_CMD_MICTEST)
++*/
++
++#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x1000 - GENERATED_GBL_DATA_SIZE)
++
++#define CONFIG_ASPEED_ENABLE_WATCHDOG
++#define CONFIG_ASPEED_WATCHDOG_TIMEOUT (5*60) // 5m
++#define CONFIG_ASPEED_ENABLE_DUAL_BOOT_WATCHDOG
++#define CONFIG_ASPEED_WATCHDOG_DUAL_BOOT_TIMEOUT \
++ (CONFIG_ASPEED_WATCHDOG_TIMEOUT - 5)
++
++#endif /* __CONFIG_H */
+--
+1.8.1
+
diff --git a/meta-aspeed/recipes-bsp/u-boot/u-boot-fw-utils_2013.07%.bbappend b/meta-aspeed/recipes-bsp/u-boot/u-boot-fw-utils_2013.07%.bbappend
index c93571b..ac75c33 100644
--- a/meta-aspeed/recipes-bsp/u-boot/u-boot-fw-utils_2013.07%.bbappend
+++ b/meta-aspeed/recipes-bsp/u-boot/u-boot-fw-utils_2013.07%.bbappend
@@ -2,4 +2,19 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
SRC_URI += "file://patch-2013.07/0000-u-boot-aspeed-064.patch \
file://patch-2013.07/0001-u-boot-openbmc.patch \
- "
+ file://patch-2013.07/0002-Create-snapshot-of-OpenBMC.patch \
+ "
+
+PV = "v2013.07"
+
+S = "${WORKDIR}/u-boot-v2013.07"
+
+# This is an ugly hack, but we want to get this out the door, rather than
+# spending forever fiddling with yocto and bitbake.
+
+do_install_append() {
+ if [ -e ${WORKDIR}/fw_env.config ] ; then
+ install -d ${D}${sysconfdir}
+ install -m 644 ${WORKDIR}/fw_env.config ${D}${sysconfdir}/fw_env.config
+ fi
+}
diff --git a/meta-aspeed/recipes-bsp/u-boot/u-boot_2013.07%.bbappend b/meta-aspeed/recipes-bsp/u-boot/u-boot_2013.07%.bbappend
index d4e347b..0ecbd77 100644
--- a/meta-aspeed/recipes-bsp/u-boot/u-boot_2013.07%.bbappend
+++ b/meta-aspeed/recipes-bsp/u-boot/u-boot_2013.07%.bbappend
@@ -1,12 +1,10 @@
FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
-SRC_URI += "file://fw_env.config \
- file://patch-2013.07/0000-u-boot-aspeed-064.patch \
+SRC_URI += "file://patch-2013.07/0000-u-boot-aspeed-064.patch \
file://patch-2013.07/0001-u-boot-openbmc.patch \
- "
+ file://patch-2013.07/0002-Create-snapshot-of-OpenBMC.patch \
+ "
-# Do not install u-boot in rootfs
-do_install[postfuncs] += "remove_uboot_from_rootfs"
-remove_uboot_from_rootfs() {
- rm -rf ${D}/boot/u-boot*
-}
+PV = "v2013.07"
+
+S = "${WORKDIR}/u-boot-v2013.07"
diff --git a/meta-aspeed/recipes-core/images/files/aspeed_device_table b/meta-aspeed/recipes-core/images/files/aspeed_device_table
index fac26b9..55dc7e0 100644
--- a/meta-aspeed/recipes-core/images/files/aspeed_device_table
+++ b/meta-aspeed/recipes-core/images/files/aspeed_device_table
@@ -35,7 +35,6 @@
/dev/urandom c 644 root root 1 9 - - -
/dev/watchdog c 660 root root 10 130 - - -
/dev/zero c 644 root root 1 5 - - -
-/dev/i2c- c 600 root root 89 0 0 1 10
-/dev/i2c- c 600 root root 89 11 11 1 2
+/dev/i2c- c 600 root root 89 0 0 1 13
/dev/net d 755 root root - - - - -
/dev/net/tun c 600 root root 10 200 - - -
diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0029-Create-snapshot-of-OpenBMC.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0029-Create-snapshot-of-OpenBMC.patch
new file mode 100644
index 0000000..a2705bf
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0029-Create-snapshot-of-OpenBMC.patch
@@ -0,0 +1,11455 @@
+From 19459c799ac0a521082d6d79e68ffc3decb18ea2 Mon Sep 17 00:00:00 2001
+From: Ori Bernstein <orib@fb.com>
+Date: Thu, 3 Sep 2015 11:28:27 -0700
+Subject: [PATCH] Create snapshot of OpenBMC
+
+---
+ .../arch/arm/configs/fbplatform1_defconfig | 1480 ++++++++++++++++++++
+ .../arch/arm/configs/wedge100_defconfig | 1462 +++++++++++++++++++
+ .../arch/arm/configs/wedge_defconfig | 1 +
+ .../arch/arm/configs/yosemite_defconfig | 1480 ++++++++++++++++++++
+ .../arch/arm/include/asm/ioctls.h | 1 +
+ .../arch/arm/mach-aspeed/Kconfig | 12 +
+ .../arch/arm/mach-aspeed/gpio.c | 2 +-
+ .../arm/mach-aspeed/include/mach/debug-macro.S | 4 +-
+ .../arch/arm/mach-aspeed/include/mach/platform.h | 17 +-
+ .../arch/arm/mach-aspeed/include/mach/uncompress.h | 6 +-
+ .../arch/arm/mach-aspeed/include/mach/vmalloc.h | 4 +-
+ .../arch/arm/plat-aspeed/ast-scu.c | 372 ++---
+ .../arch/arm/plat-aspeed/dev-eth.c | 35 +-
+ .../arch/arm/plat-aspeed/dev-i2c.c | 385 +++--
+ .../arch/arm/plat-aspeed/dev-spi.c | 27 +-
+ .../arch/arm/plat-aspeed/dev-uart.c | 50 +-
+ .../arch/arm/plat-aspeed/irq.c | 28 +-
+ .../linux-aspeed-2.6.28.9/drivers/hwmon/ast_adc.c | 233 +--
+ .../drivers/i2c/busses/i2c-ast.c | 689 +++++----
+ .../linux-aspeed-2.6.28.9/drivers/i2c/i2c-core.c | 15 +-
+ .../linux-aspeed-2.6.28.9/drivers/i2c/i2c-dev.c | 113 +-
+ .../drivers/net/ftgmac100_26.c | 1211 ++++++++++++++--
+ .../drivers/net/ftgmac100_26.h | 67 +-
+ .../linux-aspeed-2.6.28.9/drivers/rtc/rtc-aspeed.c | 42 +-
+ .../linux-aspeed-2.6.28.9/drivers/serial/8250.c | 39 +-
+ .../linux-aspeed-2.6.28.9/drivers/watchdog/Kconfig | 9 +-
+ .../drivers/watchdog/ast_wdt.c | 27 +
+ .../files/linux-aspeed-2.6.28.9/fs/compat_ioctl.c | 51 +-
+ .../linux-aspeed-2.6.28.9/include/linux/i2c-dev.h | 1 +
+ .../linux-aspeed-2.6.28.9/include/linux/i2c.h | 6 +
+ ...m25p80-Add-support-for-the-Winbond-W25Q64.patch | 29 +
+ ...t-leak-packets-when-a-netns-is-going-down.patch | 56 +
+ ...int-error-value-when-skb-allocation-fails.patch | 43 +
+ .../recipes-kernel/linux/linux-aspeed_2.6.28.9.bb | 17 +-
+ 34 files changed, 7064 insertions(+), 950 deletions(-)
+ create mode 100644 meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/configs/fbplatform1_defconfig
+ create mode 100644 meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/configs/wedge100_defconfig
+ create mode 100644 meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/configs/yosemite_defconfig
+ create mode 100644 meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0029-mtd-m25p80-Add-support-for-the-Winbond-W25Q64.patch
+ create mode 100644 meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0030-net-Don-t-leak-packets-when-a-netns-is-going-down.patch
+ create mode 100644 meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0031-IPv6-Print-error-value-when-skb-allocation-fails.patch
+
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/configs/fbplatform1_defconfig b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/configs/fbplatform1_defconfig
+new file mode 100644
+index 0000000..800d597
+--- /dev/null
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/configs/fbplatform1_defconfig
+@@ -0,0 +1,1480 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.28.9
++# Tue Feb 3 16:41:40 2015
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_KERNEL_GZIP=y
++# CONFIG_KERNEL_BZIP2 is not set
++# CONFIG_KERNEL_LZMA is not set
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++CONFIG_POSIX_MQUEUE=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++CONFIG_IKCONFIG=m
++CONFIG_IKCONFIG_PROC=y
++CONFIG_LOG_BUF_SHIFT=16
++# CONFIG_CGROUPS is not set
++# CONFIG_GROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++CONFIG_KALLSYMS_EXTRA_PASS=y
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++CONFIG_COMPAT_BRK=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++CONFIG_FREEZER=y
++
++#
++# System Type
++#
++CONFIG_ARCH_ASPEED=y
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_LOKI is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM is not set
++CONFIG_IRMP=y
++# CONFIG_PCEXT is not set
++# CONFIG_REMOTEFX is not set
++# CONFIG_ARCH_AST1100 is not set
++# CONFIG_ARCH_AST2100 is not set
++# CONFIG_ARCH_AST2200 is not set
++# CONFIG_ARCH_AST2300 is not set
++CONFIG_ARCH_AST2400=y
++CONFIG_FBPLATFORM1=y
++# CONFIG_ARCH_AST2500 is not set
++
++#
++# FLASH Chip Select
++#
++# CONFIG_AST_CS0_NOR is not set
++# CONFIG_AST_CS0_NAND is not set
++CONFIG_AST_CS0_SPI=y
++# CONFIG_AST_CS0_NONE is not set
++# CONFIG_AST_CS1_NOR is not set
++# CONFIG_AST_CS1_NAND is not set
++# CONFIG_AST_CS1_SPI is not set
++CONFIG_AST_CS1_NONE=y
++# CONFIG_AST_CS2_NOR is not set
++# CONFIG_AST_CS2_NAND is not set
++# CONFIG_AST_CS2_SPI is not set
++CONFIG_AST_CS2_NONE=y
++# CONFIG_AST_CS3_NOR is not set
++# CONFIG_AST_CS3_NAND is not set
++# CONFIG_AST_CS3_SPI is not set
++CONFIG_AST_CS3_NONE=y
++# CONFIG_AST_CS4_NOR is not set
++# CONFIG_AST_CS4_NAND is not set
++# CONFIG_AST_CS4_SPI is not set
++CONFIG_AST_CS4_NONE=y
++# CONFIG_ARCH_AST1070 is not set
++# CONFIG_AST_SCU_LOCK is not set
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++CONFIG_PLAT_ASPEED=y
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_PABRT_NOIFAR=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++# CONFIG_OUTER_CACHE is not set
++
++#
++# Bus support
++#
++CONFIG_ARM_AMBA=y
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_TICK_ONESHOT=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++CONFIG_ARCH_FLATMEM_HAS_HOLES=y
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++CONFIG_UNEVICTABLE_LRU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++CONFIG_CMDLINE=""
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Power Management
++#
++# CONFIG_CPU_IDLE is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++CONFIG_FPE_NWFPE_XP=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_VFP=y
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_HAVE_AOUT=y
++CONFIG_BINFMT_AOUT=y
++# CONFIG_BINFMT_MISC is not set
++
++#
++# Power management options
++#
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++CONFIG_PM_SLEEP=y
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++# CONFIG_APM_EMULATION is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++CONFIG_INET_TUNNEL=m
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++CONFIG_IPV6=m
++# CONFIG_IPV6_PRIVACY is not set
++# CONFIG_IPV6_ROUTER_PREF is not set
++# CONFIG_IPV6_OPTIMISTIC_DAD is not set
++# CONFIG_INET6_AH is not set
++# CONFIG_INET6_ESP is not set
++# CONFIG_INET6_IPCOMP is not set
++# CONFIG_IPV6_MIP6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++CONFIG_INET6_XFRM_MODE_TRANSPORT=m
++CONFIG_INET6_XFRM_MODE_TUNNEL=m
++CONFIG_INET6_XFRM_MODE_BEET=m
++# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
++CONFIG_IPV6_SIT=m
++CONFIG_IPV6_NDISC_NODETYPE=y
++# CONFIG_IPV6_TUNNEL is not set
++# CONFIG_IPV6_MULTIPLE_TABLES is not set
++# CONFIG_IPV6_MROUTE is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA is not set
++CONFIG_VLAN_8021Q=m
++# CONFIG_VLAN_8021Q_GVRP is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++CONFIG_WAN_ROUTER=y
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++# CONFIG_PHONET is not set
++# CONFIG_WIRELESS is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
++# CONFIG_SYS_HYPERVISOR is not set
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_CONCAT=y
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
++# CONFIG_MTD_AR7_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++CONFIG_MTD_DATAFLASH=m
++CONFIG_MTD_DATAFLASH_WRITE_VERIFY=y
++# CONFIG_MTD_DATAFLASH_OTP is not set
++CONFIG_MTD_M25P80=y
++CONFIG_M25PXX_USE_FAST_READ=y
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++CONFIG_BLK_DEV_NBD=y
++# CONFIG_BLK_DEV_UB is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=16384
++# CONFIG_BLK_DEV_XIP is not set
++# CONFIG_RD_BZIP2 is not set
++CONFIG_RD_LZMA=y
++CONFIG_RD_GZIP=y
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ICS932S401 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_C2PORT is not set
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++CONFIG_SCSI_TGT=y
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++CONFIG_SCSI_SCAN_ASYNC=y
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++CONFIG_SCSI_ISCSI_ATTRS=m
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++# CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++CONFIG_BONDING=m
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++CONFIG_TUN=m
++# CONFIG_VETH is not set
++# CONFIG_NET_ETHERNET is not set
++CONFIG_NETDEV_1000=y
++CONFIG_ASPEEDMAC=y
++# CONFIG_NETDEV_10000 is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++# CONFIG_IWLWIFI_LEDS is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_GPIO is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++CONFIG_MOUSE_PS2_ALPS=y
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++CONFIG_MOUSE_PS2_LIFEBOOK=y
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_ELANTECH is not set
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++CONFIG_MOUSE_SERIAL=y
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_BCM5974 is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_AMBAKMI is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++CONFIG_DEVKMEM=y
++CONFIG_SERIAL_NONSTANDARD=y
++# CONFIG_N_HDLC is not set
++# CONFIG_RISCOM8 is not set
++# CONFIG_SPECIALIX is not set
++# CONFIG_RIO is not set
++# CONFIG_STALDRV is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_NR_UARTS=5
++CONFIG_SERIAL_8250_RUNTIME_UARTS=5
++# CONFIG_SERIAL_AST_DMA_UART is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_AMBA_PL010 is not set
++# CONFIG_SERIAL_AMBA_PL011 is not set
++# CONFIG_SERIAL_AST is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_AST_MISC=y
++# CONFIG_AST_VIDEO is not set
++# CONFIG_ADC_CAT9883 is not set
++# CONFIG_AST_SPI_BIOS is not set
++CONFIG_AST_PECI=y
++# CONFIG_AST_KCS is not set
++# CONFIG_AST_GPIO is not set
++# CONFIG_HW_RANDOM is not set
++CONFIG_NVRAM=y
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_HELPER_AUTO=y
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++# CONFIG_I2C_GPIO is not set
++# CONFIG_I2C_OCORES is not set
++CONFIG_I2C_AST=y
++CONFIG_AST_I2C_SLAVE_MODE=y
++# CONFIG_AST_I2C_SLAVE_EEPROM is not set
++CONFIG_AST_I2C_SLAVE_RDWR=y
++# CONFIG_I2C_SIMTEC is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_STUB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_DS1682 is not set
++CONFIG_AT24=m
++# CONFIG_SENSORS_EEPROM is not set
++CONFIG_SENSORS_PCF8574=m
++# CONFIG_PCF8575 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
++
++#
++# SPI Master Controller Drivers
++#
++CONFIG_SPI_AST=y
++CONFIG_SPI_FMC=y
++CONFIG_SPI_BITBANG=y
++
++#
++# SPI Protocol Masters
++#
++CONFIG_SPI_AT25=m
++# CONFIG_SPI_SPIDEV is not set
++# CONFIG_SPI_TLE62X0 is not set
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIOLIB=y
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO expanders:
++#
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX732X is not set
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_AD7414 is not set
++# CONFIG_SENSORS_AD7418 is not set
++# CONFIG_SENSORS_ADCXX is not set
++# CONFIG_SENSORS_ADM1021 is not set
++# CONFIG_SENSORS_ADM1025 is not set
++# CONFIG_SENSORS_ADM1026 is not set
++# CONFIG_SENSORS_ADM1029 is not set
++# CONFIG_SENSORS_ADM1031 is not set
++# CONFIG_SENSORS_ADM9240 is not set
++# CONFIG_SENSORS_ADT7462 is not set
++# CONFIG_SENSORS_ADT7470 is not set
++# CONFIG_SENSORS_ADT7473 is not set
++# CONFIG_SENSORS_ATXP1 is not set
++# CONFIG_SENSORS_DS1621 is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_F75375S is not set
++# CONFIG_SENSORS_GL518SM is not set
++# CONFIG_SENSORS_GL520SM is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_LM63 is not set
++# CONFIG_SENSORS_LM70 is not set
++CONFIG_SENSORS_LM75=m
++# CONFIG_SENSORS_LM77 is not set
++# CONFIG_SENSORS_LM78 is not set
++# CONFIG_SENSORS_LM80 is not set
++# CONFIG_SENSORS_LM83 is not set
++# CONFIG_SENSORS_LM85 is not set
++# CONFIG_SENSORS_LM87 is not set
++# CONFIG_SENSORS_LM90 is not set
++# CONFIG_SENSORS_LM92 is not set
++# CONFIG_SENSORS_LM93 is not set
++CONFIG_SENSORS_MAX127=m
++# CONFIG_SENSORS_MAX1111 is not set
++# CONFIG_SENSORS_MAX1619 is not set
++# CONFIG_SENSORS_MAX6650 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_DME1737 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47M192 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++CONFIG_SENSORS_ADS7828=m
++# CONFIG_SENSORS_THMC50 is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_SENSORS_W83781D is not set
++# CONFIG_SENSORS_W83791D is not set
++# CONFIG_SENSORS_W83792D is not set
++# CONFIG_SENSORS_W83793 is not set
++# CONFIG_SENSORS_W83L785TS is not set
++# CONFIG_SENSORS_W83L786NG is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++CONFIG_SENSORS_AST_ADC=y
++CONFIG_SENSORS_AST_PWM_FAN=y
++# CONFIG_SENSORS_FB_PANTHER_PLUS is not set
++CONFIG_PMBUS=m
++CONFIG_SENSORS_PMBUS=m
++CONFIG_SENSORS_ADM1275=m
++# CONFIG_SENSORS_LM25066 is not set
++# CONFIG_SENSORS_LTC2978 is not set
++# CONFIG_SENSORS_MAX16064 is not set
++# CONFIG_SENSORS_MAX34440 is not set
++# CONFIG_SENSORS_MAX8688 is not set
++CONFIG_SENSORS_PFE1100=m
++CONFIG_SENSORS_PFE3000=m
++# CONFIG_SENSORS_UCD9000 is not set
++# CONFIG_SENSORS_UCD9200 is not set
++# CONFIG_SENSORS_ZL6100 is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++CONFIG_THERMAL=y
++CONFIG_THERMAL_HWMON=y
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++
++#
++# Watchdog Device Drivers
++#
++# CONFIG_SOFT_WATCHDOG is not set
++CONFIG_AST_WATCHDOG=y
++
++#
++# USB-based Watchdog Cards
++#
++# CONFIG_USBPCWATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM8350_I2C is not set
++
++#
++# Multimedia devices
++#
++
++#
++# Multimedia core support
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_VIDEO_MEDIA is not set
++
++#
++# Multimedia drivers
++#
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_SOUND is not set
++# CONFIG_HID_SUPPORT is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++# CONFIG_USB_ARCH_HAS_OHCI is not set
++CONFIG_USB_ARCH_HAS_EHCI=y
++CONFIG_USB=m
++# CONFIG_USB_DEBUG is not set
++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_SUSPEND is not set
++# CONFIG_USB_OTG is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB is not set
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++# CONFIG_USB_EHCI_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_HWA_HCD is not set
++
++#
++# AST USB Drivers
++#
++CONFIG_AST_USB_UHCI_HCD=y
++# CONFIG_AST_USB_UHCI_MULTIPORT_1 is not set
++# CONFIG_AST_USB_UHCI_MULTIPORT_2 is not set
++CONFIG_AST_USB_UHCI_MULTIPORT_4=y
++# CONFIG_USB_EHCI_SPLIT_ISO is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
++#
++
++#
++# see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=m
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_SEVSEG is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_VST is not set
++CONFIG_USB_GADGET=y
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_VBUS_DRAW=2
++CONFIG_USB_GADGET_SELECTED=y
++# CONFIG_USB_GADGET_AT91 is not set
++# CONFIG_USB_GADGET_ATMEL_USBA is not set
++# CONFIG_USB_GADGET_FSL_USB2 is not set
++# CONFIG_USB_GADGET_LH7A40X is not set
++# CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_PXA25X is not set
++# CONFIG_USB_GADGET_PXA27X is not set
++# CONFIG_USB_GADGET_S3C2410 is not set
++# CONFIG_USB_GADGET_M66592 is not set
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_FSL_QE is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_GOKU is not set
++CONFIG_USB_GADGET_ASPEED_AST=y
++CONFIG_USB_ASPEED_AST=y
++# CONFIG_USB_GADGET_DUMMY_HCD is not set
++CONFIG_USB_GADGET_DUALSPEED=y
++CONFIG_USB_ZERO=m
++CONFIG_USB_ETH=m
++CONFIG_USB_ETH_RNDIS=y
++CONFIG_USB_GADGETFS=m
++CONFIG_USB_FILE_STORAGE=m
++# CONFIG_USB_FILE_STORAGE_TEST is not set
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++CONFIG_USB_CDC_COMPOSITE=m
++# CONFIG_MMC is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++# CONFIG_RTC_HCTOSYS is not set
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++# CONFIG_RTC_DRV_DS1307 is not set
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_S35390A is not set
++# CONFIG_RTC_DRV_FM3130 is not set
++# CONFIG_RTC_DRV_RX8581 is not set
++
++#
++# SPI RTC drivers
++#
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
++# CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_PL030 is not set
++# CONFIG_RTC_DRV_PL031 is not set
++CONFIG_RTC_DRV_ASPEED=y
++# CONFIG_DMADEVICES is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++CONFIG_EXT2_FS_XATTR=y
++CONFIG_EXT2_FS_POSIX_ACL=y
++CONFIG_EXT2_FS_SECURITY=y
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4_FS is not set
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_FILE_LOCKING=y
++# CONFIG_XFS_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++CONFIG_GENERIC_ACL=y
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=y
++# CONFIG_NTFS_DEBUG is not set
++CONFIG_NTFS_RW=y
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=m
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_YAFFS_FS=y
++CONFIG_YAFFS_YAFFS1=y
++# CONFIG_YAFFS_9BYTE_TAGS is not set
++# CONFIG_YAFFS_DOES_ECC is not set
++CONFIG_YAFFS_YAFFS2=y
++CONFIG_YAFFS_AUTO_YAFFS2=y
++# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set
++# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
++# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
++# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
++CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
++# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
++# CONFIG_JFFS2_SUMMARY is not set
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_NFS_V4 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_REGISTER_V4 is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf8"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++CONFIG_NLS_CODEPAGE_936=y
++CONFIG_NLS_CODEPAGE_950=y
++CONFIG_NLS_CODEPAGE_932=y
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++# CONFIG_ENABLE_WARN_DEPRECATED is not set
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_MEMORY_INIT=y
++CONFIG_FRAME_POINTER=y
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_LATENCYTOP is not set
++# CONFIG_SYSCTL_SYSCALL_CHECK is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++
++#
++# Tracers
++#
++# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_DEBUG_USER is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++# CONFIG_CRYPTO_FIPS is not set
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD=m
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_NULL=y
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_AUTHENC=m
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++# CONFIG_CRYPTO_ECB is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++CONFIG_CRYPTO_HMAC=y
++# CONFIG_CRYPTO_XCBC is not set
++
++#
++# Digest
++#
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++CONFIG_CRYPTO_SHA1=y
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++CONFIG_CRYPTO_DEFLATE=m
++# CONFIG_CRYPTO_LZO is not set
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++# CONFIG_CRYPTO_HW is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_T10DIF is not set
++CONFIG_CRC_ITU_T=m
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++
++
++# GUC USB Drivers
++#
++CONFIG_GUC_USB_UHCI_HCD=m
++# CONFIG_GUC_USB_UHCI_MULTIPORT_1 is not set
++# CONFIG_GUC_USB_UHCI_MULTIPORT_2 is not set
++CONFIG_GUC_USB_UHCI_MULTIPORT_4=y
++# CONFIG_USB_GADGET_MUSB_HDRC is not set
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/configs/wedge100_defconfig b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/configs/wedge100_defconfig
+new file mode 100644
+index 0000000..0f9f0f7
+--- /dev/null
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/configs/wedge100_defconfig
+@@ -0,0 +1,1462 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.28.9
++# Wed Aug 5 18:43:53 2015
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_KERNEL_GZIP=y
++# CONFIG_KERNEL_BZIP2 is not set
++# CONFIG_KERNEL_LZMA is not set
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++CONFIG_IKCONFIG=m
++CONFIG_IKCONFIG_PROC=y
++CONFIG_LOG_BUF_SHIFT=16
++# CONFIG_CGROUPS is not set
++# CONFIG_GROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++CONFIG_KALLSYMS_EXTRA_PASS=y
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++CONFIG_COMPAT_BRK=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++CONFIG_FREEZER=y
++
++#
++# System Type
++#
++CONFIG_ARCH_ASPEED=y
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_LOKI is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM is not set
++CONFIG_IRMP=y
++# CONFIG_PCEXT is not set
++# CONFIG_REMOTEFX is not set
++# CONFIG_ARCH_AST1100 is not set
++# CONFIG_ARCH_AST2100 is not set
++# CONFIG_ARCH_AST2200 is not set
++# CONFIG_ARCH_AST2300 is not set
++CONFIG_ARCH_AST2400=y
++# CONFIG_ARCH_AST2500 is not set
++
++#
++# FLASH Chip Select
++#
++# CONFIG_AST_CS0_NOR is not set
++# CONFIG_AST_CS0_NAND is not set
++CONFIG_AST_CS0_SPI=y
++# CONFIG_AST_CS0_NONE is not set
++# CONFIG_AST_CS1_NOR is not set
++# CONFIG_AST_CS1_NAND is not set
++# CONFIG_AST_CS1_SPI is not set
++CONFIG_AST_CS1_NONE=y
++# CONFIG_AST_CS2_NOR is not set
++# CONFIG_AST_CS2_NAND is not set
++# CONFIG_AST_CS2_SPI is not set
++CONFIG_AST_CS2_NONE=y
++# CONFIG_AST_CS3_NOR is not set
++# CONFIG_AST_CS3_NAND is not set
++# CONFIG_AST_CS3_SPI is not set
++CONFIG_AST_CS3_NONE=y
++# CONFIG_AST_CS4_NOR is not set
++# CONFIG_AST_CS4_NAND is not set
++# CONFIG_AST_CS4_SPI is not set
++CONFIG_AST_CS4_NONE=y
++# CONFIG_ARCH_AST1070 is not set
++# CONFIG_AST_SCU_LOCK is not set
++# CONFIG_WEDGE is not set
++CONFIG_WEDGE100=y
++# CONFIG_YOSEMITE is not set
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++CONFIG_PLAT_ASPEED=y
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_PABRT_NOIFAR=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++# CONFIG_OUTER_CACHE is not set
++
++#
++# Bus support
++#
++CONFIG_ARM_AMBA=y
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_TICK_ONESHOT=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++CONFIG_ARCH_FLATMEM_HAS_HOLES=y
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++CONFIG_UNEVICTABLE_LRU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++CONFIG_CMDLINE=""
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Power Management
++#
++# CONFIG_CPU_IDLE is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++CONFIG_FPE_NWFPE_XP=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_VFP=y
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_HAVE_AOUT=y
++CONFIG_BINFMT_AOUT=y
++# CONFIG_BINFMT_MISC is not set
++
++#
++# Power management options
++#
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++CONFIG_PM_SLEEP=y
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++# CONFIG_APM_EMULATION is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++CONFIG_INET_TUNNEL=m
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++CONFIG_IPV6=m
++# CONFIG_IPV6_PRIVACY is not set
++# CONFIG_IPV6_ROUTER_PREF is not set
++# CONFIG_IPV6_OPTIMISTIC_DAD is not set
++# CONFIG_INET6_AH is not set
++# CONFIG_INET6_ESP is not set
++# CONFIG_INET6_IPCOMP is not set
++# CONFIG_IPV6_MIP6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++CONFIG_INET6_XFRM_MODE_TRANSPORT=m
++CONFIG_INET6_XFRM_MODE_TUNNEL=m
++CONFIG_INET6_XFRM_MODE_BEET=m
++# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
++CONFIG_IPV6_SIT=m
++CONFIG_IPV6_NDISC_NODETYPE=y
++# CONFIG_IPV6_TUNNEL is not set
++# CONFIG_IPV6_MULTIPLE_TABLES is not set
++# CONFIG_IPV6_MROUTE is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA is not set
++CONFIG_VLAN_8021Q=m
++# CONFIG_VLAN_8021Q_GVRP is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++CONFIG_WAN_ROUTER=y
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++# CONFIG_PHONET is not set
++# CONFIG_WIRELESS is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
++# CONFIG_SYS_HYPERVISOR is not set
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_CONCAT=y
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
++# CONFIG_MTD_AR7_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++CONFIG_MTD_DATAFLASH=m
++CONFIG_MTD_DATAFLASH_WRITE_VERIFY=y
++# CONFIG_MTD_DATAFLASH_OTP is not set
++CONFIG_MTD_M25P80=y
++CONFIG_M25PXX_USE_FAST_READ=y
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++CONFIG_BLK_DEV_NBD=y
++# CONFIG_BLK_DEV_UB is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=16384
++# CONFIG_BLK_DEV_XIP is not set
++# CONFIG_RD_BZIP2 is not set
++CONFIG_RD_LZMA=y
++CONFIG_RD_GZIP=y
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ICS932S401 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_C2PORT is not set
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++CONFIG_SCSI_TGT=y
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++CONFIG_SCSI_SCAN_ASYNC=y
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++CONFIG_SCSI_ISCSI_ATTRS=m
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++# CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++CONFIG_BONDING=m
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++CONFIG_TUN=m
++# CONFIG_VETH is not set
++# CONFIG_NET_ETHERNET is not set
++CONFIG_NETDEV_1000=y
++CONFIG_ASPEEDMAC=y
++# CONFIG_NETDEV_10000 is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++# CONFIG_IWLWIFI_LEDS is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_GPIO is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++CONFIG_MOUSE_PS2_ALPS=y
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++CONFIG_MOUSE_PS2_LIFEBOOK=y
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_ELANTECH is not set
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++CONFIG_MOUSE_SERIAL=y
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_BCM5974 is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_AMBAKMI is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++CONFIG_DEVKMEM=y
++CONFIG_SERIAL_NONSTANDARD=y
++# CONFIG_N_HDLC is not set
++# CONFIG_RISCOM8 is not set
++# CONFIG_SPECIALIX is not set
++# CONFIG_RIO is not set
++# CONFIG_STALDRV is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_NR_UARTS=4
++CONFIG_SERIAL_8250_RUNTIME_UARTS=4
++# CONFIG_SERIAL_AST_DMA_UART is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_AMBA_PL010 is not set
++# CONFIG_SERIAL_AMBA_PL011 is not set
++# CONFIG_SERIAL_AST is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_AST_MISC=y
++# CONFIG_AST_VIDEO is not set
++# CONFIG_ADC_CAT9883 is not set
++# CONFIG_AST_SPI_BIOS is not set
++CONFIG_AST_PECI=y
++# CONFIG_AST_KCS is not set
++# CONFIG_AST_GPIO is not set
++# CONFIG_HW_RANDOM is not set
++CONFIG_NVRAM=y
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_HELPER_AUTO=y
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++# CONFIG_I2C_GPIO is not set
++# CONFIG_I2C_OCORES is not set
++CONFIG_I2C_AST=y
++CONFIG_AST_I2C_SLAVE_MODE=y
++CONFIG_AST_I2C_SLAVE_EEPROM=y
++# CONFIG_AST_I2C_SLAVE_RDWR is not set
++# CONFIG_I2C_SIMTEC is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_STUB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_DS1682 is not set
++CONFIG_AT24=m
++# CONFIG_SENSORS_EEPROM is not set
++CONFIG_SENSORS_PCF8574=m
++# CONFIG_PCF8575 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
++
++#
++# SPI Master Controller Drivers
++#
++CONFIG_SPI_AST=y
++CONFIG_SPI_FMC=y
++CONFIG_SPI_BITBANG=y
++
++#
++# SPI Protocol Masters
++#
++CONFIG_SPI_AT25=m
++CONFIG_SPI_SPIDEV=m
++# CONFIG_SPI_TLE62X0 is not set
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIOLIB=y
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO expanders:
++#
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX732X is not set
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_AD7414 is not set
++# CONFIG_SENSORS_AD7418 is not set
++# CONFIG_SENSORS_ADCXX is not set
++# CONFIG_SENSORS_ADM1021 is not set
++# CONFIG_SENSORS_ADM1025 is not set
++# CONFIG_SENSORS_ADM1026 is not set
++# CONFIG_SENSORS_ADM1029 is not set
++# CONFIG_SENSORS_ADM1031 is not set
++# CONFIG_SENSORS_ADM9240 is not set
++# CONFIG_SENSORS_ADT7462 is not set
++# CONFIG_SENSORS_ADT7470 is not set
++# CONFIG_SENSORS_ADT7473 is not set
++# CONFIG_SENSORS_ATXP1 is not set
++# CONFIG_SENSORS_DS1621 is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_F75375S is not set
++# CONFIG_SENSORS_GL518SM is not set
++# CONFIG_SENSORS_GL520SM is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_LM63 is not set
++# CONFIG_SENSORS_LM70 is not set
++CONFIG_SENSORS_LM75=m
++# CONFIG_SENSORS_LM77 is not set
++# CONFIG_SENSORS_LM78 is not set
++# CONFIG_SENSORS_LM80 is not set
++# CONFIG_SENSORS_LM83 is not set
++# CONFIG_SENSORS_LM85 is not set
++# CONFIG_SENSORS_LM87 is not set
++# CONFIG_SENSORS_LM90 is not set
++# CONFIG_SENSORS_LM92 is not set
++# CONFIG_SENSORS_LM93 is not set
++CONFIG_SENSORS_MAX127=m
++# CONFIG_SENSORS_MAX1111 is not set
++# CONFIG_SENSORS_MAX1619 is not set
++# CONFIG_SENSORS_MAX6650 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_DME1737 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47M192 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++CONFIG_SENSORS_ADS7828=m
++# CONFIG_SENSORS_THMC50 is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_SENSORS_W83781D is not set
++# CONFIG_SENSORS_W83791D is not set
++# CONFIG_SENSORS_W83792D is not set
++# CONFIG_SENSORS_W83793 is not set
++# CONFIG_SENSORS_W83L785TS is not set
++# CONFIG_SENSORS_W83L786NG is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++CONFIG_SENSORS_AST_ADC=m
++# CONFIG_SENSORS_AST_PWM_FAN is not set
++CONFIG_SENSORS_FB_PANTHER_PLUS=m
++CONFIG_PMBUS=m
++CONFIG_SENSORS_PMBUS=m
++CONFIG_SENSORS_ADM1275=m
++# CONFIG_SENSORS_LM25066 is not set
++# CONFIG_SENSORS_LTC2978 is not set
++# CONFIG_SENSORS_MAX16064 is not set
++# CONFIG_SENSORS_MAX34440 is not set
++# CONFIG_SENSORS_MAX8688 is not set
++CONFIG_SENSORS_PFE1100=m
++CONFIG_SENSORS_PFE3000=m
++# CONFIG_SENSORS_UCD9000 is not set
++# CONFIG_SENSORS_UCD9200 is not set
++# CONFIG_SENSORS_ZL6100 is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++CONFIG_THERMAL=y
++CONFIG_THERMAL_HWMON=y
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++
++#
++# Watchdog Device Drivers
++#
++# CONFIG_SOFT_WATCHDOG is not set
++CONFIG_AST_WATCHDOG=y
++CONFIG_AST_WATCHDOG_REARM_DUAL_BOOT=y
++
++#
++# USB-based Watchdog Cards
++#
++# CONFIG_USBPCWATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM8350_I2C is not set
++
++#
++# Multimedia devices
++#
++
++#
++# Multimedia core support
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_VIDEO_MEDIA is not set
++
++#
++# Multimedia drivers
++#
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_SOUND is not set
++# CONFIG_HID_SUPPORT is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++# CONFIG_USB_ARCH_HAS_OHCI is not set
++CONFIG_USB_ARCH_HAS_EHCI=y
++CONFIG_USB=m
++# CONFIG_USB_DEBUG is not set
++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_SUSPEND is not set
++# CONFIG_USB_OTG is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB is not set
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++# CONFIG_USB_EHCI_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_HWA_HCD is not set
++
++#
++# AST USB Drivers
++#
++CONFIG_AST_USB_UHCI_HCD=m
++# CONFIG_AST_USB_UHCI_MULTIPORT_1 is not set
++# CONFIG_AST_USB_UHCI_MULTIPORT_2 is not set
++CONFIG_AST_USB_UHCI_MULTIPORT_4=y
++# CONFIG_USB_GADGET_MUSB_HDRC is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
++#
++
++#
++# see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=m
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_SEVSEG is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_VST is not set
++CONFIG_USB_GADGET=y
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_VBUS_DRAW=2
++CONFIG_USB_GADGET_SELECTED=y
++# CONFIG_USB_GADGET_AT91 is not set
++# CONFIG_USB_GADGET_ATMEL_USBA is not set
++# CONFIG_USB_GADGET_FSL_USB2 is not set
++# CONFIG_USB_GADGET_LH7A40X is not set
++# CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_PXA25X is not set
++# CONFIG_USB_GADGET_PXA27X is not set
++# CONFIG_USB_GADGET_S3C2410 is not set
++# CONFIG_USB_GADGET_M66592 is not set
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_FSL_QE is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_GOKU is not set
++CONFIG_USB_GADGET_ASPEED_AST=y
++CONFIG_USB_ASPEED_AST=y
++# CONFIG_USB_GADGET_DUMMY_HCD is not set
++CONFIG_USB_GADGET_DUALSPEED=y
++CONFIG_USB_ZERO=m
++CONFIG_USB_ETH=m
++CONFIG_USB_ETH_RNDIS=y
++CONFIG_USB_GADGETFS=m
++CONFIG_USB_FILE_STORAGE=m
++# CONFIG_USB_FILE_STORAGE_TEST is not set
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++CONFIG_USB_CDC_COMPOSITE=m
++# CONFIG_MMC is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++# CONFIG_RTC_HCTOSYS is not set
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++# CONFIG_RTC_DRV_DS1307 is not set
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_S35390A is not set
++# CONFIG_RTC_DRV_FM3130 is not set
++# CONFIG_RTC_DRV_RX8581 is not set
++
++#
++# SPI RTC drivers
++#
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
++# CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_PL030 is not set
++# CONFIG_RTC_DRV_PL031 is not set
++CONFIG_RTC_DRV_ASPEED=y
++# CONFIG_DMADEVICES is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++CONFIG_EXT2_FS_XATTR=y
++CONFIG_EXT2_FS_POSIX_ACL=y
++CONFIG_EXT2_FS_SECURITY=y
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4_FS is not set
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_FILE_LOCKING=y
++# CONFIG_XFS_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++CONFIG_GENERIC_ACL=y
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=y
++# CONFIG_NTFS_DEBUG is not set
++CONFIG_NTFS_RW=y
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=m
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
++# CONFIG_JFFS2_SUMMARY is not set
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_NFS_V4 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_REGISTER_V4 is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf8"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++CONFIG_NLS_CODEPAGE_936=y
++CONFIG_NLS_CODEPAGE_950=y
++CONFIG_NLS_CODEPAGE_932=y
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++# CONFIG_ENABLE_WARN_DEPRECATED is not set
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_MEMORY_INIT=y
++CONFIG_FRAME_POINTER=y
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_LATENCYTOP is not set
++# CONFIG_SYSCTL_SYSCALL_CHECK is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++
++#
++# Tracers
++#
++# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_DEBUG_USER is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++# CONFIG_CRYPTO_FIPS is not set
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD=m
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_NULL=y
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_AUTHENC=m
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++# CONFIG_CRYPTO_ECB is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++CONFIG_CRYPTO_HMAC=y
++# CONFIG_CRYPTO_XCBC is not set
++
++#
++# Digest
++#
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++CONFIG_CRYPTO_SHA1=y
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++CONFIG_CRYPTO_DEFLATE=m
++# CONFIG_CRYPTO_LZO is not set
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++# CONFIG_CRYPTO_HW is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_T10DIF is not set
++CONFIG_CRC_ITU_T=m
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/configs/wedge_defconfig b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/configs/wedge_defconfig
+index 23a9fe3..41fe288 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/configs/wedge_defconfig
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/configs/wedge_defconfig
+@@ -174,6 +174,7 @@ CONFIG_IRMP=y
+ # CONFIG_ARCH_AST2200 is not set
+ # CONFIG_ARCH_AST2300 is not set
+ CONFIG_ARCH_AST2400=y
++CONFIG_WEDGE=y
+ # CONFIG_ARCH_AST2500 is not set
+
+ #
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/configs/yosemite_defconfig b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/configs/yosemite_defconfig
+new file mode 100644
+index 0000000..d32f18e
+--- /dev/null
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/configs/yosemite_defconfig
+@@ -0,0 +1,1480 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.28.9
++# Tue Feb 3 16:41:40 2015
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_KERNEL_GZIP=y
++# CONFIG_KERNEL_BZIP2 is not set
++# CONFIG_KERNEL_LZMA is not set
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++CONFIG_POSIX_MQUEUE=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++CONFIG_IKCONFIG=m
++CONFIG_IKCONFIG_PROC=y
++CONFIG_LOG_BUF_SHIFT=16
++# CONFIG_CGROUPS is not set
++# CONFIG_GROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++CONFIG_KALLSYMS_EXTRA_PASS=y
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++CONFIG_COMPAT_BRK=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++CONFIG_FREEZER=y
++
++#
++# System Type
++#
++CONFIG_ARCH_ASPEED=y
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_LOKI is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM is not set
++CONFIG_IRMP=y
++# CONFIG_PCEXT is not set
++# CONFIG_REMOTEFX is not set
++# CONFIG_ARCH_AST1100 is not set
++# CONFIG_ARCH_AST2100 is not set
++# CONFIG_ARCH_AST2200 is not set
++# CONFIG_ARCH_AST2300 is not set
++CONFIG_ARCH_AST2400=y
++CONFIG_YOSEMITE=y
++# CONFIG_ARCH_AST2500 is not set
++
++#
++# FLASH Chip Select
++#
++# CONFIG_AST_CS0_NOR is not set
++# CONFIG_AST_CS0_NAND is not set
++CONFIG_AST_CS0_SPI=y
++# CONFIG_AST_CS0_NONE is not set
++# CONFIG_AST_CS1_NOR is not set
++# CONFIG_AST_CS1_NAND is not set
++# CONFIG_AST_CS1_SPI is not set
++CONFIG_AST_CS1_NONE=y
++# CONFIG_AST_CS2_NOR is not set
++# CONFIG_AST_CS2_NAND is not set
++# CONFIG_AST_CS2_SPI is not set
++CONFIG_AST_CS2_NONE=y
++# CONFIG_AST_CS3_NOR is not set
++# CONFIG_AST_CS3_NAND is not set
++# CONFIG_AST_CS3_SPI is not set
++CONFIG_AST_CS3_NONE=y
++# CONFIG_AST_CS4_NOR is not set
++# CONFIG_AST_CS4_NAND is not set
++# CONFIG_AST_CS4_SPI is not set
++CONFIG_AST_CS4_NONE=y
++# CONFIG_ARCH_AST1070 is not set
++# CONFIG_AST_SCU_LOCK is not set
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++CONFIG_PLAT_ASPEED=y
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_PABRT_NOIFAR=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++# CONFIG_OUTER_CACHE is not set
++
++#
++# Bus support
++#
++CONFIG_ARM_AMBA=y
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_TICK_ONESHOT=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++CONFIG_ARCH_FLATMEM_HAS_HOLES=y
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++CONFIG_UNEVICTABLE_LRU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++CONFIG_CMDLINE=""
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Power Management
++#
++# CONFIG_CPU_IDLE is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++CONFIG_FPE_NWFPE_XP=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_VFP=y
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_HAVE_AOUT=y
++CONFIG_BINFMT_AOUT=y
++# CONFIG_BINFMT_MISC is not set
++
++#
++# Power management options
++#
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++CONFIG_PM_SLEEP=y
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++# CONFIG_APM_EMULATION is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++CONFIG_INET_TUNNEL=m
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++CONFIG_IPV6=m
++# CONFIG_IPV6_PRIVACY is not set
++# CONFIG_IPV6_ROUTER_PREF is not set
++# CONFIG_IPV6_OPTIMISTIC_DAD is not set
++# CONFIG_INET6_AH is not set
++# CONFIG_INET6_ESP is not set
++# CONFIG_INET6_IPCOMP is not set
++# CONFIG_IPV6_MIP6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++CONFIG_INET6_XFRM_MODE_TRANSPORT=m
++CONFIG_INET6_XFRM_MODE_TUNNEL=m
++CONFIG_INET6_XFRM_MODE_BEET=m
++# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
++CONFIG_IPV6_SIT=m
++CONFIG_IPV6_NDISC_NODETYPE=y
++# CONFIG_IPV6_TUNNEL is not set
++# CONFIG_IPV6_MULTIPLE_TABLES is not set
++# CONFIG_IPV6_MROUTE is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA is not set
++CONFIG_VLAN_8021Q=m
++# CONFIG_VLAN_8021Q_GVRP is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++CONFIG_WAN_ROUTER=y
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++# CONFIG_PHONET is not set
++# CONFIG_WIRELESS is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
++# CONFIG_SYS_HYPERVISOR is not set
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_CONCAT=y
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
++# CONFIG_MTD_AR7_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++CONFIG_MTD_DATAFLASH=m
++CONFIG_MTD_DATAFLASH_WRITE_VERIFY=y
++# CONFIG_MTD_DATAFLASH_OTP is not set
++CONFIG_MTD_M25P80=y
++CONFIG_M25PXX_USE_FAST_READ=y
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++CONFIG_BLK_DEV_NBD=y
++# CONFIG_BLK_DEV_UB is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=16384
++# CONFIG_BLK_DEV_XIP is not set
++# CONFIG_RD_BZIP2 is not set
++CONFIG_RD_LZMA=y
++CONFIG_RD_GZIP=y
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ICS932S401 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_C2PORT is not set
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++CONFIG_SCSI_TGT=y
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++CONFIG_SCSI_SCAN_ASYNC=y
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++CONFIG_SCSI_ISCSI_ATTRS=m
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++# CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++CONFIG_BONDING=m
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++CONFIG_TUN=m
++# CONFIG_VETH is not set
++# CONFIG_NET_ETHERNET is not set
++CONFIG_NETDEV_1000=y
++CONFIG_ASPEEDMAC=y
++# CONFIG_NETDEV_10000 is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++# CONFIG_IWLWIFI_LEDS is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_GPIO is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++CONFIG_MOUSE_PS2_ALPS=y
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++CONFIG_MOUSE_PS2_LIFEBOOK=y
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_ELANTECH is not set
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++CONFIG_MOUSE_SERIAL=y
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_BCM5974 is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_AMBAKMI is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++CONFIG_DEVKMEM=y
++CONFIG_SERIAL_NONSTANDARD=y
++# CONFIG_N_HDLC is not set
++# CONFIG_RISCOM8 is not set
++# CONFIG_SPECIALIX is not set
++# CONFIG_RIO is not set
++# CONFIG_STALDRV is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_NR_UARTS=5
++CONFIG_SERIAL_8250_RUNTIME_UARTS=5
++# CONFIG_SERIAL_AST_DMA_UART is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_AMBA_PL010 is not set
++# CONFIG_SERIAL_AMBA_PL011 is not set
++# CONFIG_SERIAL_AST is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_AST_MISC=y
++# CONFIG_AST_VIDEO is not set
++# CONFIG_ADC_CAT9883 is not set
++# CONFIG_AST_SPI_BIOS is not set
++CONFIG_AST_PECI=y
++# CONFIG_AST_KCS is not set
++# CONFIG_AST_GPIO is not set
++# CONFIG_HW_RANDOM is not set
++CONFIG_NVRAM=y
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_HELPER_AUTO=y
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++# CONFIG_I2C_GPIO is not set
++# CONFIG_I2C_OCORES is not set
++CONFIG_I2C_AST=y
++CONFIG_AST_I2C_SLAVE_MODE=y
++# CONFIG_AST_I2C_SLAVE_EEPROM is not set
++CONFIG_AST_I2C_SLAVE_RDWR=y
++# CONFIG_I2C_SIMTEC is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_STUB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_DS1682 is not set
++CONFIG_AT24=m
++# CONFIG_SENSORS_EEPROM is not set
++CONFIG_SENSORS_PCF8574=m
++# CONFIG_PCF8575 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
++
++#
++# SPI Master Controller Drivers
++#
++CONFIG_SPI_AST=y
++CONFIG_SPI_FMC=y
++CONFIG_SPI_BITBANG=y
++
++#
++# SPI Protocol Masters
++#
++CONFIG_SPI_AT25=m
++# CONFIG_SPI_SPIDEV is not set
++# CONFIG_SPI_TLE62X0 is not set
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIOLIB=y
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO expanders:
++#
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX732X is not set
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_AD7414 is not set
++# CONFIG_SENSORS_AD7418 is not set
++# CONFIG_SENSORS_ADCXX is not set
++# CONFIG_SENSORS_ADM1021 is not set
++# CONFIG_SENSORS_ADM1025 is not set
++# CONFIG_SENSORS_ADM1026 is not set
++# CONFIG_SENSORS_ADM1029 is not set
++# CONFIG_SENSORS_ADM1031 is not set
++# CONFIG_SENSORS_ADM9240 is not set
++# CONFIG_SENSORS_ADT7462 is not set
++# CONFIG_SENSORS_ADT7470 is not set
++# CONFIG_SENSORS_ADT7473 is not set
++# CONFIG_SENSORS_ATXP1 is not set
++# CONFIG_SENSORS_DS1621 is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_F75375S is not set
++# CONFIG_SENSORS_GL518SM is not set
++# CONFIG_SENSORS_GL520SM is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_LM63 is not set
++# CONFIG_SENSORS_LM70 is not set
++CONFIG_SENSORS_LM75=m
++# CONFIG_SENSORS_LM77 is not set
++# CONFIG_SENSORS_LM78 is not set
++# CONFIG_SENSORS_LM80 is not set
++# CONFIG_SENSORS_LM83 is not set
++# CONFIG_SENSORS_LM85 is not set
++# CONFIG_SENSORS_LM87 is not set
++# CONFIG_SENSORS_LM90 is not set
++# CONFIG_SENSORS_LM92 is not set
++# CONFIG_SENSORS_LM93 is not set
++CONFIG_SENSORS_MAX127=m
++# CONFIG_SENSORS_MAX1111 is not set
++# CONFIG_SENSORS_MAX1619 is not set
++# CONFIG_SENSORS_MAX6650 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_DME1737 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47M192 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++CONFIG_SENSORS_ADS7828=m
++# CONFIG_SENSORS_THMC50 is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_SENSORS_W83781D is not set
++# CONFIG_SENSORS_W83791D is not set
++# CONFIG_SENSORS_W83792D is not set
++# CONFIG_SENSORS_W83793 is not set
++# CONFIG_SENSORS_W83L785TS is not set
++# CONFIG_SENSORS_W83L786NG is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++CONFIG_SENSORS_AST_ADC=y
++CONFIG_SENSORS_AST_PWM_FAN=y
++# CONFIG_SENSORS_FB_PANTHER_PLUS is not set
++CONFIG_PMBUS=m
++CONFIG_SENSORS_PMBUS=m
++CONFIG_SENSORS_ADM1275=m
++# CONFIG_SENSORS_LM25066 is not set
++# CONFIG_SENSORS_LTC2978 is not set
++# CONFIG_SENSORS_MAX16064 is not set
++# CONFIG_SENSORS_MAX34440 is not set
++# CONFIG_SENSORS_MAX8688 is not set
++CONFIG_SENSORS_PFE1100=m
++CONFIG_SENSORS_PFE3000=m
++# CONFIG_SENSORS_UCD9000 is not set
++# CONFIG_SENSORS_UCD9200 is not set
++# CONFIG_SENSORS_ZL6100 is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++CONFIG_THERMAL=y
++CONFIG_THERMAL_HWMON=y
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++
++#
++# Watchdog Device Drivers
++#
++# CONFIG_SOFT_WATCHDOG is not set
++CONFIG_AST_WATCHDOG=y
++
++#
++# USB-based Watchdog Cards
++#
++# CONFIG_USBPCWATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM8350_I2C is not set
++
++#
++# Multimedia devices
++#
++
++#
++# Multimedia core support
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_VIDEO_MEDIA is not set
++
++#
++# Multimedia drivers
++#
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_SOUND is not set
++# CONFIG_HID_SUPPORT is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++# CONFIG_USB_ARCH_HAS_OHCI is not set
++CONFIG_USB_ARCH_HAS_EHCI=y
++CONFIG_USB=m
++# CONFIG_USB_DEBUG is not set
++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_SUSPEND is not set
++# CONFIG_USB_OTG is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB is not set
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++# CONFIG_USB_EHCI_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_HWA_HCD is not set
++
++#
++# AST USB Drivers
++#
++CONFIG_AST_USB_UHCI_HCD=y
++# CONFIG_AST_USB_UHCI_MULTIPORT_1 is not set
++# CONFIG_AST_USB_UHCI_MULTIPORT_2 is not set
++CONFIG_AST_USB_UHCI_MULTIPORT_4=y
++# CONFIG_USB_EHCI_SPLIT_ISO is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
++#
++
++#
++# see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=m
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_SEVSEG is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_VST is not set
++CONFIG_USB_GADGET=y
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_VBUS_DRAW=2
++CONFIG_USB_GADGET_SELECTED=y
++# CONFIG_USB_GADGET_AT91 is not set
++# CONFIG_USB_GADGET_ATMEL_USBA is not set
++# CONFIG_USB_GADGET_FSL_USB2 is not set
++# CONFIG_USB_GADGET_LH7A40X is not set
++# CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_PXA25X is not set
++# CONFIG_USB_GADGET_PXA27X is not set
++# CONFIG_USB_GADGET_S3C2410 is not set
++# CONFIG_USB_GADGET_M66592 is not set
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_FSL_QE is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_GOKU is not set
++CONFIG_USB_GADGET_ASPEED_AST=y
++CONFIG_USB_ASPEED_AST=y
++# CONFIG_USB_GADGET_DUMMY_HCD is not set
++CONFIG_USB_GADGET_DUALSPEED=y
++CONFIG_USB_ZERO=m
++CONFIG_USB_ETH=m
++CONFIG_USB_ETH_RNDIS=y
++CONFIG_USB_GADGETFS=m
++CONFIG_USB_FILE_STORAGE=m
++# CONFIG_USB_FILE_STORAGE_TEST is not set
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++CONFIG_USB_CDC_COMPOSITE=m
++# CONFIG_MMC is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++# CONFIG_RTC_HCTOSYS is not set
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++# CONFIG_RTC_DRV_DS1307 is not set
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_S35390A is not set
++# CONFIG_RTC_DRV_FM3130 is not set
++# CONFIG_RTC_DRV_RX8581 is not set
++
++#
++# SPI RTC drivers
++#
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
++# CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_PL030 is not set
++# CONFIG_RTC_DRV_PL031 is not set
++CONFIG_RTC_DRV_ASPEED=y
++# CONFIG_DMADEVICES is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++CONFIG_EXT2_FS_XATTR=y
++CONFIG_EXT2_FS_POSIX_ACL=y
++CONFIG_EXT2_FS_SECURITY=y
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4_FS is not set
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_FILE_LOCKING=y
++# CONFIG_XFS_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++CONFIG_GENERIC_ACL=y
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=y
++# CONFIG_NTFS_DEBUG is not set
++CONFIG_NTFS_RW=y
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=m
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_YAFFS_FS=y
++CONFIG_YAFFS_YAFFS1=y
++# CONFIG_YAFFS_9BYTE_TAGS is not set
++# CONFIG_YAFFS_DOES_ECC is not set
++CONFIG_YAFFS_YAFFS2=y
++CONFIG_YAFFS_AUTO_YAFFS2=y
++# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set
++# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
++# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
++# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
++CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
++# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
++# CONFIG_JFFS2_SUMMARY is not set
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_NFS_V4 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_REGISTER_V4 is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf8"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++CONFIG_NLS_CODEPAGE_936=y
++CONFIG_NLS_CODEPAGE_950=y
++CONFIG_NLS_CODEPAGE_932=y
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++# CONFIG_ENABLE_WARN_DEPRECATED is not set
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_MEMORY_INIT=y
++CONFIG_FRAME_POINTER=y
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_LATENCYTOP is not set
++# CONFIG_SYSCTL_SYSCALL_CHECK is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++
++#
++# Tracers
++#
++# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_DEBUG_USER is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++# CONFIG_CRYPTO_FIPS is not set
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD=m
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_NULL=y
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_AUTHENC=m
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++# CONFIG_CRYPTO_ECB is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++CONFIG_CRYPTO_HMAC=y
++# CONFIG_CRYPTO_XCBC is not set
++
++#
++# Digest
++#
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++CONFIG_CRYPTO_SHA1=y
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++CONFIG_CRYPTO_DEFLATE=m
++# CONFIG_CRYPTO_LZO is not set
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++# CONFIG_CRYPTO_HW is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_T10DIF is not set
++CONFIG_CRC_ITU_T=m
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++
++
++# GUC USB Drivers
++#
++CONFIG_GUC_USB_UHCI_HCD=m
++# CONFIG_GUC_USB_UHCI_MULTIPORT_1 is not set
++# CONFIG_GUC_USB_UHCI_MULTIPORT_2 is not set
++CONFIG_GUC_USB_UHCI_MULTIPORT_4=y
++# CONFIG_USB_GADGET_MUSB_HDRC is not set
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/include/asm/ioctls.h b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/include/asm/ioctls.h
+index a91d8a1..fd50ffe 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/include/asm/ioctls.h
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/include/asm/ioctls.h
+@@ -65,6 +65,7 @@
+ #define TIOCSERGETLSR 0x5459 /* Get line status register */
+ #define TIOCSERGETMULTI 0x545A /* Get multiport config */
+ #define TIOCSERSETMULTI 0x545B /* Set multiport config */
++#define TIOCSERWAITTEMT 0x5499 /* Wait for empty */
+
+ #define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
+ #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/mach-aspeed/Kconfig b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/mach-aspeed/Kconfig
+index a948ab8..6d548f8 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/mach-aspeed/Kconfig
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/mach-aspeed/Kconfig
+@@ -203,6 +203,18 @@ endchoice
+ config AST_SCU_LOCK
+ bool "AST SCU Protection Key"
+
++config WEDGE
++ bool "Facebook Wedge/6-Pack"
++
++config WEDGE100
++ bool "Facebook Wedge100"
++
++config YOSEMITE
++ bool "Facebook Yosemite"
++
++config FBPLATFORM1
++ bool "Facebook Platform1"
++
+ # Support PCIE
+ config PCIE
+ bool "ASPEED PCIE support"
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/mach-aspeed/gpio.c b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/mach-aspeed/gpio.c
+index 3a633e9..e56ca35 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/mach-aspeed/gpio.c
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/mach-aspeed/gpio.c
+@@ -232,7 +232,7 @@ static struct ast_gpio_bank ast_gpio_gp[] = {
+ AST_GPIO_BANK("GPIOR", IO_ADDRESS(AST_GPIO_BASE), 1, 0x080, 0x084, 0x118, 0x11c, 0x128, 0x12c, 0x130, 0x110),
+ AST_GPIO_BANK("GPIOS", IO_ADDRESS(AST_GPIO_BASE), 2, 0x080, 0x084, 0x118, 0x11c, 0x128, 0x12c, 0x130, 0x110),
+ #if defined(CONFIG_ARCH_AST2400)
+- AST_GPIO_BANK("GPIOT", IO_ADDRESS(AST_GPIO_BASE), 4, 0x080, 0x084, 0x118, 0x11c, 0x128, 0x12c, 0x130, 0x110),
++ AST_GPIO_BANK("GPIOT", IO_ADDRESS(AST_GPIO_BASE), 3, 0x080, 0x084, 0x118, 0x11c, 0x128, 0x12c, 0x130, 0x110),
+ AST_GPIO_BANK("GPIOU", IO_ADDRESS(AST_GPIO_BASE), 0, 0x088, 0x08c, 0x148, 0x14c, 0x158, 0x15c, 0x160, 0x140),
+ AST_GPIO_BANK("GPIOV", IO_ADDRESS(AST_GPIO_BASE), 1, 0x088, 0x08c, 0x148, 0x14c, 0x158, 0x15c, 0x160, 0x140),
+ AST_GPIO_BANK("GPIOW", IO_ADDRESS(AST_GPIO_BASE), 2, 0x088, 0x08c, 0x148, 0x14c, 0x158, 0x15c, 0x160, 0x140),
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/mach-aspeed/include/mach/debug-macro.S b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/mach-aspeed/include/mach/debug-macro.S
+index ff3195a..33fc879 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/mach-aspeed/include/mach/debug-macro.S
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/mach-aspeed/include/mach/debug-macro.S
+@@ -13,8 +13,8 @@
+ .macro addruart, rx, tmp
+ mrc p15, 0, \rx, c1, c0
+ tst \rx, #1 @ MMU enabled?
+- ldreq \rx, =AST_UART3_BASE
+- ldrne \rx, =IO_ADDRESS(AST_UART3_BASE)
++ ldreq \rx, =AST_UART_BASE
++ ldrne \rx, =IO_ADDRESS(AST_UART_BASE)
+ .endm
+
+ #define UART_SHIFT 2
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/mach-aspeed/include/mach/platform.h b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/mach-aspeed/include/mach/platform.h
+index 8951ffc..4d6c50c 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/mach-aspeed/include/mach/platform.h
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/mach-aspeed/include/mach/platform.h
+@@ -62,5 +62,20 @@
+ * Watchdog
+ */
+ #define AST_WDT_VA_BASE (IO_ADDRESS(AST_WDT_BASE))
+-
++
++/*
++ * Console UART
++ */
++#ifdef CONFIG_WEDGE
++#define AST_UART_BASE AST_UART3_BASE
++#elif defined(CONFIG_WEDGE100)
++#define AST_UART_BASE AST_UART3_BASE
++#elif defined(CONFIG_YOSEMITE)
++#define AST_UART_BASE AST_UART0_BASE
++#elif defined(CONFIG_FBPLATFORM1)
++#define AST_UART_BASE AST_UART0_BASE
++#else
++#define AST_UART_BASE AST_UART0_BASE
++#endif
++
+ #endif
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/mach-aspeed/include/mach/uncompress.h b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/mach-aspeed/include/mach/uncompress.h
+index 80e560d..3be04b0 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/mach-aspeed/include/mach/uncompress.h
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/mach-aspeed/include/mach/uncompress.h
+@@ -12,8 +12,8 @@
+ #include <mach/platform.h>
+ #include <mach/aspeed_serial.h>
+
+-#define UART_PUT_CHAR (*(volatile unsigned char *)(AST_UART3_BASE + UART_THR))
+-#define UART_GET_LSR (*(volatile unsigned char *)(AST_UART3_BASE + UART_LSR))
++#define UART_PUT_CHAR (*(volatile unsigned char *)(AST_UART_BASE + UART_THR))
++#define UART_GET_LSR (*(volatile unsigned char *)(AST_UART_BASE + UART_LSR))
+
+ static void putc(int c)
+ {
+@@ -21,7 +21,7 @@ static void putc(int c)
+ /* wait for space in the UART's transmitter */
+ while (!(UART_GET_LSR & UART_LSR_THRE))
+ barrier();
+-
++
+ /* send the character out. */
+ UART_PUT_CHAR = c;
+ }
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/mach-aspeed/include/mach/vmalloc.h b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/mach-aspeed/include/mach/vmalloc.h
+index 51912ae..bc1b471 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/mach-aspeed/include/mach/vmalloc.h
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/mach-aspeed/include/mach/vmalloc.h
+@@ -25,5 +25,5 @@
+ #define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END (PAGE_OFFSET + 0x20000000)
+ #else
+-#define VMALLOC_END 0xf8000000UL
+-#endif
+\ No newline at end of file
++#define VMALLOC_END 0xf8000000UL
++#endif
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/plat-aspeed/ast-scu.c b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/plat-aspeed/ast-scu.c
+index 76722f4..101b141 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/plat-aspeed/ast-scu.c
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/plat-aspeed/ast-scu.c
+@@ -1,20 +1,20 @@
+ /********************************************************************************
+-* File Name : arch/arm/plat-aspeed/ast-scu.c
++* File Name : arch/arm/plat-aspeed/ast-scu.c
+ * Author : Ryan Chen
+-* Description : AST SCU
+-*
++* Description : AST SCU
++*
+ * Copyright (C) 2012-2020 ASPEED Technology Inc.
+-* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+-
+-CLK24M
++* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++CLK24M
+ |
+ |--> H-PLL -->HCLK
+ |
+@@ -27,9 +27,9 @@ CLK24M
+ |--> USB2PHY -->UTMICLK
+
+
+-* History :
++* History :
+ * 1. 2012/08/15 Ryan Chen Create
+-*
++*
+ ********************************************************************************/
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+@@ -56,34 +56,34 @@ CLK24M
+
+ static u32 ast_scu_base = IO_ADDRESS(AST_SCU_BASE);
+
+-static inline u32
++static inline u32
+ ast_scu_read(u32 reg)
+ {
+ u32 val;
+-
++
+ val = readl(ast_scu_base + reg);
+-
++
+ SCUDBUG("ast_scu_read : reg = 0x%08x, val = 0x%08x\n", reg, val);
+-
++
+ return val;
+ }
+
+ static inline void
+-ast_scu_write(u32 val, u32 reg)
++ast_scu_write(u32 val, u32 reg)
+ {
+ SCUDBUG("ast_scu_write : reg = 0x%08x, val = 0x%08x\n", reg, val);
+ #ifdef CONFIG_AST_SCU_LOCK
+- //unlock
++ //unlock
+ writel(SCU_PROTECT_UNLOCK, ast_scu_base);
+ writel(val, ast_scu_base + reg);
+ //lock
+- writel(0xaa,ast_scu_base);
++ writel(0xaa,ast_scu_base);
+ #else
+ writel(val, ast_scu_base + reg);
+ #endif
+ }
+
+-//SoC mapping Table
++//SoC mapping Table
+ struct soc_id {
+ const char * name;
+ u32 rev_id;
+@@ -180,9 +180,9 @@ ast_scu_init_video(u8 dynamic_en)
+ ast_scu_write((ast_scu_read(AST_SCU_CLK_SEL) & ~SCU_CLK_VIDEO_SLOW_MASK) | SCU_CLK_VIDEO_SLOW_EN | SCU_CLK_VIDEO_SLOW_SET(0), AST_SCU_CLK_SEL);
+ else
+ ast_scu_write((ast_scu_read(AST_SCU_CLK_SEL) & ~SCU_ECLK_SOURCE_MASK) | SCU_ECLK_SOURCE(2), AST_SCU_CLK_SEL);
+-
++
+ // Enable CLK
+- ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~(SCU_ECLK_STOP_EN | SCU_VCLK_STOP_EN), AST_SCU_CLK_STOP);
++ ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~(SCU_ECLK_STOP_EN | SCU_VCLK_STOP_EN), AST_SCU_CLK_STOP);
+ mdelay(10);
+ ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_VIDEO, AST_SCU_RESET);
+ udelay(100);
+@@ -201,32 +201,32 @@ ast_scu_init_eth(u8 num)
+ ast_scu_write((ast_scu_read(AST_SCU_CLK_SEL) & ~SCU_CLK_MAC_MASK) | SCU_CLK_MAC_DIV(4), AST_SCU_CLK_SEL);
+
+ //Set MAC delay Timing
+- ast_scu_write(0x2255, AST_SCU_MAC_CLK);
++ ast_scu_write(0x2255, AST_SCU_MAC_CLK);
+
+ switch(num) {
+ case 0:
+- ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_MAC0,
+- AST_SCU_RESET);
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_MAC0,
++ AST_SCU_RESET);
+ udelay(100);
+- ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~SCU_MAC0CLK_STOP_EN,
+- AST_SCU_CLK_STOP);
++ ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~SCU_MAC0CLK_STOP_EN,
++ AST_SCU_CLK_STOP);
+ udelay(1000);
+- ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_MAC0,
+- AST_SCU_RESET);
+-
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_MAC0,
++ AST_SCU_RESET);
++
+ break;
+ case 1:
+- ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_MAC1,
+- AST_SCU_RESET);
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_MAC1,
++ AST_SCU_RESET);
+ udelay(100);
+- ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~SCU_MAC1CLK_STOP_EN,
+- AST_SCU_CLK_STOP);
++ ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~SCU_MAC1CLK_STOP_EN,
++ AST_SCU_CLK_STOP);
+ udelay(1000);
+- ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_MAC1,
+- AST_SCU_RESET);
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_MAC1,
++ AST_SCU_RESET);
+ break;
+-
+- }
++
++ }
+ }
+
+
+@@ -292,7 +292,7 @@ ast_scu_init_sdhci(void)
+ {
+ //SDHCI Host's Clock Enable and Reset
+ ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_SD, AST_SCU_RESET);
+-
++
+ ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~SCU_SDCLK_STOP_EN, AST_SCU_CLK_STOP);
+ mdelay(10);
+
+@@ -300,10 +300,10 @@ ast_scu_init_sdhci(void)
+ mdelay(10);
+
+ // SDCLK = H-PLL / 4
+- ast_scu_write((ast_scu_read(AST_SCU_CLK_SEL) & ~SCU_CLK_SD_MASK) | SCU_CLK_SD_DIV(1),
++ ast_scu_write((ast_scu_read(AST_SCU_CLK_SEL) & ~SCU_CLK_SD_MASK) | SCU_CLK_SD_DIV(1),
+ AST_SCU_CLK_SEL);
+ mdelay(10);
+-
++
+ ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_SD, AST_SCU_RESET);
+ }
+
+@@ -358,13 +358,13 @@ EXPORT_SYMBOL(ast_scu_init_jtag);
+ extern void
+ ast_scu_init_lpc(void)
+ {
+- //Note .. It have been enable in U-boot.....
++ //Note .. It have been enable in U-boot.....
+ // ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_LPC, AST_SCU_RESET);
+
+ //enable LPC clock LHCLK = H-PLL/8
+- ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) |
+- SCU_SET_LHCLK_DIV(3) |
+- SCU_LHCLK_SOURCE_EN,
++ ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) |
++ SCU_SET_LHCLK_DIV(3) |
++ SCU_LHCLK_SOURCE_EN,
+ AST_SCU_CLK_STOP);
+
+ }
+@@ -377,7 +377,7 @@ ast_scu_get_lpc_plus_enable(void)
+ {
+ if(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & SCU_FUN_PIN_LPC_PLUS)
+ return 1;
+- else
++ else
+ return 0;
+ }
+
+@@ -390,10 +390,10 @@ ast_scu_init_crt(void)
+ #if defined(CONFIG_AST_DAC) || defined(CONFIG_AST_DVO)
+ ast_scu_write((ast_scu_read(AST_SCU_MISC1_CTRL) & ~(SCU_MISC_D2_PLL_DIS | SCU_MISC_DAC_MASK))
+ | SCU_MISC_DAC_SOURCE_CRT | SCU_MISC_DVO_SOURCE_CRT | SCU_MISC_2D_CRT_EN , AST_SCU_MISC1_CTRL);
+-#elif defined(CONFIG_AST_DVO)
++#elif defined(CONFIG_AST_DVO)
+ ast_scu_write((ast_scu_read(AST_SCU_MISC1_CTRL) & ~(SCU_MISC_D2_PLL_DIS)) |
+ SCU_MISC_DVO_SOURCE_CRT| SCU_MISC_2D_CRT_EN, AST_SCU_MISC1_CTRL);
+-#else //default(CONFIG_AST_DAC)
++#else //default(CONFIG_AST_DAC)
+ ast_scu_write((ast_scu_read(AST_SCU_MISC1_CTRL) & ~(SCU_MISC_D2_PLL_DIS | SCU_MISC_DAC_MASK))
+ | SCU_MISC_DAC_SOURCE_CRT | SCU_MISC_2D_CRT_EN, AST_SCU_MISC1_CTRL);
+ #endif
+@@ -401,7 +401,7 @@ ast_scu_init_crt(void)
+ ast_scu_write((ast_scu_read(AST_SCU_CLK_SEL) & ~SCU_CLK_VIDEO_DELAY_MASK) |
+ SCU_CLK_VIDEO_DELAY(5), AST_SCU_CLK_SEL);
+
+- /* Reset CRT */
++ /* Reset CRT */
+ ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_CRT, AST_SCU_RESET);
+
+ //enable D2 CLK
+@@ -409,7 +409,7 @@ ast_scu_init_crt(void)
+
+ udelay(10);
+ ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_CRT, AST_SCU_RESET);
+-
++
+ }
+
+ EXPORT_SYMBOL(ast_scu_init_crt);
+@@ -448,7 +448,7 @@ ast_get_h_pll_clk(void)
+
+ if(h_pll_set & SCU_H_PLL_OFF)
+ return 0;
+-
++
+ if(h_pll_set & SCU_H_PLL_PARAMETER) {
+ // Programming
+ clk = ast_get_clk_source();
+@@ -470,21 +470,21 @@ ast_get_h_pll_clk(void)
+ speed = SCU_HW_STRAP_GET_H_PLL_CLK(ast_scu_read(AST_SCU_HW_STRAP1));
+ switch (speed) {
+ case 0:
+- clk = 384000000;
++ clk = 384000000;
+ break;
+ case 1:
+- clk = 360000000;
++ clk = 360000000;
+ break;
+ case 2:
+- clk = 336000000;
++ clk = 336000000;
+ break;
+ case 3:
+- clk = 408000000;
++ clk = 408000000;
+ break;
+ default:
+- BUG();
++ BUG();
+ break;
+- }
++ }
+ }
+ SCUDBUG("h_pll = %d\n",clk);
+ return clk;
+@@ -500,7 +500,7 @@ ast_get_m_pll_clk(void)
+
+ if(m_pll_set & SCU_M_PLL_OFF)
+ return 0;
+-
++
+ // Programming
+ clk = ast_get_clk_source();
+ if(m_pll_set & SCU_M_PLL_BYPASS_EN) {
+@@ -542,10 +542,10 @@ ast_get_ahbclk(void)
+ case 3:
+ div = 4;
+ break;
+-
++
+ }
+-
+- SCUDBUG("HPLL=%d, Div=%d, AHB CLK=%d\n", hpll, div, hpll/div);
++
++ SCUDBUG("HPLL=%d, Div=%d, AHB CLK=%d\n", hpll, div, hpll/div);
+ return (hpll/div);
+
+ }
+@@ -559,8 +559,8 @@ ast_get_pclk(void)
+ hpll = ast_get_h_pll_clk();
+ div = SCU_GET_PCLK_DIV(ast_scu_read(AST_SCU_CLK_SEL));
+ div = (div+1) << 1;
+-
+- SCUDBUG("HPLL=%d, Div=%d, PCLK=%d\n", hpll, div, hpll/div);
++
++ SCUDBUG("HPLL=%d, Div=%d, PCLK=%d\n", hpll, div, hpll/div);
+ return (hpll/div);
+
+ }
+@@ -572,7 +572,7 @@ ast_get_lhclk(void)
+ unsigned int div, hpll;
+ u32 clk_sel = ast_scu_read(AST_SCU_CLK_SEL);
+ //FPGA AST1070 is default 100/2 Mhz input
+-// return 50000000;
++// return 50000000;
+ hpll = ast_get_h_pll_clk();
+ if(SCU_LHCLK_SOURCE_EN & clk_sel) {
+ div = SCU_GET_LHCLK_DIV(clk_sel);
+@@ -600,10 +600,10 @@ ast_get_lhclk(void)
+ break;
+ case 7:
+ div = 16;
+- break;
++ break;
+ }
+-
+- SCUDBUG("HPLL=%d, Div=%d, LHCLK = %d\n", hpll, div, hpll/div);
++
++ SCUDBUG("HPLL=%d, Div=%d, LHCLK = %d\n", hpll, div, hpll/div);
+ return (hpll/div);
+ } else {
+ SCUMSG("LPC CLK not enable \n");
+@@ -704,7 +704,7 @@ ast_get_sd_clock_src(void)
+ sd_div = SCU_CLK_SD_GET_DIV(ast_scu_read(AST_SCU_CLK_SEL));
+ SCUDBUG("div %d, sdclk =%d \n",((sd_div + 1) * 2),clk/((sd_div + 1) * 2));
+ clk /= ((sd_div + 1) * 2);
+-
++
+ #endif
+ return clk;
+ }
+@@ -717,7 +717,7 @@ ast_scu_show_system_info (void)
+ u32 h_pll, div;
+
+ h_pll = ast_get_h_pll_clk();
+-
++
+ div = SCU_HW_STRAP_GET_CPU_AHB_RATIO(ast_scu_read(AST_SCU_HW_STRAP1));
+ switch(div) {
+ case 0:
+@@ -732,10 +732,10 @@ ast_scu_show_system_info (void)
+ case 3:
+ div = 4;
+ break;
+-
++
+ }
+
+- SCUMSG("CPU = %d MHz ,AHB = %d MHz (%d:1) \n", h_pll/1000000, h_pll/div/1000000,div);
++ SCUMSG("CPU = %d MHz ,AHB = %d MHz (%d:1) \n", h_pll/1000000, h_pll/div/1000000,div);
+
+ return ;
+ }
+@@ -750,54 +750,68 @@ ast_scu_multi_func_uart(u8 uart)
+ case 1:
+ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL2) |
+ SCU_FUN_PIN_UART1_RXD |
++#ifdef CONFIG_YOSEMITE
++ SCU_FUN_PIN_UART1_TXD,
++#else
+ SCU_FUN_PIN_UART1_TXD |
+ SCU_FUN_PIN_UART1_NRTS |
+ SCU_FUN_PIN_UART1_NDTR |
+ SCU_FUN_PIN_UART1_NRI |
+ SCU_FUN_PIN_UART1_NDSR |
+ SCU_FUN_PIN_UART1_NDCD |
+- SCU_FUN_PIN_UART1_NCTS,
+- AST_SCU_FUN_PIN_CTRL2);
+- break;
++ SCU_FUN_PIN_UART1_NCTS,
++#endif
++ AST_SCU_FUN_PIN_CTRL2);
++ break;
+ case 2:
+ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL2) |
+ SCU_FUN_PIN_UART2_RXD |
++#ifdef CONFIG_YOSEMITE
++ SCU_FUN_PIN_UART2_TXD,
++#else
+ SCU_FUN_PIN_UART2_TXD |
+ SCU_FUN_PIN_UART2_NRTS |
+ SCU_FUN_PIN_UART2_NDTR |
+ SCU_FUN_PIN_UART2_NRI |
+ SCU_FUN_PIN_UART2_NDSR |
+ SCU_FUN_PIN_UART2_NDCD |
+- SCU_FUN_PIN_UART2_NCTS,
+- AST_SCU_FUN_PIN_CTRL2);
+- break;
++ SCU_FUN_PIN_UART2_NCTS,
++#endif
++ AST_SCU_FUN_PIN_CTRL2);
++ break;
+ case 3:
+ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) |
+ SCU_FUN_PIN_UART3_RXD |
++#ifdef CONFIG_YOSEMITE
++ SCU_FUN_PIN_UART3_TXD,
++#else
+ SCU_FUN_PIN_UART3_TXD |
+ SCU_FUN_PIN_UART3_NRTS |
+ SCU_FUN_PIN_UART3_NDTR |
+ SCU_FUN_PIN_UART3_NRI |
+ SCU_FUN_PIN_UART3_NDSR |
+ SCU_FUN_PIN_UART3_NDCD |
+- SCU_FUN_PIN_UART3_NCTS,
+- AST_SCU_FUN_PIN_CTRL1);
++ SCU_FUN_PIN_UART3_NCTS,
++#endif
++ AST_SCU_FUN_PIN_CTRL1);
+ break;
+ case 4:
+ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) |
+ SCU_FUN_PIN_UART4_RXD |
++#ifdef CONFIG_YOSEMITE
++ SCU_FUN_PIN_UART4_TXD,
++#else
+ SCU_FUN_PIN_UART4_TXD |
+ SCU_FUN_PIN_UART4_NRTS |
+ SCU_FUN_PIN_UART4_NDTR |
+ SCU_FUN_PIN_UART4_NRI |
+ SCU_FUN_PIN_UART4_NDSR |
+ SCU_FUN_PIN_UART4_NDCD |
+- SCU_FUN_PIN_UART4_NCTS,
+- AST_SCU_FUN_PIN_CTRL1);
++ SCU_FUN_PIN_UART4_NCTS,
++#endif
++ AST_SCU_FUN_PIN_CTRL1);
+ break;
+ }
+-
+-
+ }
+
+ extern void
+@@ -806,13 +820,13 @@ ast_scu_multi_func_video()
+ #if defined(CONFIG_ARCH_2100) || defined(CONFIG_ARCH_2200)
+ ast_scu_write(ast_scu_read(AST_SCU_MULTI_FUNC_2) |
+ MULTI_FUNC_VIDEO_RGB18 |
+- MULTI_FUNC_VIDEO_SINGLE_EDGE,
+- AST_SCU_MULTI_FUNC_2);
++ MULTI_FUNC_VIDEO_SINGLE_EDGE,
++ AST_SCU_MULTI_FUNC_2);
+ #elif defined(CONFIG_ARCH_1100) || defined(CONFIG_ARCH_2050)
+ ast_scu_write(ast_scu_read(AST_SCU_MULTI_FUNC_2) |
+ MULTI_FUNC_VIDEO_RGB18 |
+- MULTI_FUNC_VIDEO_SINGLE_EDGE,
+- AST_SCU_MULTI_FUNC_2);
++ MULTI_FUNC_VIDEO_SINGLE_EDGE,
++ AST_SCU_MULTI_FUNC_2);
+ #else
+
+ #endif
+@@ -823,40 +837,40 @@ ast_scu_multi_func_eth(u8 num)
+ {
+ switch(num) {
+ case 0:
+- if(ast_scu_read(AST_SCU_HW_STRAP1) && SCU_HW_STRAP_MAC0_RGMII) {
++ if(ast_scu_read(AST_SCU_HW_STRAP1) & SCU_HW_STRAP_MAC0_RGMII) {
+ SCUMSG("MAC0 : RGMII \n");
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) |
+- SCU_FUN_PIN_MAC0_PHY_LINK,
+- AST_SCU_FUN_PIN_CTRL1);
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) |
++ SCU_FUN_PIN_MAC0_PHY_LINK,
++ AST_SCU_FUN_PIN_CTRL1);
+ } else {
+- SCUMSG("MAC0 : RMII/NCSI \n");
++ SCUMSG("MAC0 : RMII/NCSI \n");
+ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) &
+- ~SCU_FUN_PIN_MAC0_PHY_LINK,
+- AST_SCU_FUN_PIN_CTRL1);
++ ~SCU_FUN_PIN_MAC0_PHY_LINK,
++ AST_SCU_FUN_PIN_CTRL1);
+ }
+
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL3) |
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL3) |
+ SCU_FUN_PIN_MAC0_MDIO |
+- SCU_FUN_PIN_MAC0_MDC,
+- AST_SCU_FUN_PIN_CTRL3);
+-
++ SCU_FUN_PIN_MAC0_MDC,
++ AST_SCU_FUN_PIN_CTRL3);
++
+ break;
+ case 1:
+- if(ast_scu_read(AST_SCU_HW_STRAP1) && SCU_HW_STRAP_MAC1_RGMII) {
++ if(ast_scu_read(AST_SCU_HW_STRAP1) & SCU_HW_STRAP_MAC1_RGMII) {
+ SCUMSG("MAC1 : RGMII \n");
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) |
+- SCU_FUN_PIN_MAC1_PHY_LINK,
+- AST_SCU_FUN_PIN_CTRL1);
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) |
++ SCU_FUN_PIN_MAC1_PHY_LINK,
++ AST_SCU_FUN_PIN_CTRL1);
+ } else {
+ SCUMSG("MAC1 : RMII/NCSI \n");
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) &
+- ~SCU_FUN_PIN_MAC1_PHY_LINK,
+- AST_SCU_FUN_PIN_CTRL1);
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) &
++ ~SCU_FUN_PIN_MAC1_PHY_LINK,
++ AST_SCU_FUN_PIN_CTRL1);
+ }
+-
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) |
++
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) |
+ SCU_FUC_PIN_MAC1_MDIO,
+- AST_SCU_FUN_PIN_CTRL5);
++ AST_SCU_FUN_PIN_CTRL5);
+
+ break;
+ }
+@@ -866,18 +880,18 @@ extern void
+ ast_scu_multi_func_nand(void)
+ {
+ //enable NAND flash multipin FLBUSY and FLWP
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL2) |
+- SCU_FUN_PIN_NAND_FLBUSY | SCU_FUN_PIN_NAND_FLWP,
+- AST_SCU_FUN_PIN_CTRL2);
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL2) |
++ SCU_FUN_PIN_NAND_FLBUSY | SCU_FUN_PIN_NAND_FLWP,
++ AST_SCU_FUN_PIN_CTRL2);
+
+ }
+
+ extern void
+ ast_scu_multi_func_nor(void)
+ {
+- //Address
++ //Address
+ //ROMA2~17
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL8) |
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL8) |
+ SCU_FUN_PIN_ROMA2 | SCU_FUN_PIN_ROMA3 |
+ SCU_FUN_PIN_ROMA4 | SCU_FUN_PIN_ROMA5 |
+ SCU_FUN_PIN_ROMA6 | SCU_FUN_PIN_ROMA7 |
+@@ -885,39 +899,39 @@ ast_scu_multi_func_nor(void)
+ SCU_FUN_PIN_ROMA10 | SCU_FUN_PIN_ROMA11 |
+ SCU_FUN_PIN_ROMA12 | SCU_FUN_PIN_ROMA13 |
+ SCU_FUN_PIN_ROMA14 | SCU_FUN_PIN_ROMA15 |
+- SCU_FUN_PIN_ROMA16 | SCU_FUN_PIN_ROMA17,
++ SCU_FUN_PIN_ROMA16 | SCU_FUN_PIN_ROMA17,
+ AST_SCU_FUN_PIN_CTRL8);
+
+ //ROMA18~21
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL9) |
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL9) |
+ SCU_FUN_PIN_ROMA18 | SCU_FUN_PIN_ROMA19 |
+- SCU_FUN_PIN_ROMA20 | SCU_FUN_PIN_ROMA21,
+- AST_SCU_FUN_PIN_CTRL9);
+-
++ SCU_FUN_PIN_ROMA20 | SCU_FUN_PIN_ROMA21,
++ AST_SCU_FUN_PIN_CTRL9);
++
+ //ROMA22,23
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL4) | SCU_FUN_PIN_ROMA22 | SCU_FUN_PIN_ROMA23,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL4) | SCU_FUN_PIN_ROMA22 | SCU_FUN_PIN_ROMA23,
+ AST_SCU_FUN_PIN_CTRL4);
+-
++
+ //ROMA24,25
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL3) | SCU_FUN_PIN_ROMA24 | SCU_FUN_PIN_ROMA25,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL3) | SCU_FUN_PIN_ROMA24 | SCU_FUN_PIN_ROMA25,
+ AST_SCU_FUN_PIN_CTRL3);
+
+ //SCU94 [1] = 0
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL6) & SCU_VIDEO_OUT_MASK,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL6) & SCU_VIDEO_OUT_MASK,
+ AST_SCU_FUN_PIN_CTRL6);
+
+-
++
+ //data
+ //ROMD 4~7 //ROMWE#, OE#
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL4) |
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL4) |
+ SCU_FUN_PIN_ROMOE | SCU_FUN_PIN_ROMWE |
+ SCU_FUN_PIN_ROMD4 | SCU_FUN_PIN_ROMD5 |
+ SCU_FUN_PIN_ROMD6 | SCU_FUN_PIN_ROMD7,
+ AST_SCU_FUN_PIN_CTRL4);
+-
++
+ //ROMD 8~15
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) |
+- SCU_FUC_PIN_ROM_16BIT,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) |
++ SCU_FUC_PIN_ROM_16BIT,
+ AST_SCU_FUN_PIN_CTRL5);
+
+ }
+@@ -925,44 +939,44 @@ ast_scu_multi_func_nor(void)
+ extern void
+ ast_scu_multi_func_romcs(u8 num)
+ {
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL3) |
+- SCU_FUN_PIN_ROMCS(num),
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL3) |
++ SCU_FUN_PIN_ROMCS(num),
+ AST_SCU_FUN_PIN_CTRL3);
+ }
+
+ extern void
+ ast_scu_multi_func_i2c(void)
+ {
+- //TODO check ... //In AST2400 Due to share pin with SD , please not enable I2C 10 ~14
++ //TODO check ... //In AST2400 Due to share pin with SD , please not enable I2C 10 ~14
+ // AST 2400 have 14 , AST 2300 9 ...
+ #ifdef CONFIG_MMC_AST
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) |
+- SCU_FUC_PIN_I2C3 |
+- SCU_FUC_PIN_I2C4 |
+- SCU_FUC_PIN_I2C5 |
+- SCU_FUC_PIN_I2C6 |
+- SCU_FUC_PIN_I2C7 |
+- SCU_FUC_PIN_I2C8 |
+- SCU_FUC_PIN_I2C9,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) |
++ SCU_FUC_PIN_I2C3 |
++ SCU_FUC_PIN_I2C4 |
++ SCU_FUC_PIN_I2C5 |
++ SCU_FUC_PIN_I2C6 |
++ SCU_FUC_PIN_I2C7 |
++ SCU_FUC_PIN_I2C8 |
++ SCU_FUC_PIN_I2C9,
+ AST_SCU_FUN_PIN_CTRL5);
+ #else
+- ast_scu_write((ast_scu_read(AST_SCU_FUN_PIN_CTRL5) |
+- SCU_FUC_PIN_I2C3 |
+- SCU_FUC_PIN_I2C4 |
+- SCU_FUC_PIN_I2C5 |
+- SCU_FUC_PIN_I2C6 |
+- SCU_FUC_PIN_I2C7 |
+- SCU_FUC_PIN_I2C8 |
+- SCU_FUC_PIN_I2C9 |
+- SCU_FUC_PIN_I2C10 |
+- SCU_FUC_PIN_I2C11 |
+- SCU_FUC_PIN_I2C12 |
+- SCU_FUC_PIN_I2C13 |
++ ast_scu_write((ast_scu_read(AST_SCU_FUN_PIN_CTRL5) |
++ SCU_FUC_PIN_I2C3 |
++ SCU_FUC_PIN_I2C4 |
++ SCU_FUC_PIN_I2C5 |
++ SCU_FUC_PIN_I2C6 |
++ SCU_FUC_PIN_I2C7 |
++ SCU_FUC_PIN_I2C8 |
++ SCU_FUC_PIN_I2C9 |
++ SCU_FUC_PIN_I2C10 |
++ SCU_FUC_PIN_I2C11 |
++ SCU_FUC_PIN_I2C12 |
++ SCU_FUC_PIN_I2C13 |
+ SCU_FUC_PIN_I2C14) &
+- ~(SCU_FUC_PIN_SD1 | SCU_FUC_PIN_SD2),
++ ~(SCU_FUC_PIN_SD1 | SCU_FUC_PIN_SD2),
+ AST_SCU_FUN_PIN_CTRL5);
+ #endif
+-}
++}
+
+ EXPORT_SYMBOL(ast_scu_multi_func_i2c);
+
+@@ -972,7 +986,7 @@ ast_scu_multi_func_pwm_tacho(void)
+ //TODO check
+ u32 sts = ast_scu_read(AST_SCU_FUN_PIN_CTRL3) &~0xcfffff;
+ ast_scu_write(sts | 0xc000ff, AST_SCU_FUN_PIN_CTRL3);
+-}
++}
+
+ EXPORT_SYMBOL(ast_scu_multi_func_pwm_tacho);
+
+@@ -981,12 +995,12 @@ extern void
+ ast_scu_multi_func_usb20_host_hub(u8 mode)
+ {
+ if(mode)
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_USB20_HOST,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_USB20_HOST,
+ AST_SCU_FUN_PIN_CTRL5);
+ else
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_USB20_HOST,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_USB20_HOST,
+ AST_SCU_FUN_PIN_CTRL5);
+-}
++}
+
+ EXPORT_SYMBOL(ast_scu_multi_func_usb20_host_hub);
+
+@@ -995,12 +1009,12 @@ extern void
+ ast_scu_multi_func_usb11_host_port4(u8 mode)
+ {
+ if(mode)
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_USB11_PORT4,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_USB11_PORT4,
+ AST_SCU_FUN_PIN_CTRL5);
+ else
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_USB11_PORT4,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_USB11_PORT4,
+ AST_SCU_FUN_PIN_CTRL5);
+-}
++}
+
+ EXPORT_SYMBOL(ast_scu_multi_func_usb11_host_port4);
+
+@@ -1009,26 +1023,26 @@ extern void
+ ast_scu_multi_func_usb11_host_port2(u8 mode)
+ {
+ if(mode)
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_USB11_PORT2,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_USB11_PORT2,
+ AST_SCU_FUN_PIN_CTRL5);
+ else
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_USB11_PORT2,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_USB11_PORT2,
+ AST_SCU_FUN_PIN_CTRL5);
+-}
++}
+
+ EXPORT_SYMBOL(ast_scu_multi_func_usb11_host_port2);
+
+-//0 : 1: SD1 function
++//0 : 1: SD1 function
+ extern void
+ ast_scu_multi_func_sdhc_slot1(u8 mode)
+ {
+ if(mode)
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_SD1,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_SD1,
+ AST_SCU_FUN_PIN_CTRL5);
+ else
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_SD1,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_SD1,
+ AST_SCU_FUN_PIN_CTRL5);
+-}
++}
+
+ EXPORT_SYMBOL(ast_scu_multi_func_sdhc_slot1);
+
+@@ -1036,13 +1050,13 @@ extern void
+ ast_scu_multi_func_sdhc_slot2(u8 mode)
+ {
+ if(mode)
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_SD2,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_SD2,
+ AST_SCU_FUN_PIN_CTRL5);
+ else
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_SD2,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_SD2,
+ AST_SCU_FUN_PIN_CTRL5);
+
+-}
++}
+
+ EXPORT_SYMBOL(ast_scu_multi_func_sdhc_slot2);
+
+@@ -1053,11 +1067,11 @@ ast_scu_multi_func_crt(void)
+
+ //Digital vodeo input function pins : 00 disable, 10 24bits mode 888,
+ ast_scu_write((ast_scu_read(AST_SCU_FUN_PIN_CTRL5) &
+- ~SCU_FUC_PIN_DIGI_V_OUT_MASK) |
++ ~SCU_FUC_PIN_DIGI_V_OUT_MASK) |
+ SCU_FUC_PIN_DIGI_V_OUT(VIDEO_24BITS),AST_SCU_FUN_PIN_CTRL5);
+
+ //VPI input
+-#if 0
++#if 0
+ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL2) |
+ SCU_FUN_PIN_VPIB9 | SCU_FUN_PIN_VPIB8 |
+ SCU_FUN_PIN_VPIB7 | SCU_FUN_PIN_VPIB6 |
+@@ -1070,11 +1084,11 @@ ast_scu_multi_func_crt(void)
+
+ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL3) |
+ SCU_FUN_PIN_VPIR9 | SCU_FUN_PIN_VPIR8 |
+- SCU_FUN_PIN_VPIR7 | SCU_FUN_PIN_VPIR6 |
++ SCU_FUN_PIN_VPIR7 | SCU_FUN_PIN_VPIR6 |
+ SCU_FUN_PIN_VPIR5 | SCU_FUN_PIN_VPIR4 |
+ SCU_FUN_PIN_VPIR3 | SCU_FUN_PIN_VPIR2 |
+ SCU_FUN_PIN_VPIR1 | SCU_FUN_PIN_VPIR0 |
+- SCU_FUN_PIN_VPIG9 | SCU_FUN_PIN_VPIG8 |
++ SCU_FUN_PIN_VPIG9 | SCU_FUN_PIN_VPIG8 |
+ SCU_FUN_PIN_VPIG7 | SCU_FUN_PIN_VPIG6 |
+ SCU_FUN_PIN_VPIG5 | SCU_FUN_PIN_VPIG4 |
+ SCU_FUN_PIN_VPIG3 | SCU_FUN_PIN_VPIG2 |
+@@ -1097,9 +1111,9 @@ ast_scu_revision_id(void)
+ SCUMSG("UnKnow-SOC : %x \n",rev_id);
+ else
+ SCUMSG("SOC : %4s \n",soc_map_table[i].name);
+-
++
+ return rev_id;
+-}
++}
+
+ EXPORT_SYMBOL(ast_scu_revision_id);
+
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/plat-aspeed/dev-eth.c b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/plat-aspeed/dev-eth.c
+index 5d33e33..b115c5a 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/plat-aspeed/dev-eth.c
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/plat-aspeed/dev-eth.c
+@@ -7,11 +7,11 @@
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+@@ -37,7 +37,7 @@
+ #if defined(CONFIG_ASPEEDMAC) || defined(CONFIG_ASPEEDMAC_MODULE)
+ #ifdef AST_MAC0_BASE
+ static struct ftgmac100_eth_data ast_eth0_data = {
+- .dev_addr = { 0x00, 0x84, 0x14, 0xA0, 0xB0, 0x22},
++ .dev_addr = { 0x00, 0x84, 0x14, 0xA0, 0xB0, 0x22},
+ .phy_id = 1,
+ };
+
+@@ -69,7 +69,7 @@ static struct platform_device ast_eth0_device = {
+ #endif
+ #ifdef AST_MAC1_BASE
+ static struct ftgmac100_eth_data ast_eth1_data = {
+- .dev_addr = { 0x00, 0x84, 0x14, 0xA0, 0xB0, 0x23},
++ .dev_addr = { 0x00, 0x84, 0x14, 0xA0, 0xB0, 0x23},
+ .phy_id = 1,
+ };
+
+@@ -131,11 +131,16 @@ void __init ast_add_device_gmac(void)
+ }
+
+ ast_eth0_data.DF_support = !isRevA0;
+-
++
++ // Wedge/6-Pack hardware attaches to MAC1; there's nothing on
++ // MAC0. Older drivers would drop interfaces without PHYs, but
++ // the latest open source drivers do not, so we drop the first
++ // MAC specs.
++#if !defined(CONFIG_WEDGE) && !defined(CONFIG_WEDGE100)
+ ast_scu_init_eth(0);
+ ast_scu_multi_func_eth(0);
+-
+-
++
++
+ /*
+ * D[15:11] in 0x1E6E2040 is NCSI scratch from U-Boot. D[15:14] = MAC1, D[13:12] = MAC2
+ * The meanings of the 2 bits are:
+@@ -144,7 +149,7 @@ void __init ast_add_device_gmac(void)
+ * 10(2): ASPEED's MAC is connected to NC-SI PHY chip directly
+ * 11: Reserved
+ */
+-
++
+ phy_mode = ast_scu_get_phy_config(0);
+ switch(phy_mode) {
+ case 0:
+@@ -152,12 +157,12 @@ void __init ast_add_device_gmac(void)
+ ast_eth0_data.NCSI_support = 0;
+ break;
+ case 1:
+- ast_eth0_data.NCSI_support = 1;
++ ast_eth0_data.INTEL_NCSI_EVA_support = 1;
+ break;
+ case 2:
+- ast_eth0_data.INTEL_NCSI_EVA_support = 1;
++ ast_eth0_data.NCSI_support = 1;
+ break;
+-
++
+ }
+
+ phy_inter = ast_scu_get_phy_interface(0);
+@@ -165,12 +170,13 @@ void __init ast_add_device_gmac(void)
+ // We assume the Clock Stop register does not disable the MAC1 or MAC2 clock
+ // unless Reset Control also holds the MAC in reset.
+
+-
++
+ platform_device_register(&ast_eth0_device);
++#endif
+
+ #ifdef AST_MAC1_BASE
+ ast_scu_init_eth(1);
+- ast_scu_multi_func_eth(1);
++ ast_scu_multi_func_eth(1);
+
+ ast_eth1_data.DF_support = !isRevA0;
+
+@@ -186,7 +192,7 @@ void __init ast_add_device_gmac(void)
+ case 2:
+ ast_eth1_data.INTEL_NCSI_EVA_support = 1;
+ break;
+-
++
+ }
+ phy_inter = ast_scu_get_phy_interface(1);
+
+@@ -198,4 +204,3 @@ void __init ast_add_device_gmac(void)
+ #else
+ void __init ast_add_device_gmac(void) {}
+ #endif
+-
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/plat-aspeed/dev-i2c.c b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/plat-aspeed/dev-i2c.c
+index 9905390..fffa480 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/plat-aspeed/dev-i2c.c
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/plat-aspeed/dev-i2c.c
+@@ -7,11 +7,11 @@
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+@@ -47,59 +47,59 @@
+ #if defined (CONFIG_ARCH_AST2400)
+ #define I2C_PAGE_SIZE 8
+ static spinlock_t page_info_lock = SPIN_LOCK_UNLOCKED;
+-static struct buf_page page_info[I2C_PAGE_SIZE] =
+-{
++static struct buf_page page_info[I2C_PAGE_SIZE] =
++{
+ [0] = {
+ .flag = 0,
+ .page_no = 0,
+ .page_size = 256,
+- .page_addr_point = 0,
++ .page_addr_point = 0,
+ },
+ [1] = {
+ .flag = 0,
+- .page_no = 1,
++ .page_no = 1,
+ .page_size = 256,
+- .page_addr_point = 0,
++ .page_addr_point = 0,
+ },
+ [2] = {
+ .flag = 0,
+- .page_no = 2,
++ .page_no = 2,
+ .page_size = 256,
+ .page_addr_point = 0,
+ },
+ [3] = {
+ .flag = 0,
+- .page_no = 3,
++ .page_no = 3,
+ .page_size = 256,
+ .page_addr_point = 0,
+ },
+ [4] = {
+ .flag = 0,
+- .page_no = 4,
++ .page_no = 4,
+ .page_size = 256,
+ .page_addr_point = 0,
+ },
+ [5] = {
+ .flag = 0,
+- .page_no = 5,
++ .page_no = 5,
+ .page_size = 256,
+ .page_addr_point = 0,
+ },
+ [6] = {
+ .flag = 0,
+- .page_no = 6,
++ .page_no = 6,
+ .page_size = 256,
+ .page_addr_point = 0,
+ },
+ [7] = {
+ .flag = 0,
+- .page_no = 7,
++ .page_no = 7,
+ .page_size = 256,
+ .page_addr_point = 0,
+ },
+ };
+
+-static void pool_buff_page_init(u32 buf_pool_addr)
++static void pool_buff_page_init(u32 buf_pool_addr)
+ {
+ u32 offset;
+ int i ,j;
+@@ -108,7 +108,7 @@ static void pool_buff_page_init(u32 buf_pool_addr)
+ offset = 0;
+ for(j=0;j<i;j++)
+ offset += page_info[i].page_size;
+-
++
+ page_info[i].page_addr = buf_pool_addr + offset;
+ // I2CDBUG( "page[%d],addr :%x \n", i, page_info[i].page_addr);
+ }
+@@ -130,7 +130,7 @@ static u8 request_pool_buff_page(struct buf_page **req_page)
+ break;
+ }
+ }
+- spin_unlock_irqrestore(&page_info_lock, flags);
++ spin_unlock_irqrestore(&page_info_lock, flags);
+ return (i >= I2C_PAGE_SIZE);
+ }
+
+@@ -140,17 +140,17 @@ static void free_pool_buff_page(struct buf_page *req_page)
+ spin_lock_irqsave(&page_info_lock, flags);
+
+ req_page->flag = 0;
+-// I2CDBUG( "free page addr %x \n", req_page->page_addr);
++// I2CDBUG( "free page addr %x \n", req_page->page_addr);
+ req_page = NULL;
+- spin_unlock_irqrestore(&page_info_lock, flags);
++ spin_unlock_irqrestore(&page_info_lock, flags);
+ }
+
+ #elif defined (CONFIG_ARCH_AST2300)
+ #define I2C_PAGE_SIZE 5
+
+ static spinlock_t page_info_lock = SPIN_LOCK_UNLOCKED;
+-static struct buf_page page_info[I2C_PAGE_SIZE] =
+-{
++static struct buf_page page_info[I2C_PAGE_SIZE] =
++{
+ [0] = {
+ .flag = 0,
+ .page_size = 128,
+@@ -173,7 +173,7 @@ static struct buf_page page_info[I2C_PAGE_SIZE] =
+ },
+ };
+
+-static void pool_buff_page_init(u32 buf_pool_addr)
++static void pool_buff_page_init(u32 buf_pool_addr)
+ {
+
+ u32 offset;
+@@ -183,7 +183,7 @@ static void pool_buff_page_init(u32 buf_pool_addr)
+ offset = 0;
+ for(j=0;j<i;j++)
+ offset += page_info[i].page_size;
+-
++
+ page_info[i].page_addr = buf_pool_addr + offset;
+ page_info[i].page_addr_point = page_info[i].page_addr/4;
+ // printk("page[%d],addr :%x , point : %d\n", i, page_info[i].page_addr, page_info[i].page_addr_point);
+@@ -201,11 +201,11 @@ static u8 request_pool_buff_page(struct buf_page **req_page)
+ if(page_info[i].flag ==0) {
+ page_info[i].flag = 1;
+ *req_page = &page_info[i];
+- spin_unlock_irqrestore(&page_info_lock, flags);
++ spin_unlock_irqrestore(&page_info_lock, flags);
+ return 0;
+ }
+ }
+- spin_unlock_irqrestore(&page_info_lock, flags);
++ spin_unlock_irqrestore(&page_info_lock, flags);
+ return 1;
+
+ }
+@@ -217,10 +217,10 @@ static void free_pool_buff_page(struct buf_page *req_page)
+ spin_lock_irqsave(&page_info_lock, flags);
+ req_page->flag = 0;
+ req_page = NULL;
+- spin_unlock_irqrestore(&page_info_lock, flags);
++ spin_unlock_irqrestore(&page_info_lock, flags);
+ }
+
+-#else
++#else
+ //DO nothing
+ static void pool_buff_page_init(void) {}
+ static u8 request_pool_buff_page(struct buf_page **req_page) {return 0;}
+@@ -228,15 +228,15 @@ static void free_pool_buff_page(struct buf_page *req_page) {}
+ #endif
+
+ static struct ast_i2c_driver_data ast_i2c_data = {
+- .bus_clk = 100000, //bus clock 100KHz
++ .bus_clk = 100000, //bus clock 100KHz
+ .master_dma = BUFF_MODE,
+ .slave_dma = BYTE_MODE,
+ .request_pool_buff_page = request_pool_buff_page,
+ .free_pool_buff_page = free_pool_buff_page,
+-#ifdef CONFIG_AST_I2C_SLAVE_MODE
++#ifdef CONFIG_AST_I2C_SLAVE_MODE
+ .slave_xfer = i2c_slave_xfer,
+ .slave_init = i2c_slave_init,
+-#endif
++#endif
+ .get_i2c_clock = ast_get_pclk,
+ };
+
+@@ -285,7 +285,7 @@ struct platform_device ast_i2c_dev2_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev2_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev2_resources),
+@@ -310,7 +310,7 @@ struct platform_device ast_i2c_dev3_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev3_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev3_resources),
+@@ -335,7 +335,7 @@ struct platform_device ast_i2c_dev4_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev4_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev4_resources),
+@@ -360,7 +360,7 @@ struct platform_device ast_i2c_dev5_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev5_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev5_resources),
+@@ -385,7 +385,7 @@ struct platform_device ast_i2c_dev6_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev6_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev6_resources),
+@@ -410,7 +410,7 @@ struct platform_device ast_i2c_dev7_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev7_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev7_resources),
+@@ -435,7 +435,7 @@ struct platform_device ast_i2c_dev8_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev8_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev8_resources),
+@@ -460,7 +460,7 @@ struct platform_device ast_i2c_dev9_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev9_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev9_resources),
+@@ -486,7 +486,7 @@ struct platform_device ast_i2c_dev10_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev10_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev10_resources),
+@@ -511,7 +511,7 @@ struct platform_device ast_i2c_dev11_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev11_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev11_resources),
+@@ -536,7 +536,7 @@ struct platform_device ast_i2c_dev12_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev12_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev12_resources),
+@@ -561,7 +561,7 @@ struct platform_device ast_i2c_dev13_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev13_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev13_resources),
+@@ -586,7 +586,7 @@ struct platform_device ast_i2c_dev14_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev14_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev14_resources),
+@@ -594,12 +594,196 @@ struct platform_device ast_i2c_dev14_device = {
+ #endif
+
+ /*--------- I2C Board devices ------------*/
+-//ASPEED AST2300 EVB I2C Device
++//ASPEED AST2300 EVB I2C Device
+ #if defined(CONFIG_ARCH_AST2300) || defined(CONFIG_ARCH_AST2400)
++
++#if defined(CONFIG_WEDGE100)
++
++static struct i2c_board_info __initdata wedge100_i2c_bus1[] = {
++ /* shared NIC, no kernel driver */
++};
++
++static struct i2c_board_info __initdata wedge100_i2c_bus2[] = {
++ /* TODO: one IR3581 and two IR3584 */
++};
++
++static struct i2c_board_info __initdata wedge100_i2c_bus3[] = {
++ /* TODO: one PWR1014A */
++};
++
++static struct i2c_board_info __initdata wedge100_i2c_bus4[] = {
++ {
++ I2C_BOARD_INFO("tmp75", 0x48),
++ },
++ {
++ I2C_BOARD_INFO("tmp75", 0x49),
++ },
++ {
++ I2C_BOARD_INFO("tmp75", 0x4a),
++ },
++ {
++ I2C_BOARD_INFO("tmp75", 0x4b),
++ },
++ {
++ I2C_BOARD_INFO("tmp75", 0x4c),
++ },
++};
++
++static struct i2c_board_info __initdata wedge100_i2c_bus5[] = {
++ /* Panther+ microserver */
++ {
++ I2C_BOARD_INFO("fb_panther_plus", 0x40),
++ },
++};
++
++static struct i2c_board_info __initdata wedge100_i2c_bus6[] = {
++ /* TODO: USB hub */
++};
++
++static struct i2c_board_info __initdata wedge100_i2c_bus7[] = {
++ {
++ I2C_BOARD_INFO("pcf8574", 0x2f),
++ },
++ {
++ I2C_BOARD_INFO("24c64", 0x51),
++ }
++};
++
++static struct i2c_board_info __initdata wedge100_i2c_bus8[] = {
++ /* BMC PHY EEPROM */
++ {
++ I2C_BOARD_INFO("24c02", 0x50),
++ },
++ // EEPROM on the pfe1100 power supplies
++ {
++ I2C_BOARD_INFO("24c64", 0x51),
++ },
++ {
++ I2C_BOARD_INFO("24c64", 0x52),
++ },
++ /* PSU driver */
++ {
++ I2C_BOARD_INFO("pfe1100", 0x59),
++ },
++ {
++ I2C_BOARD_INFO("pfe1100", 0x5a),
++ },
++};
++
++static struct i2c_board_info __initdata wedge100_i2c_bus9[] = {
++ {
++ I2C_BOARD_INFO("fancpld", 0x33),
++ },
++ {
++ I2C_BOARD_INFO("tmp75", 0x48),
++ },
++ {
++ I2C_BOARD_INFO("tmp75", 0x49),
++ },
++};
++
++/* i2c bus 10-12 on wedge100 are not connected as i2c bus */
++
++static struct i2c_board_info __initdata wedge100_i2c_bus13[] = {
++ {
++ I2C_BOARD_INFO("syscpld", 0x31),
++ },
++};
++
++/* i2c bus 14 on wedge100 are not connected as i2c bus */
++
++/* end of defined(CONFIG_WEDGE100) */
++
++#elif defined(CONFIG_YOSEMITE) || defined(CONFIG_FBPLATFORM1)
++
++//Under I2C Dev 1
++static struct i2c_board_info __initdata ast_i2c_board_info_1[] = {
++ // Slot#0 NIC sideband
++};
++
++//Under I2C Dev 2
++static struct i2c_board_info __initdata ast_i2c_board_info_2[] = {
++ // Slot#0 IPMB interface
++};
++
++//Under I2C Dev 3
++static struct i2c_board_info __initdata ast_i2c_board_info_3[] = {
++ // Slot#1 NIC sideband
++};
++
++
++//Under I2C Dev 4
++static struct i2c_board_info __initdata ast_i2c_board_info_4[] = {
++ // Slot#1 IPMB interface
++};
++
++//Under I2C Dev 5
++static struct i2c_board_info __initdata ast_i2c_board_info_5[] = {
++ // Slot#2 NIC sideband
++};
++
++//Under I2C Dev 6
++static struct i2c_board_info __initdata ast_i2c_board_info_6[] = {
++ // Slot#2 IPMB interface
++};
++
++//Under I2C Dev 7
++static struct i2c_board_info __initdata ast_i2c_board_info_7[] = {
++ // Slot#3 NIC sideband
++};
++
++//Under I2C Dev 8
++static struct i2c_board_info __initdata ast_i2c_board_info_8[] = {
++ // Slot#3 IPMB interface
++};
++
++//Under I2C Dev 9
++static struct i2c_board_info __initdata ast_i2c_board_info_9[] = {
++ // FRUID
++ {
++ I2C_BOARD_INFO("24c64", 0x51),
++ },
++};
++
++//Under I2C Dev 10
++static struct i2c_board_info __initdata ast_i2c_board_info_10[] = {
++ // Inlet and Outlet temp. sensors
++ {
++ I2C_BOARD_INFO("tmp75", 0x4e),
++ },
++ {
++ I2C_BOARD_INFO("tmp75", 0x4f),
++ },
++};
++
++//Under I2C Dev 11
++static struct i2c_board_info __initdata ast_i2c_board_info_11[] = {
++ // Hotswap Sensor
++ {
++ I2C_BOARD_INFO("adm1278", 0x40),
++ },
++};
++
++//Under I2C Dev 12
++static struct i2c_board_info __initdata ast_i2c_board_info_12[] = {
++ // Mezz Card LAN_SMB bus (PHY, Temp. Sensor)
++};
++
++//Under I2C Dev 13
++static struct i2c_board_info __initdata ast_i2c_board_info_13[] = {
++ // Mezz Card Mezz_SMB bus (FRUID, GPIO expander, QSFP+)
++};
++
++/* end of CONFIG_YOSEMITE */
++
++#else
++
++/* wedge */
++
+ //Under I2C Dev 1
+ static struct i2c_board_info __initdata ast_i2c_board_info_1[] = {
+ {
+- I2C_BOARD_INFO("cat9883", 0x4d),
++ I2C_BOARD_INFO("cat9883", 0x4d),
+ }
+ };
+
+@@ -612,15 +796,6 @@ static struct i2c_board_info __initdata ast_i2c_board_info_2[] = {
+ {
+ I2C_BOARD_INFO("ncp4200", 0x60),
+ },
+- {
+- I2C_BOARD_INFO("ncp4200", 0x61),
+- },
+- {
+- I2C_BOARD_INFO("ncp4200", 0x62),
+- },
+- {
+- I2C_BOARD_INFO("ncp4200", 0x63),
+- },
+ };
+
+
+@@ -632,15 +807,6 @@ static struct i2c_board_info __initdata ast_i2c_board_info_3[] = {
+ {
+ I2C_BOARD_INFO("ncp4200", 0x60),
+ },
+- {
+- I2C_BOARD_INFO("ncp4200", 0x61),
+- },
+- {
+- I2C_BOARD_INFO("ncp4200", 0x62),
+- },
+- {
+- I2C_BOARD_INFO("ncp4200", 0x63),
+- },
+ };
+
+
+@@ -675,7 +841,7 @@ static struct i2c_board_info __initdata ast_i2c_board_info_5[] = {
+ I2C_BOARD_INFO("24c128", 0x51),
+ },
+ };
+-
++
+ //Under I2C Dev 7
+ static struct i2c_board_info __initdata ast_i2c_board_info_7[] = {
+ // Wedge devices
+@@ -688,15 +854,23 @@ static struct i2c_board_info __initdata ast_i2c_board_info_7[] = {
+ },
+ {
+ I2C_BOARD_INFO("24c64", 0x50),
+- }
++ },
+ };
+
+
+ //Under I2C Dev 8
+ static struct i2c_board_info __initdata ast_i2c_board_info_8[] = {
+ {
++ // 6pack power supply
++ I2C_BOARD_INFO("pfe3000", 0x10),
++ },
++ {
+ // Eval board:
+- I2C_BOARD_INFO("lm75b", 0x4a),
++ I2C_BOARD_INFO("lm75b", 0x4a),
++ },
++ {
++ // 6pack power supply EEPROM
++ I2C_BOARD_INFO("24c64", 0x50),
+ },
+ // EEPROMS on the pfe1100 power supplies
+ {
+@@ -722,20 +896,12 @@ static struct i2c_board_info __initdata ast_i2c_board_info_9[] = {
+ {
+ I2C_BOARD_INFO("ncp4200", 0x60),
+ },
+- {
+- I2C_BOARD_INFO("ncp4200", 0x61),
+- },
+- {
+- I2C_BOARD_INFO("ncp4200", 0x62),
+- },
+- {
+- I2C_BOARD_INFO("ncp4200", 0x63),
+- },
+ };
+
+ //Under I2C Dev 12
+ static struct i2c_board_info __initdata ast_i2c_board_info_12[] = {
+ {
++ // Early version of 6pack
+ I2C_BOARD_INFO("pfe3000", 0x10),
+ },
+ };
+@@ -747,6 +913,10 @@ static struct i2c_board_info __initdata ast_i2c_board_info_13[] = {
+ },
+ };
+
++/* end of WEDGE case */
++#endif
++
++/* end of defined(CONFIG_ARCH_AST2300) || defined(CONFIG_ARCH_AST2400) */
+ #endif
+
+ /*-------------------------------------*/
+@@ -755,7 +925,7 @@ void __init ast_add_device_i2c(void)
+ //I2C Multi-Pin
+ ast_scu_multi_func_i2c();
+
+- //SCU I2C Reset
++ //SCU I2C Reset
+ ast_scu_init_i2c();
+
+ ast_i2c_data.reg_gr = ioremap(AST_I2C_BASE, 4*SZ_16);
+@@ -777,8 +947,48 @@ void __init ast_add_device_i2c(void)
+ return;
+ }
+ #endif
+- //TODO
+- pool_buff_page_init(ast_i2c_data.buf_pool);
++
++ pool_buff_page_init(ast_i2c_data.buf_pool);
++
++#if defined(CONFIG_WEDGE100)
++
++ platform_device_register(&ast_i2c_dev1_device);
++ i2c_register_board_info(0, wedge100_i2c_bus1, ARRAY_SIZE(wedge100_i2c_bus1));
++
++ platform_device_register(&ast_i2c_dev2_device);
++ i2c_register_board_info(1, wedge100_i2c_bus2, ARRAY_SIZE(wedge100_i2c_bus2));
++
++ platform_device_register(&ast_i2c_dev3_device);
++ i2c_register_board_info(2, wedge100_i2c_bus3, ARRAY_SIZE(wedge100_i2c_bus3));
++
++ platform_device_register(&ast_i2c_dev4_device);
++ i2c_register_board_info(3, wedge100_i2c_bus4, ARRAY_SIZE(wedge100_i2c_bus4));
++
++ platform_device_register(&ast_i2c_dev5_device);
++ i2c_register_board_info(4, wedge100_i2c_bus5, ARRAY_SIZE(wedge100_i2c_bus5));
++
++ platform_device_register(&ast_i2c_dev6_device);
++ i2c_register_board_info(5, wedge100_i2c_bus6, ARRAY_SIZE(wedge100_i2c_bus6));
++
++ platform_device_register(&ast_i2c_dev7_device);
++ i2c_register_board_info(6, wedge100_i2c_bus7, ARRAY_SIZE(wedge100_i2c_bus7));
++
++ platform_device_register(&ast_i2c_dev8_device);
++ i2c_register_board_info(7, wedge100_i2c_bus8, ARRAY_SIZE(wedge100_i2c_bus8));
++
++ platform_device_register(&ast_i2c_dev9_device);
++ i2c_register_board_info(8, wedge100_i2c_bus9, ARRAY_SIZE(wedge100_i2c_bus9));
++
++ /* i2c bus 10 - 12 are not used as i2c on wedge100 */
++
++ platform_device_register(&ast_i2c_dev13_device);
++ i2c_register_board_info(12, wedge100_i2c_bus13, ARRAY_SIZE(wedge100_i2c_bus13));
++
++ /* i2c bug 14 is not used as i2c on wedge100 */
++
++ /* end of defined(CONFIG_WEDGE100) */
++#else
++
+ platform_device_register(&ast_i2c_dev1_device);
+ i2c_register_board_info(0, ast_i2c_board_info_1, ARRAY_SIZE(ast_i2c_board_info_1));
+ platform_device_register(&ast_i2c_dev2_device);
+@@ -790,17 +1000,27 @@ void __init ast_add_device_i2c(void)
+ platform_device_register(&ast_i2c_dev5_device);
+ i2c_register_board_info(4, ast_i2c_board_info_5, ARRAY_SIZE(ast_i2c_board_info_5));
+ platform_device_register(&ast_i2c_dev6_device);
++#if defined(CONFIG_YOSEMITE)
++ i2c_register_board_info(5, ast_i2c_board_info_6, ARRAY_SIZE(ast_i2c_board_info_6));
++#endif
+ platform_device_register(&ast_i2c_dev7_device);
+ i2c_register_board_info(6, ast_i2c_board_info_7, ARRAY_SIZE(ast_i2c_board_info_7));
+ platform_device_register(&ast_i2c_dev8_device);
+ i2c_register_board_info(7, ast_i2c_board_info_8, ARRAY_SIZE(ast_i2c_board_info_8));
+- platform_device_register(&ast_i2c_dev9_device);
++ platform_device_register(&ast_i2c_dev9_device);
+ i2c_register_board_info(8, ast_i2c_board_info_9, ARRAY_SIZE(ast_i2c_board_info_9));
+
+ #if defined(CONFIG_ARCH_AST2400)
+ platform_device_register(&ast_i2c_dev10_device);
++
++#if defined(CONFIG_YOSEMITE)
++ i2c_register_board_info(9, ast_i2c_board_info_10, ARRAY_SIZE(ast_i2c_board_info_10));
++ platform_device_register(&ast_i2c_dev11_device);
++ i2c_register_board_info(10, ast_i2c_board_info_11, ARRAY_SIZE(ast_i2c_board_info_11));
++#endif
++
+ #if defined(CONFIG_MMC_AST)
+- //Due to share pin with SD
++ //Due to share pin with SD
+ #else
+ /*
+ * On Wedge, bus 13 is used as i2c bus. Bus 12 is used on other
+@@ -812,7 +1032,12 @@ void __init ast_add_device_i2c(void)
+ i2c_register_board_info(11, ast_i2c_board_info_12, ARRAY_SIZE(ast_i2c_board_info_12));
+ platform_device_register(&ast_i2c_dev13_device);
+ i2c_register_board_info(12, ast_i2c_board_info_13, ARRAY_SIZE(ast_i2c_board_info_13));
+-#endif
++#endif
++
++ /* end of defined(CONFIG_ARCH_AST2400) */
++#endif
++
++ /* end of else of defined(CONFIG_WEDGE100) */
+ #endif
+ }
+ #else
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/plat-aspeed/dev-spi.c b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/plat-aspeed/dev-spi.c
+index e22c49e..0cb0189 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/plat-aspeed/dev-spi.c
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/plat-aspeed/dev-spi.c
+@@ -344,8 +344,8 @@ static struct flash_platform_data wedge_spi_flash_data = {
+
+
+ /* Device info for the flash on ast-spi */
+-#ifdef CONFIG_ARCH_AST2400
+-static struct mtd_partition ast_spi5_flash_partitions[] = {
++#ifdef CONFIG_WEDGE
++static struct mtd_partition wedge_spi5_flash_partitions[] = {
+ {
+ .name = "led-fpga",
+ .offset = 0, /* From 0 */
+@@ -355,8 +355,8 @@ static struct mtd_partition ast_spi5_flash_partitions[] = {
+
+ static struct flash_platform_data wedge_spi5_flash_data = {
+ .type = "at45db011d",
+- .nr_parts = ARRAY_SIZE(ast_spi5_flash_partitions),
+- .parts = ast_spi5_flash_partitions,
++ .nr_parts = ARRAY_SIZE(wedge_spi5_flash_partitions),
++ .parts = wedge_spi5_flash_partitions,
+ };
+ #endif
+
+@@ -372,6 +372,7 @@ static struct spi_board_info ast_spi_devices[] = {
+ },
+ #endif
+ #ifdef CONFIG_ARCH_AST2400
++#ifdef CONFIG_WEDGE
+ {
+ .modalias = "mtd_dataflash",
+ .platform_data = &wedge_spi5_flash_data,
+@@ -380,6 +381,15 @@ static struct spi_board_info ast_spi_devices[] = {
+ .bus_num = 5,
+ .mode = SPI_MODE_0,
+ },
++#elif defined CONFIG_WEDGE100
++ {
++ .modalias = "spidev",
++ .chip_select = 0,
++ .max_speed_hz = 33 * 1000 * 1000,
++ .bus_num = 5,
++ .mode = SPI_MODE_0,
++ },
++#endif
+ {
+ .modalias = "m25p80",
+ .platform_data = &wedge_spi_flash_data,
+@@ -389,13 +399,6 @@ static struct spi_board_info ast_spi_devices[] = {
+ .mode = SPI_MODE_0,
+ },
+ #endif
+- {
+- .modalias = "spidev",
+- .chip_select = 0,
+- .max_speed_hz = 30 * 1000 * 1000,
+- .bus_num = 1,
+- .mode = SPI_MODE_0,
+- },
+ };
+
+ #if defined(AST_SPI1_BASE)
+@@ -490,5 +493,3 @@ void __init ast_add_device_spi(void)
+ #else
+ void __init ast_add_device_spi(void) {}
+ #endif
+-
+-
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/plat-aspeed/dev-uart.c b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/plat-aspeed/dev-uart.c
+index 0b7b614..e424a5a 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/plat-aspeed/dev-uart.c
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/plat-aspeed/dev-uart.c
+@@ -6,11 +6,11 @@
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+@@ -50,14 +50,14 @@ static struct plat_serial8250_port ast_uart_data[] = {
+ .irq = IRQ_UART0,
+ .uartclk = (24*1000000L),
+ .regshift = 2,
+-#if defined(CONFIG_COLDFIRE)
++#if defined(CONFIG_COLDFIRE)
+ .iotype = UPIO_MEM32,
+ #else
+ .iotype = UPIO_MEM,
+-#endif
++#endif
+ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ },
+-#if defined(CONFIG_ARCH_AST1010)
++#if defined(CONFIG_ARCH_AST1010)
+ {
+ .mapbase = AST_UART1_BASE,
+ .irq = IRQ_UART1,
+@@ -65,7 +65,7 @@ static struct plat_serial8250_port ast_uart_data[] = {
+ .regshift = 2,
+ .iotype = UPIO_MEM32,
+ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+- },
++ },
+ {
+ .mapbase = AST_UART2_BASE,
+ .irq = IRQ_UART2,
+@@ -73,7 +73,7 @@ static struct plat_serial8250_port ast_uart_data[] = {
+ .regshift = 2,
+ .iotype = UPIO_MEM32,
+ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+- },
++ },
+ #else
+ //BMC UART 1 ,2 default to LPC
+ #ifdef CONFIG_ARCH_AST1070
+@@ -85,7 +85,7 @@ static struct plat_serial8250_port ast_uart_data[] = {
+ .regshift = 2,
+ .iotype = UPIO_MEM,
+ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+- },
++ },
+ #endif
+ #ifdef AST_UART2_BASE
+ {
+@@ -95,7 +95,7 @@ static struct plat_serial8250_port ast_uart_data[] = {
+ .regshift = 2,
+ .iotype = UPIO_MEM,
+ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+- },
++ },
+ #endif
+ #endif
+ #ifdef AST_UART1_BASE
+@@ -109,6 +109,19 @@ static struct plat_serial8250_port ast_uart_data[] = {
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ },
+ #endif
++#if defined(CONFIG_YOSEMITE) //Without this, tty offset might change for others
++#ifdef AST_UART2_BASE
++ {
++ .mapbase = AST_UART2_BASE,
++ .membase = (char*)(IO_ADDRESS(AST_UART2_BASE)),
++ .irq = IRQ_UART2,
++ .uartclk = (24*1000000L),
++ .regshift = 2,
++ .iotype = UPIO_MEM,
++ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++ },
++#endif
++#endif
+ #ifdef AST_UART3_BASE
+ {
+ .mapbase = AST_UART3_BASE,
+@@ -117,7 +130,7 @@ static struct plat_serial8250_port ast_uart_data[] = {
+ .regshift = 2,
+ .iotype = UPIO_MEM,
+ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+- },
++ },
+ #endif
+ #ifdef AST_UART4_BASE
+ {
+@@ -127,9 +140,9 @@ static struct plat_serial8250_port ast_uart_data[] = {
+ .regshift = 2,
+ .iotype = UPIO_MEM,
+ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+- },
++ },
++#endif
+ #endif
+-#endif
+ { },
+ };
+
+@@ -144,11 +157,16 @@ struct platform_device ast_uart_device = {
+ void __init ast_add_device_uart(void)
+ {
+ #if defined(CONFIG_ARCH_AST1010)
++#elif defined(CONFIG_YOSEMITE)
++ ast_scu_multi_func_uart(1);
++ ast_scu_multi_func_uart(2);
++ ast_scu_multi_func_uart(3);
++ ast_scu_multi_func_uart(4);
+ #else
+- ast_scu_multi_func_uart(1);
+- ast_scu_multi_func_uart(3);
+- ast_scu_multi_func_uart(4);
+-#endif
++ ast_scu_multi_func_uart(1);
++ ast_scu_multi_func_uart(3);
++ ast_scu_multi_func_uart(4);
++#endif
+ platform_device_register(&ast_uart_device);
+ }
+ #else
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/plat-aspeed/irq.c b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/plat-aspeed/irq.c
+index b118359..f6100fa 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/plat-aspeed/irq.c
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/arch/arm/plat-aspeed/irq.c
+@@ -48,13 +48,14 @@ static void ast_mask_irq(unsigned int irq)
+ if((irq >= IRQ_TIMER0) && (irq <= IRQ_TIMER2))
+ timer = 1;
+ #endif
+-
+- if (irq > 32) {
++
++ // for irq0-irq31 use LOW register; for irq32-irq63 use HIGH register set.
++ if (irq >= 32) {
+ i=1;
+ irq = irq - 32;
+ } else
+ i=0;
+-
++
+ regVal = readl(AST_INTR_DIS(i));
+ regVal |= (1 << irq);
+ writel(regVal, AST_INTR_DIS(i));
+@@ -63,8 +64,8 @@ static void ast_mask_irq(unsigned int irq)
+ * clear the interrupt
+ */
+ if(timer)
+- IRQ_EDGE_CLEAR(i,irq);
+-
++ IRQ_EDGE_CLEAR(i,irq);
++
+ }
+
+ static void ast_unmask_irq(unsigned int irq)
+@@ -72,12 +73,13 @@ static void ast_unmask_irq(unsigned int irq)
+ int i;
+ u32 regVal;
+
+- if (irq > 32) {
++ // for irq0-irq31 use LOW register; for irq32-irq63 use HIGH register set.
++ if (irq >= 32) {
+ i=1;
+ irq = irq - 32;
+ } else
+ i=0;
+-
++
+ regVal = readl(AST_INTR_EN(i));
+ regVal |= (1 << irq);
+ writel(regVal, AST_INTR_EN(i));
+@@ -88,8 +90,8 @@ static struct irq_chip ast_irq_chip = {
+ .ack = ast_mask_irq,
+ .mask = ast_mask_irq,
+ .unmask = ast_unmask_irq,
+-};
+-
++};
++
+ void __init ast_init_irq(void)
+ {
+ unsigned int i;
+@@ -107,8 +109,8 @@ void __init ast_init_irq(void)
+ writel(0xFFFFFFFF, AST_INTR_EDGE_CLR(1));
+ #endif
+
+- //TOTAL IRQ NUM =
+- for (i = 0; i < AST_VIC_NUM; i++)
++ //TOTAL IRQ NUM =
++ for (i = 0; i < AST_VIC_NUM; i++)
+ {
+ if(i<32) {
+ if((i >= IRQ_TIMER0) && (i <= IRQ_TIMER2)) //Timer0/1/2
+@@ -125,9 +127,9 @@ void __init ast_init_irq(void)
+ IRQ_SET_HIGH_LEVEL(1,i-32);
+ IRQ_SET_LEVEL_TRIGGER(1,i-32);
+ }
+-#endif
++#endif
+ }
+-
++
+ set_irq_chip(i, &ast_irq_chip);
+ set_irq_handler(i, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/hwmon/ast_adc.c b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/hwmon/ast_adc.c
+index 3f95dc6..8f5aa54 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/hwmon/ast_adc.c
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/hwmon/ast_adc.c
+@@ -13,10 +13,10 @@
+ * 2012.11.26: Initial version [Ryan Chen]
+ */
+
+-/* attr ADC sysfs 0~max adc channel
++/* attr ADC sysfs 0~max adc channel
+ * 0 - show/store enable
+ * 3 - show value
+-* 1 - show/store alarm_en set enable
++* 1 - show/store alarm_en set enable
+ * 2 - show alarm get statuse
+ * 4 - show/store upper
+ * 5 - show/store lower */
+@@ -44,13 +44,33 @@
+
+ #define REST_DESIGN 5
+
++
++#ifdef CONFIG_YOSEMITE
++enum {
++ ADC_P5V = 0,
++ ADC_P12V,
++ ADC_P3V3_STBY,
++ ADC_P12V_SLOT0,
++ ADC_P12V_SLOT1,
++ ADC_P12V_SLOT2,
++ ADC_P12V_SLOT3,
++ ADC_P3V3,
++};
++
++enum {
++ REST_DESIGN_P3V3 = 6,
++ REST_DESIGN_P5V = 7,
++ REST_DESIGN_P12V = 8,
++};
++#endif // CONFIG_YOSEMITE
++
+ struct adc_vcc_ref_data {
+ int v2;
+ int r1;
+- int r2;
++ int r2;
+ };
+
+-static struct adc_vcc_ref_data adc_vcc_ref[6] = {
++static struct adc_vcc_ref_data adc_vcc_ref[9] = {
+ [0] = {
+ .v2 = 0,
+ .r1 = 5600,
+@@ -81,6 +101,24 @@ static struct adc_vcc_ref_data adc_vcc_ref[6] = {
+ .r1 = 1000,
+ .r2 = 1000,
+ },
++ // P3V3
++ [6] = {
++ .v2 = 0,
++ .r1 = 5110,
++ .r2 = 8250,
++ },
++ // P5V
++ [7] = {
++ .v2 = 0,
++ .r1 = 5110,
++ .r2 = 3480,
++ },
++ // P12V
++ [8] = {
++ .v2 = 0,
++ .r1 = 5110,
++ .r2 = 1020,
++ },
+ };
+
+ /* Divisors for voltage sense; right now adc5 & adc6 divide by 2 */
+@@ -93,7 +131,7 @@ static int adc_divisor[] = { 1, 1, 1, 1,
+ struct ast_adc_data {
+ struct device *hwmon_dev;
+ void __iomem *reg_base; /* virtual */
+- int irq; //ADC IRQ number
++ int irq; //ADC IRQ number
+ int compen_value; //Compensating value
+ };
+
+@@ -123,14 +161,14 @@ static void ast_adc_ctrl_init(void)
+ ast_adc_write(ast_adc, AST_ADC_CTRL_COMPEN | AST_ADC_CTRL_NORMAL | AST_ADC_CTRL_EN, AST_ADC_CTRL);
+
+ //Set wait a sensing cycle t (s) = 1000 * 12 * (1/PCLK) * 2 * (ADC0c[31:17] + 1) * (ADC0c[9:0] +1)
+- //ex : pclk = 48Mhz , ADC0c[31:17] = 0, ADC0c[9:0] = 0x40 : 64, ADC0c[31:17] = 0x3e7 : 999
++ //ex : pclk = 48Mhz , ADC0c[31:17] = 0, ADC0c[9:0] = 0x40 : 64, ADC0c[31:17] = 0x3e7 : 999
+ // --> 0.0325s = 12 * 2 * (0x3e7 + 1) *(64+1) / 48000000
+- // --> 0.0005s = 12 * 2 * (0x3e7 + 1) / 48000000
+-
++ // --> 0.0005s = 12 * 2 * (0x3e7 + 1) / 48000000
++
+ pclk = ast_get_pclk();
+
+ #if defined(CONFIG_ARCH_AST2300)
+- ast_adc_write(ast_adc, 0x3e7, AST_ADC_CLK);
++ ast_adc_write(ast_adc, 0x3e7, AST_ADC_CLK);
+
+ ast_adc_write(ast_adc, AST_ADC_CTRL_CH12_EN | AST_ADC_CTRL_COMPEN_CLR| ast_adc_read(ast_adc, AST_ADC_CTRL), AST_ADC_CTRL);
+
+@@ -141,16 +179,16 @@ static void ast_adc_ctrl_init(void)
+ ast_adc->compen_value = 0x200 - (ast_adc_read(ast_adc, AST_ADC_CH12_13) & AST_ADC_L_CH_MASK);
+ else
+ ast_adc->compen_value = 0 - (ast_adc_read(ast_adc, AST_ADC_CH12_13) & AST_ADC_L_CH_MASK);
+-
+- printk("compensating value %d \n",ast_adc->compen_value);
+-
++
++ // printk("compensating value %d \n",ast_adc->compen_value);
++
+ #elif defined(CONFIG_ARCH_AST2400)
+
+ //For AST2400 A0 workaround ... ADC0c = 1 ;
+ // ast_adc_write(ast_adc, 1, AST_ADC_CLK);
+ // ast_adc_write(ast_adc, (0x3e7<< 17) | 0x40, AST_ADC_CLK);
+ ast_adc_write(ast_adc, 0x40, AST_ADC_CLK);
+-
++
+ ast_adc_write(ast_adc, AST_ADC_CTRL_CH0_EN | AST_ADC_CTRL_COMPEN | AST_ADC_CTRL_NORMAL | AST_ADC_CTRL_EN, AST_ADC_CTRL);
+
+ ast_adc_read(ast_adc, AST_ADC_CTRL);
+@@ -159,15 +197,15 @@ static void ast_adc_ctrl_init(void)
+
+ //compensating value = 0x200 - ADC10[9:0]
+ ast_adc->compen_value = 0x200 - (ast_adc_read(ast_adc, AST_ADC_CH0_1) & AST_ADC_L_CH_MASK);
+- printk("compensating value %d \n",ast_adc->compen_value);
++ // printk("compensating value %d \n",ast_adc->compen_value);
+
+ #elif defined(CONFIG_ARCH_AST2500)
+-// TODO ...
+-// scu read trim
++// TODO ...
++// scu read trim
+ // write trim 0xc4 [3:0]
+-
++
+ ast_adc_write(ast_adc, 0x40, AST_ADC_CLK);
+-
++
+ ast_adc_write(ast_adc, AST_ADC_CTRL_NORMAL | AST_ADC_CTRL_EN, AST_ADC_CTRL);
+
+ while(!ast_adc_read(ast_adc, AST_ADC_CTRL) & 0x100);
+@@ -175,17 +213,17 @@ static void ast_adc_ctrl_init(void)
+ ast_adc_write(ast_adc, AST_ADC_CTRL_COMPEN | AST_ADC_CTRL_NORMAL | AST_ADC_CTRL_EN, AST_ADC_CTRL);
+
+ while(ast_adc_read(ast_adc, AST_ADC_CTRL) & AST_ADC_CTRL_COMPEN);
+-
++
+ //compensating value = 0x200 - ADC10[9:0]
+ ast_adc->compen_value = 0x200 - ((ast_adc_read(ast_adc, AST_ADC_TRIM) >> 16) & 0x3ff);
+- printk("compensating value %d \n",ast_adc->compen_value);
+-
++ // printk("compensating value %d \n",ast_adc->compen_value);
++
+ #else
+ #err "No define for ADC "
+ #endif
+
+ ast_adc_write(ast_adc, AST_ADC_CTRL_NORMAL | AST_ADC_CTRL_EN, AST_ADC_CTRL);
+-
++
+ }
+
+ static u16
+@@ -203,9 +241,9 @@ ast_get_adc_hyster_lower(struct ast_adc_data *ast_adc, u8 adc_ch)
+ static void
+ ast_set_adc_hyster_lower(struct ast_adc_data *ast_adc, u8 adc_ch, u16 value)
+ {
+- ast_adc_write(ast_adc,
++ ast_adc_write(ast_adc,
+ (ast_adc_read(ast_adc, AST_ADC_HYSTER0 + (adc_ch *4)) & ~AST_ADC_L_BOUND) |
+- value,
++ value,
+ AST_ADC_HYSTER0 + (adc_ch *4));
+
+ }
+@@ -224,9 +262,9 @@ ast_get_adc_hyster_upper(struct ast_adc_data *ast_adc, u8 adc_ch)
+ static void
+ ast_set_adc_hyster_upper(struct ast_adc_data *ast_adc, u8 adc_ch, u32 value)
+ {
+- ast_adc_write(ast_adc,
++ ast_adc_write(ast_adc,
+ (ast_adc_read(ast_adc, AST_ADC_HYSTER0 + (adc_ch *4)) & ~AST_ADC_H_BOUND) |
+- (value << 16),
++ (value << 16),
+ AST_ADC_HYSTER0 + (adc_ch *4));
+
+ }
+@@ -244,7 +282,7 @@ ast_get_adc_hyster_en(struct ast_adc_data *ast_adc, u8 adc_ch)
+ static void
+ ast_set_adc_hyster_en(struct ast_adc_data *ast_adc, u8 adc_ch, u8 enable)
+ {
+- //tacho source
++ //tacho source
+ if(enable == 1)
+ ast_adc_write(ast_adc,
+ ast_adc_read(ast_adc, AST_ADC_HYSTER0 + (adc_ch *4)) | AST_ADC_HYSTER_EN,
+@@ -270,9 +308,9 @@ ast_get_adc_lower(struct ast_adc_data *ast_adc, u8 adc_ch)
+ static void
+ ast_set_adc_lower(struct ast_adc_data *ast_adc, u8 adc_ch, u16 value)
+ {
+- ast_adc_write(ast_adc,
++ ast_adc_write(ast_adc,
+ (ast_adc_read(ast_adc, AST_ADC_BOUND0 + (adc_ch *4)) & ~AST_ADC_L_BOUND) |
+- value,
++ value,
+ AST_ADC_BOUND0 + (adc_ch *4));
+
+ }
+@@ -293,9 +331,9 @@ ast_get_adc_upper(struct ast_adc_data *ast_adc, u8 adc_ch)
+ static void
+ ast_set_adc_upper(struct ast_adc_data *ast_adc, u8 adc_ch, u32 value)
+ {
+- ast_adc_write(ast_adc,
++ ast_adc_write(ast_adc,
+ (ast_adc_read(ast_adc, AST_ADC_BOUND0 + (adc_ch *4)) & ~AST_ADC_H_BOUND) |
+- (value << 16),
++ (value << 16),
+ AST_ADC_BOUND0 + (adc_ch *4));
+
+ }
+@@ -304,7 +342,7 @@ ast_set_adc_upper(struct ast_adc_data *ast_adc, u8 adc_ch, u32 value)
+ static u8
+ ast_get_adc_alarm(struct ast_adc_data *ast_adc, u8 adc_ch)
+ {
+- //adc ch source
++ //adc ch source
+ if(ast_adc_read(ast_adc, AST_ADC_IER) & (0x1 << adc_ch))
+ return 1;
+ else
+@@ -322,61 +360,61 @@ ast_get_adc_value(struct ast_adc_data *ast_adc, u8 adc_ch)
+ break;
+ case 1:
+ tmp = (ast_adc_read(ast_adc, AST_ADC_CH0_1) & AST_ADC_H_CH_MASK) >> 16;
+- break;
++ break;
+ case 2:
+ tmp = ast_adc_read(ast_adc, AST_ADC_CH2_3) & AST_ADC_L_CH_MASK;
+ break;
+ case 3:
+ tmp = (ast_adc_read(ast_adc, AST_ADC_CH2_3) & AST_ADC_H_CH_MASK) >> 16;
+- break;
++ break;
+ case 4:
+ tmp = ast_adc_read(ast_adc, AST_ADC_CH4_5) & AST_ADC_L_CH_MASK;
+ break;
+ case 5:
+ tmp = (ast_adc_read(ast_adc, AST_ADC_CH4_5) & AST_ADC_H_CH_MASK) >> 16;
+- break;
++ break;
+ case 6:
+ tmp = ast_adc_read(ast_adc, AST_ADC_CH6_7) & AST_ADC_L_CH_MASK;
+ break;
+ case 7:
+ tmp = (ast_adc_read(ast_adc, AST_ADC_CH6_7) & AST_ADC_H_CH_MASK) >> 16;
+- break;
++ break;
+ case 8:
+ tmp = ast_adc_read(ast_adc, AST_ADC_CH8_9) & AST_ADC_L_CH_MASK;
+ break;
+ case 9:
+ tmp = (ast_adc_read(ast_adc, AST_ADC_CH8_9) & AST_ADC_H_CH_MASK) >> 16;
+- break;
++ break;
+ case 10:
+ tmp = ast_adc_read(ast_adc, AST_ADC_CH10_11) & AST_ADC_L_CH_MASK;
+ break;
+ case 11:
+ tmp = (ast_adc_read(ast_adc, AST_ADC_CH10_11) & AST_ADC_H_CH_MASK) >> 16;
+- break;
++ break;
+ case 12:
+ tmp = ast_adc_read(ast_adc, AST_ADC_CH12_13) & AST_ADC_L_CH_MASK;
+ break;
+ case 13:
+ tmp = (ast_adc_read(ast_adc, AST_ADC_CH12_13) & AST_ADC_H_CH_MASK) >> 16;
+- break;
++ break;
+ case 14:
+ tmp = ast_adc_read(ast_adc, AST_ADC_CH14_15) & AST_ADC_L_CH_MASK;
+ break;
+ case 15:
+ tmp = (ast_adc_read(ast_adc, AST_ADC_CH14_15) & AST_ADC_H_CH_MASK) >> 16;
+- break;
++ break;
+
+ }
+
+ tmp += ast_adc->compen_value;
+
+ // printk("voltage = %d \n",tmp);
+-
++
+ return tmp;
+
+ }
+
+-static u8
++static u8
+ ast_get_adc_en(struct ast_adc_data *ast_adc, u8 adc_ch)
+ {
+ u8 tmp=0;
+@@ -390,7 +428,7 @@ ast_get_adc_en(struct ast_adc_data *ast_adc, u8 adc_ch)
+
+ }
+
+-static void
++static void
+ ast_set_adc_en(struct ast_adc_data *ast_adc, u8 adc_ch, u8 enable)
+ {
+ if(enable)
+@@ -401,7 +439,7 @@ ast_set_adc_en(struct ast_adc_data *ast_adc, u8 adc_ch, u8 enable)
+
+
+ /* NAME sysfs */
+-static ssize_t
++static ssize_t
+ show_name(struct device *dev, struct device_attribute *devattr,
+ char *buf)
+ {
+@@ -416,38 +454,63 @@ static const struct attribute_group name_attribute_groups = {
+ .attrs = name_attributes,
+ };
+
+-/* attr ADC sysfs 0~max adc channel
++/* attr ADC sysfs 0~max adc channel
+ * 0 - show/store channel enable
+-* 1 - show value
++* 1 - show value
+ * 2 - show alarm get statuse
+ * 3 - show/store upper
+-* 4 - show/store lower
+-* 5 - show/store hystersis enable
+-* 6 - show/store hystersis upper
+-* 7 - show/store hystersis low
++* 4 - show/store lower
++* 5 - show/store hystersis enable
++* 6 - show/store hystersis upper
++* 7 - show/store hystersis low
+ */
+
+-static u32
++static u32
+ ast_get_voltage(int idx) {
++ u8 rest_design = REST_DESIGN;
+ u16 tmp;
+ u32 voltage, tmp1, tmp2, tmp3;
+ tmp = ast_get_adc_value(ast_adc, idx);
++
++#ifdef CONFIG_YOSEMITE
++ switch (idx) {
++ case ADC_P3V3:
++ case ADC_P3V3_STBY:
++ rest_design = REST_DESIGN_P3V3;
++ break;
++ case ADC_P5V:
++ rest_design = REST_DESIGN_P5V;
++ break;
++ case ADC_P12V:
++ case ADC_P12V_SLOT0:
++ case ADC_P12V_SLOT1:
++ case ADC_P12V_SLOT2:
++ case ADC_P12V_SLOT3:
++ rest_design = REST_DESIGN_P12V;
++ break;
++ default:
++ rest_design = REST_DESIGN;
++ }
++#endif // CONFIG_YOSEMITE
++
+ // Voltage Sense Method
+- tmp1 = (adc_vcc_ref[REST_DESIGN].r1 + adc_vcc_ref[REST_DESIGN].r2) * tmp * 25 * 10;
+- tmp2 = adc_vcc_ref[REST_DESIGN].r2 * 1024 ;
+- tmp3 = (adc_vcc_ref[REST_DESIGN].r1 * adc_vcc_ref[REST_DESIGN].v2) / adc_vcc_ref[REST_DESIGN].r2;
++ tmp1 = (adc_vcc_ref[rest_design].r1 + adc_vcc_ref[rest_design].r2) * tmp * 25 * 10;
++ tmp2 = adc_vcc_ref[rest_design].r2 * 1024 ;
++ tmp3 = (adc_vcc_ref[rest_design].r1 * adc_vcc_ref[rest_design].v2) / adc_vcc_ref[rest_design].r2;
+ // printk("tmp3 = %d \n",tmp3);
+ voltage = (tmp1/tmp2) - tmp3;
+
++#ifndef CONFIG_YOSEMITE
+ // Higher voltage inputs require a divisor
+
+ if (adc_divisor[idx])
+ voltage /= adc_divisor[idx];
++#endif //CONFIG_YOSEMITE
+
+ return voltage;
+ }
+
+-static ssize_t
++static ssize_t
+ ast_show_adc(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
+ {
+ struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
+@@ -455,7 +518,7 @@ ast_show_adc(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
+
+ //sensor_attr->index : pwm_ch#
+ //sensor_attr->nr : attr#
+- switch(sensor_attr->nr)
++ switch(sensor_attr->nr)
+ {
+ case 0: //channel enable, disable
+ return sprintf(sysfsbuf, "%d : %s\n", ast_get_adc_en(ast_adc,sensor_attr->index),ast_get_adc_en(ast_adc,sensor_attr->index) ? "Enable":"Disable");
+@@ -466,23 +529,23 @@ ast_show_adc(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
+ break;
+ case 2: //alarm
+ return sprintf(sysfsbuf, "%d \n", ast_get_adc_alarm(ast_adc,sensor_attr->index));
+- break;
++ break;
+ case 3: //upper
+ return sprintf(sysfsbuf, "%d \n", ast_get_adc_upper(ast_adc,sensor_attr->index));
+- break;
++ break;
+ case 4: //lower
+ return sprintf(sysfsbuf, "%d \n", ast_get_adc_lower(ast_adc,sensor_attr->index));
+- break;
+- case 5: //hystersis enable
++ break;
++ case 5: //hystersis enable
+ return sprintf(sysfsbuf, "%d : %s\n", ast_get_adc_hyster_en(ast_adc,sensor_attr->index),ast_get_adc_hyster_en(ast_adc,sensor_attr->index) ? "Enable":"Disable");
+- break;
++ break;
+ case 6: //hystersis upper
+ return sprintf(sysfsbuf, "%d \n", ast_get_adc_hyster_upper(ast_adc,sensor_attr->index));
+- break;
++ break;
+ case 7: //hystersis lower
+ return sprintf(sysfsbuf, "%d \n", ast_get_adc_hyster_lower(ast_adc,sensor_attr->index));
+- break;
+- case 8:
++ break;
++ case 8:
+ voltage = ast_get_voltage(sensor_attr->index);
+ return sprintf(sysfsbuf, "%d\n",voltage * 10);
+
+@@ -492,7 +555,7 @@ ast_show_adc(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
+ }
+ }
+
+-static ssize_t
++static ssize_t
+ ast_store_adc(struct device *dev, struct device_attribute *attr, const char *sysfsbuf, size_t count)
+ {
+ u32 input_val;
+@@ -503,16 +566,16 @@ ast_store_adc(struct device *dev, struct device_attribute *attr, const char *sys
+
+ //sensor_attr->index : pwm_ch#
+ //sensor_attr->nr : attr#
+- switch(sensor_attr->nr)
++ switch(sensor_attr->nr)
+ {
+ case 0: //enable, disable
+ ast_set_adc_en(ast_adc, sensor_attr->index, input_val);
+ break;
+ case 1: //value
+-
++
+ break;
+ case 2: //alarm
+- break;
++ break;
+ case 3:
+ ast_set_adc_upper(ast_adc, sensor_attr->index, input_val);
+ break;
+@@ -521,14 +584,14 @@ ast_store_adc(struct device *dev, struct device_attribute *attr, const char *sys
+ break;
+ case 5: //hystersis
+ ast_set_adc_hyster_en(ast_adc, sensor_attr->index, input_val);
+- break;
++ break;
+ case 6:
+ ast_set_adc_hyster_upper(ast_adc, sensor_attr->index, input_val);
+ break;
+ case 7:
+ ast_set_adc_hyster_lower(ast_adc, sensor_attr->index, input_val);
+ break;
+-
++
+ default:
+ return -EINVAL;
+ break;
+@@ -537,15 +600,15 @@ ast_store_adc(struct device *dev, struct device_attribute *attr, const char *sys
+ return count;
+ }
+
+-/* attr ADC sysfs 0~max adc channel
++/* attr ADC sysfs 0~max adc channel
+ * 0 - show/store channel enable
+-* 1 - show value
++* 1 - show value
+ * 2 - show alarm get statuse
+ * 3 - show/store upper
+-* 4 - show/store lower
+-* 5 - show/store hystersis enable
+-* 6 - show/store hystersis upper
+-* 7 - show/store hystersis low
++* 4 - show/store lower
++* 5 - show/store hystersis enable
++* 6 - show/store hystersis upper
++* 7 - show/store hystersis low
+ * 8 - show value as 1000s, expected by lm-sensors
+ */
+
+@@ -624,18 +687,18 @@ static const struct attribute_group adc_attribute_groups[] = {
+ { .attrs = adc7_attributes },
+ { .attrs = adc8_attributes },
+ { .attrs = adc9_attributes },
+- { .attrs = adc10_attributes },
++ { .attrs = adc10_attributes },
+ { .attrs = adc11_attributes },
+ #if defined(CONFIG_ARCH_AST2400) || defined(CONFIG_ARCH_AST2500)
+ { .attrs = adc12_attributes },
+ { .attrs = adc13_attributes },
+ { .attrs = adc14_attributes },
+ { .attrs = adc15_attributes },
+-#endif
++#endif
+ };
+
+
+-static int
++static int
+ ast_adc_probe(struct platform_device *pdev)
+ {
+ struct resource *res;
+@@ -695,7 +758,7 @@ ast_adc_probe(struct platform_device *pdev)
+ }
+
+ ast_adc_ctrl_init();
+-
++
+ printk(KERN_INFO "ast_adc: driver successfully loaded.\n");
+
+ return 0;
+@@ -714,7 +777,7 @@ out:
+ return ret;
+ }
+
+-static int
++static int
+ ast_adc_remove(struct platform_device *pdev)
+ {
+ int i=0;
+@@ -739,14 +802,14 @@ ast_adc_remove(struct platform_device *pdev)
+ }
+
+ #ifdef CONFIG_PM
+-static int
++static int
+ ast_adc_suspend(struct platform_device *pdev, pm_message_t state)
+ {
+ printk("ast_adc_suspend : TODO \n");
+ return 0;
+ }
+
+-static int
++static int
+ ast_adc_resume(struct platform_device *pdev)
+ {
+ ast_adc_ctrl_init();
+@@ -769,13 +832,13 @@ static struct platform_driver ast_adc_driver = {
+ },
+ };
+
+-static int __init
++static int __init
+ ast_adc_init(void)
+ {
+ return platform_driver_register(&ast_adc_driver);
+ }
+
+-static void __exit
++static void __exit
+ ast_adc_exit(void)
+ {
+ platform_driver_unregister(&ast_adc_driver);
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/i2c/busses/i2c-ast.c b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/i2c/busses/i2c-ast.c
+index 7a083de..9bb3154 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/i2c/busses/i2c-ast.c
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/i2c/busses/i2c-ast.c
+@@ -40,63 +40,68 @@
+ #include <plat/ast_i2c.h>
+ #endif
+
+-//AST2400 buffer mode issue , force I2C slave write use byte mode , read use buffer mode
++//AST2400 buffer mode issue , force I2C slave write use byte mode , read use buffer mode
+ /* Use platform_data instead of module parameters */
+ /* Fast Mode = 400 kHz, Standard = 100 kHz */
+ //static int clock = 100; /* Default: 100 kHz */
+
+
+ /***************************************************************************/
++
++#ifdef CONFIG_AST_I2C_SLAVE_RDWR
++#define I2C_S_BUF_SIZE 64
++#define I2C_S_RX_BUF_NUM 4
++#define BUFF_FULL 0xff00
++#define BUFF_ONGOING 1
++#endif
++
++#define AST_LOCKUP_DETECTED (0x1 << 15)
++
+ struct ast_i2c_dev {
+ struct ast_i2c_driver_data *ast_i2c_data;
+ struct device *dev;
+- void __iomem *reg_base; /* virtual */
+- int irq; //I2C IRQ number
+- u32 bus_id; //for i2c dev# IRQ number check
+- u32 state; //I2C xfer mode state matchine
++ void __iomem *reg_base; /* virtual */
++ int irq; //I2C IRQ number
++ u32 bus_id; //for i2c dev# IRQ number check
++ u32 state; //I2C xfer mode state matchine
+ struct i2c_adapter adap;
+- struct buf_page *req_page;
++ struct buf_page *req_page;
+ //dma or buff mode needed
+ unsigned char *dma_buf;
+ dma_addr_t dma_addr;
+-
+-//master
++
++//master
+ int xfer_last; //cur xfer is last msgs for stop msgs
+ struct i2c_msg *master_msgs; //cur xfer msgs
+- int master_xfer_len; //cur xfer len
++ int master_xfer_len; //cur xfer len
+ int master_xfer_cnt; //total xfer count
+ u32 master_xfer_mode; //cur xfer mode ... 0 : no_op , master: 1 byte , 2 : buffer , 3: dma , slave : xxxx
+ struct completion cmd_complete;
+ int cmd_err;
+ u8 blk_r_flag; //for smbus block read
+- void (*do_master_xfer)(struct ast_i2c_dev *i2c_dev);
+-//Slave structure
++ void (*do_master_xfer)(struct ast_i2c_dev *i2c_dev);
++ spinlock_t master_lock;
++//Slave structure
+ u8 slave_operation;
+ u8 slave_event;
+ struct i2c_msg *slave_msgs; //cur slave xfer msgs
+- int slave_xfer_len;
+- int slave_xfer_cnt;
+- u32 slave_xfer_mode; //cur xfer mode ... 0 : no_op , master: 1 byte , 2 : buffer , 3: dma , slave : xxxx
++ int slave_xfer_len;
++ int slave_xfer_cnt;
++ u32 slave_xfer_mode; //cur xfer mode ... 0 : no_op , master: 1 byte , 2 : buffer , 3: dma , slave : xxxx
+ void (*do_slave_xfer)(struct ast_i2c_dev *i2c_dev);
+-};
+-
+ #ifdef CONFIG_AST_I2C_SLAVE_RDWR
+-#define I2C_S_BUF_SIZE 64
+-#define I2C_S_RX_BUF_NUM 4
+-#define BUFF_FULL 0xff00
+-#define BUFF_ONGOING 1
+-
+-struct i2c_msg slave_rx_msg[I2C_S_RX_BUF_NUM + 1];
+-struct i2c_msg slave_tx_msg;
+-static spinlock_t slave_rx_lock = SPIN_LOCK_UNLOCKED;
++ struct i2c_msg slave_rx_msg[I2C_S_RX_BUF_NUM + 1];
++ struct i2c_msg slave_tx_msg;
++ spinlock_t slave_rx_lock;
+ #endif
++};
++
+
+-static spinlock_t g_master_lock = SPIN_LOCK_UNLOCKED;
+
+ static inline void
+ ast_i2c_write(struct ast_i2c_dev *i2c_dev, u32 val, u32 reg)
+ {
+-// dev_dbg(i2c_dev->dev, "ast_i2c_write : val: %x , reg : %x \n",val,reg);
++// dev_dbg(i2c_dev->dev, "ast_i2c_write : val: %x , reg : %x \n",val,reg);
+ writel(val, i2c_dev->reg_base+ reg);
+ }
+
+@@ -107,7 +112,7 @@ ast_i2c_read(struct ast_i2c_dev *i2c_dev, u32 reg)
+ u32 val = readl(i2c_dev->reg_base + reg);
+ printk("R : reg %x , val: %x \n",reg, val);
+ return val;
+-#else
++#else
+ return readl(i2c_dev->reg_base + reg);
+ #endif
+ }
+@@ -152,7 +157,7 @@ static void ast_slave_issue_alert(struct ast_i2c_dev *i2c_dev, u8 enable)
+ static void ast_slave_mode_enable(struct ast_i2c_dev *i2c_dev, struct i2c_msg *msgs)
+ {
+ if(msgs->buf[0] == 1) {
+- ast_i2c_write(i2c_dev, msgs->addr, I2C_DEV_ADDR_REG);
++ ast_i2c_write(i2c_dev, msgs->addr, I2C_DEV_ADDR_REG);
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_FUN_CTRL_REG) | AST_I2CD_SLAVE_EN, I2C_FUN_CTRL_REG);
+ } else
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_FUN_CTRL_REG) & ~AST_I2CD_SLAVE_EN, I2C_FUN_CTRL_REG);
+@@ -162,12 +167,14 @@ static void ast_slave_mode_enable(struct ast_i2c_dev *i2c_dev, struct i2c_msg *m
+
+ static void ast_i2c_dev_init(struct ast_i2c_dev *i2c_dev)
+ {
+- //I2CG Reset
++ //I2CG Reset
+ ast_i2c_write(i2c_dev, 0, I2C_FUN_CTRL_REG);
+
+-#ifdef CONFIG_AST_I2C_SLAVE_EEPROM
++#ifdef CONFIG_AST_I2C_SLAVE_EEPROM
+ i2c_dev->ast_i2c_data->slave_init(&(i2c_dev->slave_msgs));
+ ast_slave_mode_enable(i2c_dev, i2c_dev->slave_msgs);
++#else
++ i2c_dev->slave_msgs = i2c_dev->slave_rx_msg;
+ #endif
+
+ //Enable Master Mode
+@@ -177,20 +184,20 @@ static void ast_i2c_dev_init(struct ast_i2c_dev *i2c_dev)
+ /* Set AC Timing */
+ #if defined(CONFIG_ARCH_AST2400)
+ if(i2c_dev->ast_i2c_data->bus_clk/1000 > 400) {
+- printk("high speed mode enable clk [%dkhz]\n",i2c_dev->ast_i2c_data->bus_clk/1000);
++ printk("high speed mode enable clk [%dkhz]\n",i2c_dev->ast_i2c_data->bus_clk/1000);
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev, I2C_FUN_CTRL_REG) |
+ AST_I2CD_M_HIGH_SPEED_EN |
+ AST_I2CD_M_SDA_DRIVE_1T_EN |
+- AST_I2CD_SDA_DRIVE_1T_EN
++ AST_I2CD_SDA_DRIVE_1T_EN
+ , I2C_FUN_CTRL_REG);
+-
++
+ /* Set AC Timing */
+ ast_i2c_write(i2c_dev, 0x3, I2C_AC_TIMING_REG2);
+- ast_i2c_write(i2c_dev, select_i2c_clock(i2c_dev), I2C_AC_TIMING_REG1);
++ ast_i2c_write(i2c_dev, select_i2c_clock(i2c_dev), I2C_AC_TIMING_REG1);
+ }else {
+- /* target apeed is xxKhz*/
++ /* target apeed is xxKhz*/
+ ast_i2c_write(i2c_dev, select_i2c_clock(i2c_dev), I2C_AC_TIMING_REG1);
+- ast_i2c_write(i2c_dev, AST_NO_TIMEOUT_CTRL, I2C_AC_TIMING_REG2);
++ ast_i2c_write(i2c_dev, AST_NO_TIMEOUT_CTRL, I2C_AC_TIMING_REG2);
+ }
+ #else
+ /* target apeed is xxKhz*/
+@@ -206,12 +213,12 @@ static void ast_i2c_dev_init(struct ast_i2c_dev *i2c_dev)
+
+ //TODO
+ // ast_i2c_write(i2c_dev, 0xAF, I2C_INTR_CTRL_REG);
+- //Enable Interrupt, STOP Interrupt has bug in AST2000
+-
++ //Enable Interrupt, STOP Interrupt has bug in AST2000
++
+ /* Set interrupt generation of I2C controller */
+ ast_i2c_write(i2c_dev,
+- AST_I2CD_SDA_DL_TO_INTR_EN |
+- AST_I2CD_BUS_RECOVER_INTR_EN |
++ AST_I2CD_SDA_DL_TO_INTR_EN |
++ AST_I2CD_BUS_RECOVER_INTR_EN |
+ AST_I2CD_SMBUS_ALT_INTR_EN |
+ // AST_I2CD_SLAVE_MATCH_INTR_EN |
+ AST_I2CD_SCL_TO_INTR_EN |
+@@ -230,16 +237,16 @@ static void ast_i2c_dev_init(struct ast_i2c_dev *i2c_dev)
+ static void ast_i2c_slave_buff_init(struct ast_i2c_dev *i2c_dev)
+ {
+ int i;
+- //Tx buf 1
+- slave_tx_msg.len = I2C_S_BUF_SIZE;
+- slave_tx_msg.buf = kzalloc(I2C_S_BUF_SIZE, GFP_KERNEL);
++ //Tx buf 1
++ i2c_dev->slave_tx_msg.len = I2C_S_BUF_SIZE;
++ i2c_dev->slave_tx_msg.buf = kzalloc(I2C_S_BUF_SIZE, GFP_KERNEL);
+ //Rx buf 4
+ for(i=0; i<I2C_S_RX_BUF_NUM+1; i++) {
+- slave_rx_msg[i].addr = ~BUFF_ONGOING;
+- slave_rx_msg[i].flags = 0; //mean empty buffer
+- slave_rx_msg[i].len = I2C_S_BUF_SIZE;
+- slave_rx_msg[i].buf = kzalloc(I2C_S_BUF_SIZE, GFP_KERNEL);
+- }
++ i2c_dev->slave_rx_msg[i].addr = ~BUFF_ONGOING;
++ i2c_dev->slave_rx_msg[i].flags = 0; //mean empty buffer
++ i2c_dev->slave_rx_msg[i].len = I2C_S_BUF_SIZE;
++ i2c_dev->slave_rx_msg[i].buf = kzalloc(I2C_S_BUF_SIZE, GFP_KERNEL);
++ }
+ }
+
+ static void ast_i2c_slave_rdwr_xfer(struct ast_i2c_dev *i2c_dev)
+@@ -247,13 +254,13 @@ static void ast_i2c_slave_rdwr_xfer(struct ast_i2c_dev *i2c_dev)
+ int i;
+ unsigned long flags;
+
+- spin_lock_irqsave(&slave_rx_lock, flags);
+-
++ spin_lock_irqsave(&i2c_dev->slave_rx_lock, flags);
++
+ switch(i2c_dev->slave_event) {
+ case I2C_SLAVE_EVENT_START_WRITE:
+ for(i=0; i<I2C_S_RX_BUF_NUM; i++) {
+- if((slave_rx_msg[i].flags == 0) && (slave_rx_msg[i].addr != BUFF_ONGOING)) {
+- slave_rx_msg[i].addr = BUFF_ONGOING;
++ if((i2c_dev->slave_rx_msg[i].flags == 0) && (i2c_dev->slave_rx_msg[i].addr != BUFF_ONGOING)) {
++ i2c_dev->slave_rx_msg[i].addr = BUFF_ONGOING;
+ break;
+ }
+ }
+@@ -261,40 +268,40 @@ static void ast_i2c_slave_rdwr_xfer(struct ast_i2c_dev *i2c_dev)
+ printk("RX buffer full ........use tmp msgs buff \n");
+ //TODO...
+ }
+- printk("I2C_SLAVE_EVENT_START_WRITE ... %d \n", i);
++ //printk("I2C_SLAVE_EVENT_START_WRITE ... %d \n", i);
+
+- i2c_dev->slave_msgs = &slave_rx_msg[i];
++ i2c_dev->slave_msgs = &i2c_dev->slave_rx_msg[i];
+ break;
+ case I2C_SLAVE_EVENT_START_READ:
+- printk("I2C_SLAVE_EVENT_START_READ ERROR .. not imple \n");
+- i2c_dev->slave_msgs = &slave_tx_msg;
++ //printk("I2C_SLAVE_EVENT_START_READ ERROR .. not imple \n");
++ i2c_dev->slave_msgs = &i2c_dev->slave_tx_msg;
+ break;
+ case I2C_SLAVE_EVENT_WRITE:
+- printk("I2C_SLAVE_EVENT_WRITE next write ERROR ...\n");
+- i2c_dev->slave_msgs = &slave_tx_msg;
++ //printk("I2C_SLAVE_EVENT_WRITE next write ERROR ...\n");
++ i2c_dev->slave_msgs = &i2c_dev->slave_tx_msg;
+ break;
+ case I2C_SLAVE_EVENT_READ:
+- printk("I2C_SLAVE_EVENT_READ ERROR ... \n");
+- i2c_dev->slave_msgs = &slave_tx_msg;
++ printk("I2C_SLAVE_EVENT_READ ERROR ... \n");
++ i2c_dev->slave_msgs = &i2c_dev->slave_tx_msg;
+ break;
+ case I2C_SLAVE_EVENT_NACK:
+- printk("I2C_SLAVE_EVENT_NACK ERROR ... \n");
+- i2c_dev->slave_msgs = &slave_tx_msg;
++ //printk("I2C_SLAVE_EVENT_NACK ERROR ... \n");
++ i2c_dev->slave_msgs = &i2c_dev->slave_tx_msg;
+ break;
+ case I2C_SLAVE_EVENT_STOP:
+- printk("I2C_SLAVE_EVENT_STOP \n");
++ //printk("I2C_SLAVE_EVENT_STOP \n");
+ for(i=0; i<I2C_S_RX_BUF_NUM; i++) {
+- if(slave_rx_msg[i].addr == BUFF_ONGOING) {
+- slave_rx_msg[i].flags = BUFF_FULL;
+- slave_rx_msg[i].addr = 0;
++ if(i2c_dev->slave_rx_msg[i].addr == BUFF_ONGOING) {
++ i2c_dev->slave_rx_msg[i].flags = BUFF_FULL;
++ i2c_dev->slave_rx_msg[i].addr = 0;
+ break;
+ }
+ }
+-
+- i2c_dev->slave_msgs = &slave_tx_msg;
++
++ i2c_dev->slave_msgs = &i2c_dev->slave_tx_msg;
+ break;
+ }
+- spin_unlock_irqrestore(&slave_rx_lock, flags);
++ spin_unlock_irqrestore(&i2c_dev->slave_rx_lock, flags);
+
+ }
+
+@@ -308,29 +315,29 @@ static int ast_i2c_slave_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs)
+ case 0:
+ // printk("slave read \n");
+ //cur_msg = get_free_msg;
+- spin_lock_irqsave(&slave_rx_lock, flags);
++ spin_lock_irqsave(&i2c_dev->slave_rx_lock, flags);
+
+ for(i=0; i<I2C_S_RX_BUF_NUM; i++) {
+- if((slave_rx_msg[i].addr == 0) && (slave_rx_msg[i].flags == BUFF_FULL)) {
+- memcpy(msgs->buf, slave_rx_msg[i].buf, slave_rx_msg[i].len);
+- msgs->len = slave_rx_msg[i].len;
+- slave_rx_msg[i].flags = 0;
+- slave_rx_msg[i].len = 0;
++ if((i2c_dev->slave_rx_msg[i].addr == 0) && (i2c_dev->slave_rx_msg[i].flags == BUFF_FULL)) {
++ memcpy(msgs->buf, i2c_dev->slave_rx_msg[i].buf, i2c_dev->slave_rx_msg[i].len);
++ msgs->len = i2c_dev->slave_rx_msg[i].len;
++ i2c_dev->slave_rx_msg[i].flags = 0;
++ i2c_dev->slave_rx_msg[i].len = 0;
+ break;
+ }
+ }
+- spin_unlock_irqrestore(&slave_rx_lock, flags);
+-
++ spin_unlock_irqrestore(&i2c_dev->slave_rx_lock, flags);
++
+ if(i == I2C_S_RX_BUF_NUM) {
+- printk("No buffer ........ \n");
++ //printk("No buffer ........ \n");
+ msgs->len = 0;
+ ret = -1;
+ }
+ break;
+ case I2C_M_RD: //slave write
+ // printk("slave write \n");
+- memcpy(msgs->buf, slave_tx_msg.buf, I2C_S_BUF_SIZE);
+- break;
++ memcpy(msgs->buf, i2c_dev->slave_tx_msg.buf, I2C_S_BUF_SIZE);
++ break;
+ case I2C_S_EN:
+ if((msgs->addr < 0x1) || (msgs->addr > 0xff)) {
+ ret = -1;
+@@ -352,7 +359,7 @@ static int ast_i2c_slave_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs)
+ default:
+ printk("slave xfer error \n");
+ break;
+-
++
+ }
+ return ret;
+ }
+@@ -360,16 +367,16 @@ static int ast_i2c_slave_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs)
+
+ #endif
+
+-static u8
++static u8
+ ast_i2c_bus_error_recover(struct ast_i2c_dev *i2c_dev)
+ {
+ u32 sts;
+- int r;
++ int r;
+ u32 i = 0;
+-
++
+ //Check 0x14's SDA and SCL status
+ sts = ast_i2c_read(i2c_dev,I2C_CMD_REG);
+-
++
+ if ((sts & AST_I2CD_SDA_LINE_STS) && (sts & AST_I2CD_SCL_LINE_STS)) {
+ //Means bus is idle.
+ dev_dbg(i2c_dev->dev, "I2C bus (%d) is idle. I2C slave doesn't exist?!\n", i2c_dev->bus_id);
+@@ -377,11 +384,11 @@ ast_i2c_bus_error_recover(struct ast_i2c_dev *i2c_dev)
+ }
+
+ dev_dbg(i2c_dev->dev, "ERROR!! I2C(%d) bus hanged, try to recovery it!\n", i2c_dev->bus_id);
+-
+-
++
++
+ if ((sts & AST_I2CD_SDA_LINE_STS) && !(sts & AST_I2CD_SCL_LINE_STS)) {
+ //if SDA == 1 and SCL == 0, it means the master is locking the bus.
+- //Send a stop command to unlock the bus.
++ //Send a stop command to unlock the bus.
+ dev_dbg(i2c_dev->dev, "I2C's master is locking the bus, try to stop it.\n");
+ //
+ init_completion(&i2c_dev->cmd_complete);
+@@ -397,12 +404,12 @@ ast_i2c_bus_error_recover(struct ast_i2c_dev *i2c_dev)
+ dev_dbg(i2c_dev->dev, "recovery error \n");
+ return -1;
+ }
+-
++
+ if (r == 0) {
+ dev_dbg(i2c_dev->dev, "recovery timed out\n");
+ return -1;
+ } else {
+- dev_dbg(i2c_dev->dev, "Recovery successfully\n");
++ dev_dbg(i2c_dev->dev, "Recovery successfully\n");
+ return 0;
+ }
+
+@@ -415,11 +422,11 @@ ast_i2c_bus_error_recover(struct ast_i2c_dev *i2c_dev)
+ for (i = 0; i < 10; i++) {
+ ast_i2c_dev_init(i2c_dev);
+ //Do the recovery command BIT11
+- init_completion(&i2c_dev->cmd_complete);
++ init_completion(&i2c_dev->cmd_complete);
+ ast_i2c_write(i2c_dev, AST_I2CD_BUS_RECOVER_CMD_EN, I2C_CMD_REG);
+-
++
+ r = wait_for_completion_interruptible_timeout(&i2c_dev->cmd_complete,
+- i2c_dev->adap.timeout*HZ);
++ i2c_dev->adap.timeout*HZ);
+ if (i2c_dev->cmd_err != 0 &&
+ i2c_dev->cmd_err != AST_I2CD_INTR_STS_NORMAL_STOP) {
+ dev_dbg(i2c_dev->dev, "ERROR!! Failed to do recovery command(0x%08x)\n", i2c_dev->cmd_err);
+@@ -438,31 +445,56 @@ ast_i2c_bus_error_recover(struct ast_i2c_dev *i2c_dev)
+ dev_dbg(i2c_dev->dev, "Don't know how to handle this case?!\n");
+ return -1;
+ }
+- dev_dbg(i2c_dev->dev, "Recovery successfully\n");
++ dev_dbg(i2c_dev->dev, "Recovery successfully\n");
+ return 0;
+ }
+
+-static void ast_master_alert_recv(struct ast_i2c_dev *i2c_dev)
++static void ast_master_alert_recv(struct ast_i2c_dev *i2c_dev)
+ {
+ printk("ast_master_alert_recv bus id %d, Disable Alt, Please Imple \n",i2c_dev->bus_id);
+ }
+
+ static int ast_i2c_wait_bus_not_busy(struct ast_i2c_dev *i2c_dev)
+ {
+- int timeout = 32; //TODO number
++ int timeout = 10; //TODO number
++ volatile u8 mode = 0;
+ // printk("ast_i2c_wait_bus_not_busy \n");
++
++ // Wait for slave transfer to finish
++ mode = i2c_dev->slave_operation;
++ while (mode == 1) {
++ if (timeout <= 0) {
++ break;
++ }
++ mode = i2c_dev->slave_operation;
++ timeout--;
++ msleep(1);
++ }
++
++ if (timeout <= 0) {
++ return -EAGAIN;
++ }
++
++ // Wait for Bus to go IDLE
++ timeout = 10;
+ while (ast_i2c_read(i2c_dev,I2C_CMD_REG) & AST_I2CD_BUS_BUSY_STS) {
+- ast_i2c_bus_error_recover(i2c_dev);
+- if(timeout<=0)
++ if(timeout<=0) {
+ break;
++ }
++
+ timeout--;
+- msleep(2);
++ msleep(1);
+ }
+
+- return timeout <= 0 ? EAGAIN : 0;
++ if (timeout <=0) {
++ ast_i2c_bus_error_recover(i2c_dev);
++ return 0;
++ }
++
++ return 0;
+ }
+
+-static void ast_i2c_do_dma_xfer(struct ast_i2c_dev *i2c_dev)
++static void ast_i2c_do_dma_xfer(struct ast_i2c_dev *i2c_dev)
+ {
+ u32 cmd = 0;
+ int i;
+@@ -470,49 +502,49 @@ static void ast_i2c_do_dma_xfer(struct ast_i2c_dev *i2c_dev)
+ i2c_dev->master_xfer_mode = DMA_XFER;
+ i2c_dev->slave_xfer_mode = DMA_XFER;
+
+- if(i2c_dev->slave_operation == 1) {
++ if(i2c_dev->slave_operation == 1) {
+ if(i2c_dev->slave_msgs->flags & I2C_M_RD) {
+ //DMA tx mode
+ if(i2c_dev->slave_msgs->len > AST_I2C_DMA_SIZE)
+ i2c_dev->slave_xfer_len = AST_I2C_DMA_SIZE;
+- else
++ else
+ i2c_dev->slave_xfer_len = i2c_dev->slave_msgs->len;
+-
++
+ dev_dbg(i2c_dev->dev, "(<--) slave tx DMA \n");
+ for(i=0; i<i2c_dev->slave_xfer_len; i++)
+ i2c_dev->dma_buf[i] = i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt + i];
+-
++
+ ast_i2c_write(i2c_dev, i2c_dev->dma_addr, I2C_DMA_BASE_REG);
+ ast_i2c_write(i2c_dev, (i2c_dev->slave_xfer_len-1), I2C_DMA_LEN_REG);
+- ast_i2c_write(i2c_dev, AST_I2CD_TX_DMA_ENABLE | AST_I2CD_S_TX_CMD,I2C_CMD_REG);
++ ast_i2c_write(i2c_dev, AST_I2CD_TX_DMA_ENABLE | AST_I2CD_S_TX_CMD,I2C_CMD_REG);
+ } else {
+ //DMA prepare rx
+ dev_dbg(i2c_dev->dev, "(-->) slave rx DMA \n");
+ ast_i2c_write(i2c_dev, i2c_dev->dma_addr, I2C_DMA_BASE_REG);
+ ast_i2c_write(i2c_dev, (AST_I2C_DMA_SIZE-1), I2C_DMA_LEN_REG);
+- ast_i2c_write(i2c_dev, AST_I2CD_RX_DMA_ENABLE, I2C_CMD_REG);
++ ast_i2c_write(i2c_dev, AST_I2CD_RX_DMA_ENABLE, I2C_CMD_REG);
+ }
+ } else {
+ dev_dbg(i2c_dev->dev,"M cnt %d, xf len %d \n",i2c_dev->master_xfer_cnt, i2c_dev->master_msgs->len);
+ if(i2c_dev->master_xfer_cnt == -1) {
+- //send start
++ //send start
+ dev_dbg(i2c_dev->dev, " %sing %d byte%s %s 0x%02x\n",
+ i2c_dev->master_msgs->flags & I2C_M_RD ? "read" : "write",
+ i2c_dev->master_msgs->len, i2c_dev->master_msgs->len > 1 ? "s" : "",
+ i2c_dev->master_msgs->flags & I2C_M_RD ? "from" : "to", i2c_dev->master_msgs->addr);
+
+ if(i2c_dev->master_msgs->flags & I2C_M_RD) {
+- //workaround .. HW can;t send start read addr with buff mode
++ //workaround .. HW can;t send start read addr with buff mode
+ cmd = AST_I2CD_M_START_CMD | AST_I2CD_M_TX_CMD;
+ ast_i2c_write(i2c_dev, (i2c_dev->master_msgs->addr <<1) |0x1, I2C_BYTE_BUF_REG);
+
+ // tx_buf[0] = (i2c_dev->master_msgs->addr <<1); //+1
+ i2c_dev->master_xfer_len = 1;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+ } else {
+ //tx
+- cmd = AST_I2CD_M_START_CMD | AST_I2CD_M_TX_CMD | AST_I2CD_TX_DMA_ENABLE;
++ cmd = AST_I2CD_M_START_CMD | AST_I2CD_M_TX_CMD | AST_I2CD_TX_DMA_ENABLE;
+
+ i2c_dev->dma_buf[0] = (i2c_dev->master_msgs->addr <<1); //+1
+ //next data write
+@@ -520,44 +552,44 @@ static void ast_i2c_do_dma_xfer(struct ast_i2c_dev *i2c_dev)
+ i2c_dev->master_xfer_len = AST_I2C_DMA_SIZE;
+ else
+ i2c_dev->master_xfer_len = i2c_dev->master_msgs->len + 1;
+-
++
+ for(i = 1; i < i2c_dev->master_xfer_len; i++)
+ i2c_dev->dma_buf[i] = i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt+i];
+-
++
+ if (i2c_dev->xfer_last == 1) {
+ dev_dbg(i2c_dev->dev, "last stop \n");
+ cmd |= AST_I2CD_M_STOP_CMD;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
+- ~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+-
++ ~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++
+ } else {
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+ }
+ ast_i2c_write(i2c_dev, i2c_dev->dma_addr, I2C_DMA_BASE_REG);
+ ast_i2c_write(i2c_dev, (i2c_dev->master_xfer_len-1), I2C_DMA_LEN_REG);
+-
++
+ }
+- ast_i2c_write(i2c_dev, cmd, I2C_CMD_REG);
++ ast_i2c_write(i2c_dev, cmd, I2C_CMD_REG);
+ dev_dbg(i2c_dev->dev, "txfer size %d , cmd = %x \n",i2c_dev->master_xfer_len, cmd);
+
+ } else if (i2c_dev->master_xfer_cnt < i2c_dev->master_msgs->len){
+- //Next send
++ //Next send
+ if(i2c_dev->master_msgs->flags & I2C_M_RD) {
+ //Rx data
+ cmd = AST_I2CD_M_RX_CMD | AST_I2CD_RX_DMA_ENABLE;
+-
++
+ if((i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt) > AST_I2C_DMA_SIZE) {
+ i2c_dev->master_xfer_len = AST_I2C_DMA_SIZE;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+ AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+-
++
+ } else {
+ i2c_dev->master_xfer_len = i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt;
+ if((i2c_dev->master_msgs->flags & I2C_M_RECV_LEN) && (i2c_dev->blk_r_flag == 0)) {
+ dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN \n");
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
++ AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+ } else {
+ #ifdef CONFIG_AST1010
+ //Workaround for ast1010 can't send NACK
+@@ -568,7 +600,7 @@ static void ast_i2c_do_dma_xfer(struct ast_i2c_dev *i2c_dev)
+ i2c_dev->master_xfer_mode = BYTE_XFER;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
+ ~AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+-
++
+ } else if (i2c_dev->master_xfer_len > 1) {
+ i2c_dev->master_xfer_len -=1;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+@@ -578,8 +610,8 @@ static void ast_i2c_do_dma_xfer(struct ast_i2c_dev *i2c_dev)
+ }
+ #else
+ if(i2c_dev->xfer_last == 1) {
+- dev_dbg(i2c_dev->dev, "last stop \n");
+- cmd |= AST_I2CD_M_STOP_CMD;
++ dev_dbg(i2c_dev->dev, "last stop \n");
++ cmd |= AST_I2CD_M_STOP_CMD;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
+ ~AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+ } else {
+@@ -588,9 +620,9 @@ static void ast_i2c_do_dma_xfer(struct ast_i2c_dev *i2c_dev)
+ }
+ //TODO check....
+ cmd |= AST_I2CD_M_S_RX_CMD_LAST;
+-#endif
++#endif
+ }
+-
++
+ }
+ ast_i2c_write(i2c_dev, i2c_dev->dma_addr, I2C_DMA_BASE_REG);
+ ast_i2c_write(i2c_dev, i2c_dev->master_xfer_len-1, I2C_DMA_LEN_REG);
+@@ -603,23 +635,23 @@ static void ast_i2c_do_dma_xfer(struct ast_i2c_dev *i2c_dev)
+ if((i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt) > AST_I2C_DMA_SIZE) {
+ i2c_dev->master_xfer_len = AST_I2C_DMA_SIZE;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+-
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++
+ } else {
+ i2c_dev->master_xfer_len = i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt;
+ if(i2c_dev->xfer_last == 1) {
+ dev_dbg(i2c_dev->dev, "last stop \n");
+ cmd |= AST_I2CD_M_STOP_CMD;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
+- ~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+-
++ ~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++
+ } else {
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+ }
+ }
+
+- for(i = 0; i < i2c_dev->master_xfer_len; i++)
++ for(i = 0; i < i2c_dev->master_xfer_len; i++)
+ i2c_dev->dma_buf[i] = i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt + i];
+
+ ast_i2c_write(i2c_dev, i2c_dev->dma_addr, I2C_DMA_BASE_REG);
+@@ -627,33 +659,33 @@ static void ast_i2c_do_dma_xfer(struct ast_i2c_dev *i2c_dev)
+ ast_i2c_write(i2c_dev, cmd , I2C_CMD_REG);
+ dev_dbg(i2c_dev->dev, "txfer size %d , cmd = %x \n",i2c_dev->master_xfer_len, cmd);
+
+- }
++ }
+ }else {
+- //should send next msg
++ //should send next msg
+ if(i2c_dev->master_xfer_cnt != i2c_dev->master_msgs->len)
+ printk("complete rx ... bus=%d addr=0x%x (%d vs. %d) ERROR\n",
+ i2c_dev->bus_id, i2c_dev->master_msgs->addr,
+ i2c_dev->master_xfer_cnt, i2c_dev->master_msgs->len);
+-
++
+ dev_dbg(i2c_dev->dev, "ast_i2c_do_byte_xfer complete \n");
+ i2c_dev->cmd_err = 0;
+- complete(&i2c_dev->cmd_complete);
++ complete(&i2c_dev->cmd_complete);
+ }
+-
++
+ }
+
+-
++
+ }
+
+-static void ast_i2c_do_pool_xfer(struct ast_i2c_dev *i2c_dev)
++static void ast_i2c_do_pool_xfer(struct ast_i2c_dev *i2c_dev)
+ {
+ u32 cmd = 0;
+ int i;
+ u32 *tx_buf;
+
+ i2c_dev->master_xfer_mode = BUFF_XFER;
+- i2c_dev->slave_xfer_mode = BUFF_XFER;
+-
++ i2c_dev->slave_xfer_mode = BUFF_XFER;
++
+ #if defined(CONFIG_ARCH_AST2400)
+ ast_i2c_write(i2c_dev,
+ (ast_i2c_read(i2c_dev, I2C_FUN_CTRL_REG) &
+@@ -665,15 +697,15 @@ static void ast_i2c_do_pool_xfer(struct ast_i2c_dev *i2c_dev)
+ tx_buf = (u32 *) i2c_dev->req_page->page_addr;
+
+
+- if(i2c_dev->slave_operation == 1) {
++ if(i2c_dev->slave_operation == 1) {
+ if(i2c_dev->slave_msgs->flags & I2C_M_RD) {
+ dev_dbg(i2c_dev->dev, "(<--) slave tx buf \n");
+-
++
+ if(i2c_dev->slave_msgs->len > i2c_dev->req_page->page_size)
+ i2c_dev->slave_xfer_len = i2c_dev->req_page->page_size;
+ else
+ i2c_dev->slave_xfer_len = i2c_dev->slave_msgs->len;
+-
++
+ for(i = 0; i< i2c_dev->slave_xfer_len; i++) {
+ if(i%4 == 0)
+ tx_buf[i/4] = 0;
+@@ -681,80 +713,80 @@ static void ast_i2c_do_pool_xfer(struct ast_i2c_dev *i2c_dev)
+ dev_dbg(i2c_dev->dev, "[%x] ",tx_buf[i/4]);
+ }
+ dev_dbg(i2c_dev->dev, "\n");
+-
+- ast_i2c_write(i2c_dev, AST_I2CD_TX_DATA_BUF_END_SET((i2c_dev->slave_xfer_len-1)) |
+- AST_I2CD_BUF_BASE_ADDR_SET((i2c_dev->req_page->page_addr_point)),
++
++ ast_i2c_write(i2c_dev, AST_I2CD_TX_DATA_BUF_END_SET((i2c_dev->slave_xfer_len-1)) |
++ AST_I2CD_BUF_BASE_ADDR_SET((i2c_dev->req_page->page_addr_point)),
+ I2C_BUF_CTRL_REG);
+-
++
+ ast_i2c_write(i2c_dev, AST_I2CD_TX_BUFF_ENABLE | AST_I2CD_S_TX_CMD, I2C_CMD_REG);
+ } else {
+ //prepare for new rx
+ dev_dbg(i2c_dev->dev, "(-->) slave prepare rx buf \n");
+- ast_i2c_write(i2c_dev,
++ ast_i2c_write(i2c_dev,
+ AST_I2CD_RX_BUF_END_ADDR_SET((i2c_dev->req_page->page_size-1)) |
+ AST_I2CD_BUF_BASE_ADDR_SET((i2c_dev->req_page->page_addr_point)),
+ I2C_BUF_CTRL_REG);
+
+- ast_i2c_write(i2c_dev, AST_I2CD_RX_BUFF_ENABLE, I2C_CMD_REG);
+-
++ ast_i2c_write(i2c_dev, AST_I2CD_RX_BUFF_ENABLE, I2C_CMD_REG);
++
+ }
+ } else {
+ dev_dbg(i2c_dev->dev,"M cnt %d, xf len %d \n",i2c_dev->master_xfer_cnt, i2c_dev->master_msgs->len);
+ if(i2c_dev->master_xfer_cnt == -1) {
+- //send start
++ //send start
+ dev_dbg(i2c_dev->dev, " %sing %d byte%s %s 0x%02x\n",
+ i2c_dev->master_msgs->flags & I2C_M_RD ? "read" : "write",
+ i2c_dev->master_msgs->len, i2c_dev->master_msgs->len > 1 ? "s" : "",
+ i2c_dev->master_msgs->flags & I2C_M_RD ? "from" : "to", i2c_dev->master_msgs->addr);
+
+ if(i2c_dev->master_msgs->flags & I2C_M_RD) {
+-//workaround .. HW can;t send start read addr with buff mode
++//workaround .. HW can;t send start read addr with buff mode
+ cmd = AST_I2CD_M_START_CMD | AST_I2CD_M_TX_CMD;
+ ast_i2c_write(i2c_dev, (i2c_dev->master_msgs->addr <<1) |0x1, I2C_BYTE_BUF_REG);
+
+ // tx_buf[0] = (i2c_dev->master_msgs->addr <<1); //+1
+ i2c_dev->master_xfer_len = 1;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+ } else {
+- cmd = AST_I2CD_M_START_CMD | AST_I2CD_M_TX_CMD | AST_I2CD_TX_BUFF_ENABLE;
++ cmd = AST_I2CD_M_START_CMD | AST_I2CD_M_TX_CMD | AST_I2CD_TX_BUFF_ENABLE;
+ tx_buf[0] = (i2c_dev->master_msgs->addr <<1); //+1
+ //next data write
+ if((i2c_dev->master_msgs->len + 1) > i2c_dev->req_page->page_size)
+ i2c_dev->master_xfer_len = i2c_dev->req_page->page_size;
+ else
+ i2c_dev->master_xfer_len = i2c_dev->master_msgs->len + 1;
+-
++
+ for(i = 1; i < i2c_dev->master_xfer_len; i++) {
+ if(i%4 == 0)
+ tx_buf[i/4] = 0;
+ tx_buf[i/4] |= (i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt + i] << ((i%4)*8)) ;
+ }
+-
++
+ if (i2c_dev->xfer_last == 1) {
+ dev_dbg(i2c_dev->dev, "last stop \n");
+ cmd |= AST_I2CD_M_STOP_CMD;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
+- ~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+-
++ ~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++
+ } else {
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+ }
+- ast_i2c_write(i2c_dev,
++ ast_i2c_write(i2c_dev,
+ AST_I2CD_TX_DATA_BUF_END_SET((i2c_dev->master_xfer_len - 1)) |
+ AST_I2CD_BUF_BASE_ADDR_SET(i2c_dev->req_page->page_addr_point),
+ I2C_BUF_CTRL_REG);
+ }
+- ast_i2c_write(i2c_dev, cmd, I2C_CMD_REG);
++ ast_i2c_write(i2c_dev, cmd, I2C_CMD_REG);
+ dev_dbg(i2c_dev->dev, "txfer size %d , cmd = %x \n",i2c_dev->master_xfer_len, cmd);
+
+ } else if (i2c_dev->master_xfer_cnt < i2c_dev->master_msgs->len){
+- //Next send
++ //Next send
+ if(i2c_dev->master_msgs->flags & I2C_M_RD) {
+ //Rx data
+ cmd = AST_I2CD_M_RX_CMD | AST_I2CD_RX_BUFF_ENABLE;
+-
++
+ if((i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt) > i2c_dev->req_page->page_size) {
+ i2c_dev->master_xfer_len = i2c_dev->req_page->page_size;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+@@ -764,11 +796,11 @@ static void ast_i2c_do_pool_xfer(struct ast_i2c_dev *i2c_dev)
+ if((i2c_dev->master_msgs->flags & I2C_M_RECV_LEN) && (i2c_dev->blk_r_flag == 0)) {
+ dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN \n");
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
++ AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+ } else {
+ if(i2c_dev->xfer_last == 1) {
+- dev_dbg(i2c_dev->dev, "last stop \n");
+- cmd |= AST_I2CD_M_STOP_CMD;
++ dev_dbg(i2c_dev->dev, "last stop \n");
++ cmd |= AST_I2CD_M_STOP_CMD;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
+ ~AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+ } else {
+@@ -791,46 +823,46 @@ static void ast_i2c_do_pool_xfer(struct ast_i2c_dev *i2c_dev)
+ if((i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt) > i2c_dev->req_page->page_size) {
+ i2c_dev->master_xfer_len = i2c_dev->req_page->page_size;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+-
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++
+ } else {
+ i2c_dev->master_xfer_len = i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt;
+ if(i2c_dev->xfer_last == 1) {
+ dev_dbg(i2c_dev->dev, "last stop \n");
+ cmd |= AST_I2CD_M_STOP_CMD;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
+- ~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+-
++ ~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++
+ } else {
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+ }
+ }
+-
++
+ for(i = 0; i < i2c_dev->master_xfer_len; i++) {
+ if(i%4 == 0)
+ tx_buf[i/4] = 0;
+ tx_buf[i/4] |= (i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt + i] << ((i%4)*8)) ;
+ }
+-// printk("count %x \n",ast_i2c_read(i2c_dev,I2C_CMD_REG));
+- ast_i2c_write(i2c_dev,
++// printk("count %x \n",ast_i2c_read(i2c_dev,I2C_CMD_REG));
++ ast_i2c_write(i2c_dev,
+ AST_I2CD_TX_DATA_BUF_END_SET((i2c_dev->master_xfer_len - 1)) |
+ AST_I2CD_BUF_BASE_ADDR_SET(i2c_dev->req_page->page_addr_point),
+ I2C_BUF_CTRL_REG);
+-
++
+ ast_i2c_write(i2c_dev, cmd , I2C_CMD_REG);
+ dev_dbg(i2c_dev->dev, "txfer size %d , cmd = %x \n",i2c_dev->master_xfer_len, cmd);
+ }
+ } else {
+- //should send next msg
++ //should send next msg
+ if(i2c_dev->master_xfer_cnt != i2c_dev->master_msgs->len)
+ printk("complete rx ... bus=%d addr=0x%x (%d vs. %d) ERROR\n",
+ i2c_dev->bus_id, i2c_dev->master_msgs->addr,
+ i2c_dev->master_xfer_cnt, i2c_dev->master_msgs->len);
+-
++
+ dev_dbg(i2c_dev->dev, "ast_i2c_do_byte_xfer complete \n");
+ i2c_dev->cmd_err = 0;
+- complete(&i2c_dev->cmd_complete);
++ complete(&i2c_dev->cmd_complete);
+ }
+
+ }
+@@ -843,16 +875,16 @@ static void ast_i2c_do_byte_xfer(struct ast_i2c_dev *i2c_dev)
+ i2c_dev->master_xfer_mode = BYTE_XFER;
+ i2c_dev->master_xfer_len = 1;
+
+- i2c_dev->slave_xfer_mode = BYTE_XFER;
++ i2c_dev->slave_xfer_mode = BYTE_XFER;
+ i2c_dev->slave_xfer_len = 1;
+-
+- if(i2c_dev->slave_operation == 1) {
++
++ if(i2c_dev->slave_operation == 1) {
+ dev_dbg(i2c_dev->dev,"S cnt %d, xf len %d \n",i2c_dev->slave_xfer_cnt, i2c_dev->slave_msgs->len);
+ if(i2c_dev->slave_msgs->flags & I2C_M_RD) {
+ //READ <-- TX
+ dev_dbg(i2c_dev->dev, "(<--) slave(tx) buf %d [%x]\n", i2c_dev->slave_xfer_cnt, i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt]);
+ ast_i2c_write(i2c_dev, i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt], I2C_BYTE_BUF_REG);
+- ast_i2c_write(i2c_dev, AST_I2CD_S_TX_CMD, I2C_CMD_REG);
++ ast_i2c_write(i2c_dev, AST_I2CD_S_TX_CMD, I2C_CMD_REG);
+ } else {
+ // Write -->Rx
+ //no need to handle in byte mode
+@@ -862,21 +894,21 @@ static void ast_i2c_do_byte_xfer(struct ast_i2c_dev *i2c_dev)
+ } else {
+ dev_dbg(i2c_dev->dev,"M cnt %d, xf len %d \n",i2c_dev->master_xfer_cnt, i2c_dev->master_msgs->len);
+ if(i2c_dev->master_xfer_cnt == -1) {
+- //first start
++ //first start
+ dev_dbg(i2c_dev->dev, " %sing %d byte%s %s 0x%02x\n",
+ i2c_dev->master_msgs->flags & I2C_M_RD ? "read" : "write",
+ i2c_dev->master_msgs->len, i2c_dev->master_msgs->len > 1 ? "s" : "",
+ i2c_dev->master_msgs->flags & I2C_M_RD ? "from" : "to", i2c_dev->master_msgs->addr);
+-
+-
+- if(i2c_dev->master_msgs->flags & I2C_M_RD)
++
++
++ if(i2c_dev->master_msgs->flags & I2C_M_RD)
+ ast_i2c_write(i2c_dev, (i2c_dev->master_msgs->addr <<1) |0x1, I2C_BYTE_BUF_REG);
+ else
+ ast_i2c_write(i2c_dev, (i2c_dev->master_msgs->addr <<1), I2C_BYTE_BUF_REG);
+
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+-
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++
+ ast_i2c_write(i2c_dev, AST_I2CD_M_TX_CMD | AST_I2CD_M_START_CMD, I2C_CMD_REG);
+
+
+@@ -888,7 +920,7 @@ static void ast_i2c_do_byte_xfer(struct ast_i2c_dev *i2c_dev)
+ if((i2c_dev->master_msgs->flags & I2C_M_RECV_LEN) && (i2c_dev->master_xfer_cnt == 0)) {
+ dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN \n");
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
++ AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+
+ } else if((i2c_dev->xfer_last == 1) && (i2c_dev->master_xfer_cnt + 1 == i2c_dev->master_msgs->len)) {
+ cmd |= AST_I2CD_M_S_RX_CMD_LAST | AST_I2CD_M_STOP_CMD;
+@@ -897,11 +929,11 @@ static void ast_i2c_do_byte_xfer(struct ast_i2c_dev *i2c_dev)
+ ~AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+ } else {
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
++ AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+ }
+
+ dev_dbg(i2c_dev->dev, "(<--) rx byte, cmd = %x \n",cmd);
+-
++
+ ast_i2c_write(i2c_dev, cmd, I2C_CMD_REG);
+
+
+@@ -911,29 +943,29 @@ static void ast_i2c_do_byte_xfer(struct ast_i2c_dev *i2c_dev)
+ ast_i2c_write(i2c_dev, *(xfer_buf + i2c_dev->master_xfer_cnt), I2C_BYTE_BUF_REG);
+ if((i2c_dev->xfer_last == 1) && (i2c_dev->master_xfer_cnt + 1 == i2c_dev->master_msgs->len)) {
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
+- ~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++ ~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+ ast_i2c_write(i2c_dev, AST_I2CD_M_TX_CMD | AST_I2CD_M_STOP_CMD, I2C_CMD_REG);
+ } else {
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+ ast_i2c_write(i2c_dev, AST_I2CD_M_TX_CMD, I2C_CMD_REG);
+ }
+ }
+-
++
+ } else {
+- //should send next msg
++ //should send next msg
+ if(i2c_dev->master_xfer_cnt != i2c_dev->master_msgs->len)
+ printk("CNT ERROR bus=%d addr=0x%x (%d vs. %d)\n",
+ i2c_dev->bus_id, i2c_dev->master_msgs->addr,
+ i2c_dev->master_xfer_cnt, i2c_dev->master_msgs->len);
+-
++
+ dev_dbg(i2c_dev->dev, "ast_i2c_do_byte_xfer complete \n");
+ i2c_dev->cmd_err = 0;
+- complete(&i2c_dev->cmd_complete);
+-
++ complete(&i2c_dev->cmd_complete);
++
+ }
+ }
+-
++
+ }
+
+ static void ast_i2c_slave_xfer_done(struct ast_i2c_dev *i2c_dev)
+@@ -941,8 +973,8 @@ static void ast_i2c_slave_xfer_done(struct ast_i2c_dev *i2c_dev)
+ u32 xfer_len;
+ int i;
+ u8 *rx_buf;
+-
+- dev_dbg(i2c_dev->dev, "ast_i2c_slave_xfer_done [%d]\n",i2c_dev->slave_xfer_mode);
++
++ dev_dbg(i2c_dev->dev, "ast_i2c_slave_xfer_done [%d]\n",i2c_dev->slave_xfer_mode);
+
+ if (i2c_dev->slave_msgs->flags & I2C_M_RD) {
+ //tx done , only check tx count ...
+@@ -979,16 +1011,16 @@ static void ast_i2c_slave_xfer_done(struct ast_i2c_dev *i2c_dev)
+ xfer_len = AST_I2CD_RX_BUF_ADDR_GET(ast_i2c_read(i2c_dev, I2C_BUF_CTRL_REG));
+ if(xfer_len == 0)
+ xfer_len = AST_I2C_PAGE_SIZE;
+-
++
+ dev_dbg(i2c_dev->dev,"rx buff done len %d \n",xfer_len);
+-
++
+ rx_buf = (u8 *)i2c_dev->req_page->page_addr;
+-
++
+ for(i=0;i<xfer_len;i++) {
+ i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt+i] = rx_buf[i];
+ dev_dbg(i2c_dev->dev,"%d, [%x] \n",i2c_dev->slave_xfer_cnt+i ,i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt+i]);
+ }
+-
++
+ } else {
+ //RX DMA DOWN
+ xfer_len = ast_i2c_read(i2c_dev, I2C_DMA_LEN_REG);
+@@ -996,15 +1028,15 @@ static void ast_i2c_slave_xfer_done(struct ast_i2c_dev *i2c_dev)
+ xfer_len = i2c_dev->slave_xfer_len;
+ else
+ xfer_len = i2c_dev->slave_xfer_len - xfer_len - 1;
+-
++
+ dev_dbg(i2c_dev->dev, " rx dma done len %d \n", xfer_len);
+-
++
+ for(i=0;i<xfer_len;i++) {
+ i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt+i] = i2c_dev->dma_buf[i];
+ dev_dbg(i2c_dev->dev,"%d, [%x] \n",i2c_dev->slave_xfer_cnt+i ,i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt+i]);
+ }
+ }
+-
++
+ }
+
+ if(xfer_len !=i2c_dev->slave_xfer_len) {
+@@ -1012,7 +1044,7 @@ static void ast_i2c_slave_xfer_done(struct ast_i2c_dev *i2c_dev)
+ printk(" **slave xfer error ====\n");
+ //should goto stop....
+ } else
+- i2c_dev->slave_xfer_cnt += i2c_dev->slave_xfer_len;
++ i2c_dev->slave_xfer_cnt += i2c_dev->slave_xfer_len;
+
+
+ if((i2c_dev->slave_event == I2C_SLAVE_EVENT_NACK) || (i2c_dev->slave_event == I2C_SLAVE_EVENT_STOP)) {
+@@ -1020,33 +1052,33 @@ static void ast_i2c_slave_xfer_done(struct ast_i2c_dev *i2c_dev)
+ ast_i2c_slave_rdwr_xfer(i2c_dev);
+ #else
+ i2c_dev->ast_i2c_data->slave_xfer(i2c_dev->slave_event, &(i2c_dev->slave_msgs));
+-#endif
++#endif
+ i2c_dev->slave_xfer_cnt = 0;
+ } else {
+ if(i2c_dev->slave_xfer_cnt == i2c_dev->slave_msgs->len) {
+- dev_dbg(i2c_dev->dev,"slave next msgs \n");
++ dev_dbg(i2c_dev->dev,"slave next msgs \n");
+ #ifdef CONFIG_AST_I2C_SLAVE_RDWR
+ ast_i2c_slave_rdwr_xfer(i2c_dev);
+ #else
+ i2c_dev->ast_i2c_data->slave_xfer(i2c_dev->slave_event, &(i2c_dev->slave_msgs));
+-#endif
++#endif
+
+ i2c_dev->slave_xfer_cnt = 0;
+- }
++ }
+ i2c_dev->do_slave_xfer(i2c_dev);
+ }
+
+
+ if(AST_I2CD_IDLE == i2c_dev->state) {
+- dev_dbg(i2c_dev->dev,"** Slave go IDLE **\n");
++ dev_dbg(i2c_dev->dev,"** Slave go IDLE **\n");
+ i2c_dev->slave_operation = 0;
+-
++
+ if(i2c_dev->slave_xfer_mode == BUFF_XFER) {
+ i2c_dev->ast_i2c_data->free_pool_buff_page(i2c_dev->req_page);
+- }
+-
+- }
+-
++ }
++
++ }
++
+ }
+
+ //TX/Rx Done
+@@ -1057,7 +1089,7 @@ static void ast_i2c_master_xfer_done(struct ast_i2c_dev *i2c_dev)
+ u8 *pool_buf;
+ unsigned long flags;
+
+- spin_lock_irqsave(&g_master_lock, flags);
++ spin_lock_irqsave(&i2c_dev->master_lock, flags);
+
+ /*
+ * This function shall be involked during interrupt handling.
+@@ -1068,8 +1100,8 @@ static void ast_i2c_master_xfer_done(struct ast_i2c_dev *i2c_dev)
+ goto unlock_out;
+ }
+
+- dev_dbg(i2c_dev->dev, "ast_i2c_master_xfer_done mode[%d]\n",i2c_dev->master_xfer_mode);
+-
++ dev_dbg(i2c_dev->dev, "ast_i2c_master_xfer_done mode[%d]\n",i2c_dev->master_xfer_mode);
++
+ if (i2c_dev->master_msgs->flags & I2C_M_RD) {
+ if(i2c_dev->master_xfer_cnt == -1) {
+ xfer_len = 1;
+@@ -1077,16 +1109,16 @@ static void ast_i2c_master_xfer_done(struct ast_i2c_dev *i2c_dev)
+ }
+ if(i2c_dev->master_xfer_mode == BYTE_XFER) {
+ if ((i2c_dev->master_msgs->flags & I2C_M_RECV_LEN) && (i2c_dev->blk_r_flag == 0)) {
+- i2c_dev->master_msgs->len += (ast_i2c_read(i2c_dev,I2C_BYTE_BUF_REG) & AST_I2CD_RX_BYTE_BUFFER) >> 8;
++ i2c_dev->master_msgs->len += (ast_i2c_read(i2c_dev,I2C_BYTE_BUF_REG) & AST_I2CD_RX_BYTE_BUFFER) >> 8;
+ i2c_dev->blk_r_flag = 1;
+- dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN %d \n", i2c_dev->master_msgs->len -1);
++ dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN %d \n", i2c_dev->master_msgs->len -1);
+ }
+ xfer_len = 1;
+ i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt] = (ast_i2c_read(i2c_dev,I2C_BYTE_BUF_REG) & AST_I2CD_RX_BYTE_BUFFER) >> 8;
+ } else if (i2c_dev->master_xfer_mode == BUFF_XFER) {
+ pool_buf = (u8 *)i2c_dev->req_page->page_addr;
+ xfer_len = AST_I2CD_RX_BUF_ADDR_GET(ast_i2c_read(i2c_dev, I2C_BUF_CTRL_REG));
+-
++
+ if(xfer_len == 0)
+ xfer_len = AST_I2C_PAGE_SIZE;
+
+@@ -1098,7 +1130,7 @@ static void ast_i2c_master_xfer_done(struct ast_i2c_dev *i2c_dev)
+ if ((i2c_dev->master_msgs->flags & I2C_M_RECV_LEN) && (i2c_dev->blk_r_flag == 0)) {
+ i2c_dev->master_msgs->len += pool_buf[0];
+ i2c_dev->blk_r_flag = 1;
+- dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN %d \n", i2c_dev->master_msgs->len -1);
++ dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN %d \n", i2c_dev->master_msgs->len -1);
+ }
+ } else {
+ //DMA Mode
+@@ -1114,13 +1146,13 @@ static void ast_i2c_master_xfer_done(struct ast_i2c_dev *i2c_dev)
+ dev_dbg(i2c_dev->dev, "buf[%x] \n", i2c_dev->dma_buf[i]);
+ dev_dbg(i2c_dev->dev, "buf[%x] \n", i2c_dev->dma_buf[i+1]);
+ }
+-
++
+ if ((i2c_dev->master_msgs->flags & I2C_M_RECV_LEN) && (i2c_dev->blk_r_flag == 0)) {
+ i2c_dev->master_msgs->len += i2c_dev->dma_buf[0];
+ i2c_dev->blk_r_flag = 1;
+- dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN %d \n", i2c_dev->master_msgs->len -1);
++ dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN %d \n", i2c_dev->master_msgs->len -1);
+ }
+-
++
+ }
+
+ }else {
+@@ -1153,28 +1185,28 @@ next_xfer:
+ i2c_dev->cmd_err = 1;
+ goto done_out;
+ } else
+- i2c_dev->master_xfer_cnt += i2c_dev->master_xfer_len;
++ i2c_dev->master_xfer_cnt += i2c_dev->master_xfer_len;
+
+ if(i2c_dev->master_xfer_cnt != i2c_dev->master_msgs->len) {
+ dev_dbg(i2c_dev->dev,"do next cnt \n");
+ i2c_dev->do_master_xfer(i2c_dev);
+ } else {
+-#if 0
+- int i;
++#if 0
++ int i;
+ printk(" ===== \n");
+ for(i=0;i<i2c_dev->master_msgs->len;i++)
+ printk("rx buf i,[%x]\n",i,i2c_dev->master_msgs->buf[i]);
+- printk(" ===== \n");
+-#endif
++ printk(" ===== \n");
++#endif
+ i2c_dev->cmd_err = 0;
+
+ done_out:
+ dev_dbg(i2c_dev->dev,"msgs complete \n");
+- complete(&i2c_dev->cmd_complete);
++ complete(&i2c_dev->cmd_complete);
+ }
+
+ unlock_out:
+- spin_unlock_irqrestore(&g_master_lock, flags);
++ spin_unlock_irqrestore(&i2c_dev->master_lock, flags);
+ }
+
+ static void ast_i2c_slave_addr_match(struct ast_i2c_dev *i2c_dev)
+@@ -1187,7 +1219,7 @@ static void ast_i2c_slave_addr_match(struct ast_i2c_dev *i2c_dev)
+ i2c_dev->slave_msgs->buf[0] = match;
+ dev_dbg(i2c_dev->dev, "S Start Addr match [%x] \n",match);
+
+-
++
+ if(match & 1) {
+ i2c_dev->slave_event = I2C_SLAVE_EVENT_START_READ;
+ } else {
+@@ -1201,7 +1233,7 @@ static void ast_i2c_slave_addr_match(struct ast_i2c_dev *i2c_dev)
+ #else
+ i2c_dev->ast_i2c_data->slave_xfer(i2c_dev->slave_event, &(i2c_dev->slave_msgs));
+ i2c_dev->slave_xfer_cnt = 0;
+-#endif
++#endif
+
+ //request
+ if(i2c_dev->ast_i2c_data->slave_dma == BYTE_MODE)
+@@ -1211,7 +1243,7 @@ static void ast_i2c_slave_addr_match(struct ast_i2c_dev *i2c_dev)
+ else {
+ if(i2c_dev->ast_i2c_data->request_pool_buff_page(&(i2c_dev->req_page)) == 0)
+ i2c_dev->do_slave_xfer = ast_i2c_do_pool_xfer;
+- else
++ else
+ i2c_dev->do_slave_xfer = ast_i2c_do_byte_xfer;
+ }
+
+@@ -1221,7 +1253,7 @@ static void ast_i2c_slave_addr_match(struct ast_i2c_dev *i2c_dev)
+
+ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+ {
+- u32 sts;
++ u32 sts;
+
+ struct ast_i2c_dev *i2c_dev = dev_id;
+ u32 isr_sts = readl(i2c_dev->ast_i2c_data->reg_gr);
+@@ -1231,7 +1263,7 @@ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+
+ i2c_dev->state = (ast_i2c_read(i2c_dev,I2C_CMD_REG) >> 19) & 0xf;
+ sts = ast_i2c_read(i2c_dev,I2C_INTR_STS_REG);
+-// printk("ISR : %x , sts [%x]\n",sts , xfer_sts);
++// printk("ISR : %x , sts [%x]\n",sts , xfer_sts);
+ // dev_dbg(i2c_dev->dev,"ISR : %x , sts [%x]\n",sts , xfer_sts);
+
+ // dev_dbg(i2c_dev->dev,"sts machine %x, slave_op %d \n", xfer_sts,i2c_dev->slave_operation);
+@@ -1244,9 +1276,9 @@ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+ I2C_INTR_CTRL_REG);
+ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_SMBUS_ALT, I2C_INTR_STS_REG);
+ ast_master_alert_recv(i2c_dev);
+- sts &= ~AST_I2CD_SMBUS_ALT_INTR_EN;
++ sts &= ~AST_I2CD_SMBUS_ALT_INTR_EN;
+ }
+-
++
+ if(AST_I2CD_INTR_STS_ABNORMAL & sts) {
+ i2c_dev->cmd_err |= AST_I2CD_INTR_STS_ABNORMAL;
+ // Turn off interrupts for further abnormal
+@@ -1257,6 +1289,8 @@ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+ I2C_INTR_CTRL_REG);
+ complete(&i2c_dev->cmd_complete);
+ sts &= ~AST_I2CD_INTR_STS_ABNORMAL;
++ // Need to clear the interrupt
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_ABNORMAL, I2C_INTR_STS_REG);
+ }
+
+ switch(sts) {
+@@ -1265,7 +1299,7 @@ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+ i2c_dev->slave_event = I2C_SLAVE_EVENT_READ;
+ ast_i2c_slave_xfer_done(i2c_dev);
+ dev_dbg(i2c_dev->dev, "S clear isr: AST_I2CD_INTR_STS_TX_ACK = %x\n",sts);
+- ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_ACK, I2C_INTR_STS_REG);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_ACK, I2C_INTR_STS_REG);
+ } else {
+ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_TX_ACK = %x\n",sts);
+ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_ACK, I2C_INTR_STS_REG);
+@@ -1280,9 +1314,17 @@ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+ ast_i2c_master_xfer_done(i2c_dev);
+-
++
+ } else {
+- printk("TODO ...\n");
++ printk("ast_i2c: TX_ACK | NORMAL_STOP; xfer_last %d\n", i2c_dev->xfer_last);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_ACK | AST_I2CD_INTR_STS_NORMAL_STOP, I2C_INTR_STS_REG);
++ uint32_t new_val = ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
++ AST_I2CD_NORMAL_STOP_INTR_EN |
++ AST_I2CD_TX_ACK_INTR_EN;
++ ast_i2c_write(i2c_dev, new_val, I2C_INTR_CTRL_REG);
++ //take care
++ i2c_dev->cmd_err |= AST_LOCKUP_DETECTED;
++ complete(&i2c_dev->cmd_complete);
+ }
+ break;
+
+@@ -1291,8 +1333,8 @@ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+ i2c_dev->slave_event = I2C_SLAVE_EVENT_NACK;
+ ast_i2c_slave_xfer_done(i2c_dev);
+ dev_dbg(i2c_dev->dev, "S clear isr: AST_I2CD_INTR_STS_TX_NAK = %x\n",sts);
+- ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_NAK, I2C_INTR_STS_REG);
+-
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_NAK, I2C_INTR_STS_REG);
++
+ } else {
+ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_TX_NAK = %x\n",sts);
+ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_NAK, I2C_INTR_STS_REG);
+@@ -1310,7 +1352,7 @@ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+ case AST_I2CD_INTR_STS_TX_NAK | AST_I2CD_INTR_STS_NORMAL_STOP:
+ if(i2c_dev->slave_operation == 1) {
+ printk("SLAVE TODO .... \n");
+-
++
+ } else {
+ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_TX_NAK| AST_I2CD_INTR_STS_NORMAL_STOP = %x\n",sts);
+ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_NAK | AST_I2CD_INTR_STS_NORMAL_STOP, I2C_INTR_STS_REG);
+@@ -1320,47 +1362,47 @@ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+ }
+ break;
+
+- //Issue : Workaround for I2C slave mode
++ //Issue : Workaround for I2C slave mode
+ case AST_I2CD_INTR_STS_TX_NAK | AST_I2CD_INTR_STS_SLAVE_MATCH:
+ if(i2c_dev->slave_operation == 1) {
+ i2c_dev->slave_event = I2C_SLAVE_EVENT_NACK;
+ ast_i2c_slave_xfer_done(i2c_dev);
+ ast_i2c_slave_addr_match(i2c_dev);
+- ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_NAK | AST_I2CD_INTR_STS_SLAVE_MATCH , I2C_INTR_STS_REG);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_NAK | AST_I2CD_INTR_STS_SLAVE_MATCH , I2C_INTR_STS_REG);
+ } else {
+ printk("ERROR !!!!\n");
+ }
+ break;
+ case AST_I2CD_INTR_STS_RX_DOWN | AST_I2CD_INTR_STS_SLAVE_MATCH:
+ ast_i2c_slave_addr_match(i2c_dev);
+- dev_dbg(i2c_dev->dev, "S clear isr: AST_I2CD_INTR_STS_RX_DOWN | AST_I2CD_INTR_STS_SLAVE_MATCH = %x\n",sts);
++ dev_dbg(i2c_dev->dev, "S clear isr: AST_I2CD_INTR_STS_RX_DOWN | AST_I2CD_INTR_STS_SLAVE_MATCH = %x\n",sts);
+ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_RX_DOWN | AST_I2CD_INTR_STS_SLAVE_MATCH, I2C_INTR_STS_REG);
+ break;
+-
++
+ case AST_I2CD_INTR_STS_RX_DOWN:
+ if(i2c_dev->slave_operation == 1) {
+ i2c_dev->slave_event = I2C_SLAVE_EVENT_WRITE;
+ ast_i2c_slave_xfer_done(i2c_dev);
+ dev_dbg(i2c_dev->dev, "S clear isr: AST_I2CD_INTR_STS_RX_DOWN = %x\n",sts);
+- ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_RX_DOWN, I2C_INTR_STS_REG);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_RX_DOWN, I2C_INTR_STS_REG);
+ } else {
+ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_RX_DOWN = %x\n",sts);
+ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_RX_DOWN, I2C_INTR_STS_REG);
+ ast_i2c_master_xfer_done(i2c_dev);
+-
++
+ }
+ break;
+-
++
+ case AST_I2CD_INTR_STS_NORMAL_STOP:
+ if(i2c_dev->slave_operation == 1) {
+ i2c_dev->slave_event = I2C_SLAVE_EVENT_STOP;
+ ast_i2c_slave_xfer_done(i2c_dev);
+ dev_dbg(i2c_dev->dev, "S clear isr: AST_I2CD_INTR_STS_NORMAL_STOP = %x\n",sts);
+- ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_NORMAL_STOP, I2C_INTR_STS_REG);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_NORMAL_STOP, I2C_INTR_STS_REG);
+ dev_dbg(i2c_dev->dev, "state [%x] \n",i2c_dev->state);
+- } else {
++ } else {
+ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_NORMAL_STOP = %x\n",sts);
+- ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_NORMAL_STOP, I2C_INTR_STS_REG);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_NORMAL_STOP, I2C_INTR_STS_REG);
+ i2c_dev->cmd_err |= AST_I2CD_INTR_STS_NORMAL_STOP;
+ complete(&i2c_dev->cmd_complete);
+ }
+@@ -1380,24 +1422,24 @@ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_ARBIT_LOSS = %x\n",sts);
+ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_ARBIT_LOSS, I2C_INTR_STS_REG);
+ i2c_dev->cmd_err |= AST_I2CD_INTR_STS_ARBIT_LOSS;
+- complete(&i2c_dev->cmd_complete);
++ complete(&i2c_dev->cmd_complete);
+ break;
+ case AST_I2CD_INTR_STS_SCL_TO:
+ i2c_dev->cmd_err |= AST_I2CD_INTR_STS_SCL_TO;
+- complete(&i2c_dev->cmd_complete);
+-
++ complete(&i2c_dev->cmd_complete);
++
+ break;
+ case AST_I2CD_INTR_STS_GCALL_ADDR:
+ i2c_dev->cmd_err |= AST_I2CD_INTR_STS_GCALL_ADDR;
+- complete(&i2c_dev->cmd_complete);
++ complete(&i2c_dev->cmd_complete);
+
+ break;
+ case AST_I2CD_INTR_STS_SMBUS_DEF_ADDR:
+ break;
+ case AST_I2CD_INTR_STS_SMBUS_DEV_ALT:
+-
++
+ break;
+-
++
+ case AST_I2CD_INTR_STS_SMBUS_ARP_ADDR:
+ break;
+ case AST_I2CD_INTR_STS_SDA_DL_TO:
+@@ -1405,25 +1447,50 @@ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+ case AST_I2CD_INTR_STS_BUS_RECOVER:
+ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_BUS_RECOVER= %x\n",sts);
+ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_BUS_RECOVER, I2C_INTR_STS_REG);
+- complete(&i2c_dev->cmd_complete);
++ complete(&i2c_dev->cmd_complete);
+ break;
+ default:
+- if(sts)
+- printk("GR %x : No one care : %x, bus_id %d\n",i2c_dev->ast_i2c_data->reg_gr, sts, i2c_dev->bus_id);
+- return IRQ_NONE;
++ //TODO: Clearing this interrupt for now, but needs to cleanup this ISR function
++ ast_i2c_write(i2c_dev, sts, I2C_INTR_STS_REG);
++
++ // Handle Arbitration Loss
++ if (sts & AST_I2CD_INTR_STS_ARBIT_LOSS) {
++ i2c_dev->cmd_err |= AST_I2CD_INTR_STS_ARBIT_LOSS;
++ complete(&i2c_dev->cmd_complete);
++ sts &= (~AST_I2CD_INTR_STS_ARBIT_LOSS);
++ }
++
++ // Handle the write transaction ACK
++ if (sts & AST_I2CD_INTR_STS_TX_ACK) {
++ ast_i2c_master_xfer_done(i2c_dev);
++ complete(&i2c_dev->cmd_complete);
++ sts &= (~AST_I2CD_INTR_STS_TX_ACK);
++ }
++
++ // Handle the Slave address match
++ if (sts & AST_I2CD_INTR_STS_SLAVE_MATCH) {
++ ast_i2c_slave_addr_match(i2c_dev);
++ sts &= (~AST_I2CD_INTR_STS_SLAVE_MATCH);
++ }
++
++ // TODO: Debug print for any unhandled condition
++ if(sts) {
++ printk("GR %x : Status : %x, bus_id %d\n",i2c_dev->ast_i2c_data->reg_gr, sts, i2c_dev->bus_id);
++ }
++
++ return IRQ_HANDLED;
+ }
+
+ return IRQ_HANDLED;
+-
+ }
+
+ static int ast_i2c_do_msgs_xfer(struct ast_i2c_dev *i2c_dev, struct i2c_msg *msgs, int num)
+ {
+ int i;
+- int ret = 1;
++ int ret = 1;
+ unsigned long flags;
+
+- spin_lock_irqsave(&g_master_lock, flags);
++ spin_lock_irqsave(&i2c_dev->master_lock, flags);
+
+ //request
+ if(i2c_dev->ast_i2c_data->master_dma == BYTE_MODE)
+@@ -1433,7 +1500,7 @@ static int ast_i2c_do_msgs_xfer(struct ast_i2c_dev *i2c_dev, struct i2c_msg *msg
+ else {
+ if(i2c_dev->ast_i2c_data->request_pool_buff_page(&(i2c_dev->req_page)) == 0)
+ i2c_dev->do_master_xfer = ast_i2c_do_pool_xfer;
+- else
++ else
+ i2c_dev->do_master_xfer = ast_i2c_do_byte_xfer;
+ }
+
+@@ -1458,12 +1525,12 @@ static int ast_i2c_do_msgs_xfer(struct ast_i2c_dev *i2c_dev, struct i2c_msg *msg
+
+ i2c_dev->do_master_xfer(i2c_dev);
+
+- spin_unlock_irqrestore(&g_master_lock, flags);
++ spin_unlock_irqrestore(&i2c_dev->master_lock, flags);
+
+ ret = wait_for_completion_interruptible_timeout(&i2c_dev->cmd_complete,
+ i2c_dev->adap.timeout*HZ);
+-
+- spin_lock_irqsave(&g_master_lock, flags);
++
++ spin_lock_irqsave(&i2c_dev->master_lock, flags);
+ i2c_dev->master_msgs = NULL;
+
+ if (ret == 0) {
+@@ -1471,25 +1538,30 @@ static int ast_i2c_do_msgs_xfer(struct ast_i2c_dev *i2c_dev, struct i2c_msg *msg
+ i2c_dev->state = (ast_i2c_read(i2c_dev,I2C_CMD_REG) >> 19) & 0xf;
+ // printk("sts [%x], isr sts [%x] \n",i2c_dev->state, ast_i2c_read(i2c_dev,I2C_INTR_STS_REG));
+ ret = -ETIMEDOUT;
+- spin_unlock_irqrestore(&g_master_lock, flags);
++ spin_unlock_irqrestore(&i2c_dev->master_lock, flags);
+ goto stop;
+ }
+-
++
+ if(i2c_dev->cmd_err != 0 &&
+ i2c_dev->cmd_err != AST_I2CD_INTR_STS_NORMAL_STOP) {
++ if (i2c_dev->cmd_err & AST_LOCKUP_DETECTED) {
++ printk("ast-i2c: error got unexpected STOP\n");
++ // reset the bus
++ ast_i2c_bus_error_recover(i2c_dev);
++ }
+ ret = -EAGAIN;
+- spin_unlock_irqrestore(&g_master_lock, flags);
++ spin_unlock_irqrestore(&i2c_dev->master_lock, flags);
+ goto stop;
+ }
+ }
+
+- spin_unlock_irqrestore(&g_master_lock, flags);
++ spin_unlock_irqrestore(&i2c_dev->master_lock, flags);
+
+ if(i2c_dev->cmd_err == 0 ||
+ i2c_dev->cmd_err == AST_I2CD_INTR_STS_NORMAL_STOP) {
+ ret = num;
+ goto out;
+-
++
+ }
+ stop:
+ init_completion(&i2c_dev->cmd_complete);
+@@ -1503,8 +1575,8 @@ out:
+ //Free ..
+ if(i2c_dev->master_xfer_mode == BUFF_XFER) {
+ i2c_dev->ast_i2c_data->free_pool_buff_page(i2c_dev->req_page);
+-
+- }
++
++ }
+ dev_dbg(i2c_dev->dev, "end xfer ret = %d, xfer mode[%d]\n",ret, i2c_dev->master_xfer_mode);
+ return ret;
+
+@@ -1521,7 +1593,7 @@ static int ast_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+ /*
+ * Wait for the bus to become free.
+ */
+-
++
+ ret = ast_i2c_wait_bus_not_busy(i2c_dev);
+ if (ret) {
+ dev_err(&i2c_dev->adap.dev, "i2c_ast: timeout waiting for bus free\n");
+@@ -1536,7 +1608,7 @@ static int ast_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+ dev_dbg(&adap->dev, "Retrying transmission [%d]\n",i);
+ udelay(100);
+ }
+-
++
+ ret = -EREMOTEIO;
+ out:
+
+@@ -1550,9 +1622,9 @@ static u32 ast_i2c_functionality(struct i2c_adapter *adap)
+
+ static const struct i2c_algorithm i2c_ast_algorithm = {
+ .master_xfer = ast_i2c_xfer,
+-#ifdef CONFIG_AST_I2C_SLAVE_RDWR
++#ifdef CONFIG_AST_I2C_SLAVE_RDWR
+ .slave_xfer = ast_i2c_slave_xfer,
+-#endif
++#endif
+ .functionality = ast_i2c_functionality,
+ };
+
+@@ -1572,23 +1644,23 @@ static int ast_i2c_probe(struct platform_device *pdev)
+
+ i2c_dev->ast_i2c_data = pdev->dev.platform_data;
+ if(i2c_dev->ast_i2c_data->master_dma == BUFF_MODE) {
+- dev_dbg(&pdev->dev, "use buffer pool mode 256\n");
+-
++ dev_dbg(&pdev->dev, "use buffer pool mode 256\n");
++
+ } else if ((i2c_dev->ast_i2c_data->master_dma == DMA_MODE) || (i2c_dev->ast_i2c_data->slave_dma == DMA_MODE)) {
+- dev_dbg(&pdev->dev, "use dma mode \n");
++ dev_dbg(&pdev->dev, "use dma mode \n");
+ if (!i2c_dev->dma_buf) {
+ i2c_dev->dma_buf = dma_alloc_coherent(NULL, AST_I2C_DMA_SIZE, &i2c_dev->dma_addr, GFP_KERNEL);
+ if (!i2c_dev->dma_buf) {
+ printk("unable to allocate tx Buffer memory\n");
+ ret = -ENOMEM;
+- goto err_no_dma;
++ goto err_no_dma;
+ }
+ if(i2c_dev->dma_addr%4 !=0) {
+ printk("not 4 byte boundary \n");
+ ret = -ENOMEM;
+- goto err_no_dma;
+- }
+-// printk("dma_buf = [0x%x] dma_addr = [0x%x], please check 4byte boundary \n",i2c_dev->dma_buf,i2c_dev->dma_addr);
++ goto err_no_dma;
++ }
++// printk("dma_buf = [0x%x] dma_addr = [0x%x], please check 4byte boundary \n",i2c_dev->dma_buf,i2c_dev->dma_addr);
+ memset (i2c_dev->dma_buf, 0, AST_I2C_DMA_SIZE);
+ }
+
+@@ -1596,7 +1668,7 @@ static int ast_i2c_probe(struct platform_device *pdev)
+ //master_mode 0: use byte mode
+ dev_dbg(&pdev->dev, "use default byte mode \n");
+ }
+-
++
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (NULL == res) {
+ dev_err(&pdev->dev, "cannot get IORESOURCE_MEM\n");
+@@ -1628,11 +1700,11 @@ static int ast_i2c_probe(struct platform_device *pdev)
+ if(i2c_dev->irq == IRQ_C0_I2C) {
+ i2c_dev->bus_id = pdev->id - NUM_BUS;
+ dev_dbg(&pdev->dev, "C0 :: pdev->id %d , i2c_dev->bus_id = %d, i2c_dev->irq =%d\n",pdev->id, i2c_dev->bus_id,i2c_dev->irq);
+-#if (CONFIG_AST1070_NR >= 2)
++#if (CONFIG_AST1070_NR >= 2)
+ } else if(i2c_dev->irq == IRQ_C1_I2C) {
+ i2c_dev->bus_id = pdev->id - (NUM_BUS + 8);
+- dev_dbg(&pdev->dev, "C1 :: pdev->id %d , i2c_dev->bus_id = %d, i2c_dev->irq =%d\n",pdev->id, i2c_dev->bus_id,i2c_dev->irq);
+-#endif
++ dev_dbg(&pdev->dev, "C1 :: pdev->id %d , i2c_dev->bus_id = %d, i2c_dev->irq =%d\n",pdev->id, i2c_dev->bus_id,i2c_dev->irq);
++#endif
+ } else {
+ i2c_dev->bus_id = pdev->id;
+ dev_dbg(&pdev->dev, "AST pdev->id %d , i2c_dev->bus_id = %d, i2c_dev->irq =%d\n",pdev->id, i2c_dev->bus_id,i2c_dev->irq);
+@@ -1644,13 +1716,13 @@ static int ast_i2c_probe(struct platform_device *pdev)
+ /* Initialize the I2C adapter */
+ i2c_dev->adap.owner = THIS_MODULE;
+ //TODO
+- i2c_dev->adap.retries = 0;
++ i2c_dev->adap.retries = 0;
+
+-// i2c_dev->adap.retries = 3;
++// i2c_dev->adap.retries = 3;
+
+- i2c_dev->adap.timeout = 5;
++ i2c_dev->adap.timeout = 5;
+
+- i2c_dev->master_xfer_mode = BYTE_XFER;
++ i2c_dev->master_xfer_mode = BYTE_XFER;
+
+ /*
+ * If "pdev->id" is negative we consider it as zero.
+@@ -1662,7 +1734,7 @@ static int ast_i2c_probe(struct platform_device *pdev)
+ i2c_dev->adap.nr);
+
+ i2c_dev->slave_operation = 0;
+- i2c_dev->blk_r_flag = 0;
++ i2c_dev->blk_r_flag = 0;
+ i2c_dev->adap.algo = &i2c_ast_algorithm;
+
+ ast_i2c_dev_init(i2c_dev);
+@@ -1674,8 +1746,11 @@ static int ast_i2c_probe(struct platform_device *pdev)
+ goto ereqirq;
+ }
+
++ spin_lock_init(&i2c_dev->master_lock);
++
+ #ifdef CONFIG_AST_I2C_SLAVE_RDWR
+ ast_i2c_slave_buff_init(i2c_dev);
++ spin_lock_init(&i2c_dev->slave_rx_lock);
+ #endif
+
+ i2c_dev->adap.algo_data = i2c_dev;
+@@ -1718,7 +1793,7 @@ static int ast_i2c_remove(struct platform_device *pdev)
+
+ platform_set_drvdata(pdev, NULL);
+ i2c_del_adapter(&i2c_dev->adap);
+-
++
+ free_irq(i2c_dev->irq, i2c_dev);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+@@ -1742,7 +1817,7 @@ static int ast_i2c_resume(struct platform_device *pdev)
+ {
+ //TODO
+ // struct ast_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
+- //Should reset i2c ???
++ //Should reset i2c ???
+ return 0;
+ }
+ #else
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/i2c/i2c-core.c b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/i2c/i2c-core.c
+index c8e3cf6..06d9042 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/i2c/i2c-core.c
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/i2c/i2c-core.c
+@@ -1064,7 +1064,7 @@ int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)
+ EXPORT_SYMBOL(i2c_transfer);
+
+ #ifdef CONFIG_AST_I2C_SLAVE_RDWR
+-int i2c_slave_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs)
++int i2c_slave_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+ {
+ unsigned long orig_jiffies;
+ int ret, try;
+@@ -1075,9 +1075,18 @@ int i2c_slave_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs)
+ "len=%d\n", (msgs->flags & I2C_S_RD)
+ ? 'R' : 'W', msgs->addr, msgs->len);
+ #endif
+- i2c_lock_adapter(adap);
++ if (in_atomic() || irqs_disabled()) {
++ ret = mutex_trylock(&adap->bus_lock);
++ if (!ret)
++ /* I2C activity is ongoing. */
++ return -EAGAIN;
++ } else {
++ mutex_lock_nested(&adap->bus_lock, adap->level);
++ }
++
+ ret = adap->algo->slave_xfer(adap, msgs);
+- i2c_unlock_adapter(adap);
++
++ mutex_unlock(&adap->bus_lock);
+
+ return ret;
+ } else {
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/i2c/i2c-dev.c b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/i2c/i2c-dev.c
+index 07f393d..82f2c7c 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/i2c/i2c-dev.c
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/i2c/i2c-dev.c
+@@ -38,7 +38,7 @@
+ #include <asm/uaccess.h>
+
+ #ifdef CONFIG_AST_I2C_SLAVE_RDWR
+-#include <asm/arch/ast_i2c.h>
++#include <plat/ast_i2c.h>
+ #endif
+
+ static struct i2c_driver i2cdev_driver;
+@@ -310,6 +310,113 @@ static noinline int i2cdev_ioctl_rdrw(struct i2c_client *client,
+ return res;
+ }
+
++static noinline int i2cdev_ioctl_slave_rdrw(struct i2c_client *client,
++ unsigned long arg)
++{
++ struct i2c_rdwr_ioctl_data rdwr_arg;
++ struct i2c_msg *rdwr_pa;
++ u8 __user **data_ptrs;
++ int i, res;
++
++ if (copy_from_user(&rdwr_arg,
++ (struct i2c_rdwr_ioctl_data __user *)arg,
++ sizeof(rdwr_arg)))
++ return -EFAULT;
++
++ /* Put an arbitrary limit on the number of messages that can
++ * be sent at once */
++ if (rdwr_arg.nmsgs > I2C_RDRW_IOCTL_MAX_MSGS)
++ return -EINVAL;
++
++ rdwr_pa = (struct i2c_msg *)
++ kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg),
++ GFP_KERNEL);
++ if (!rdwr_pa)
++ return -ENOMEM;
++
++ if (copy_from_user(rdwr_pa, rdwr_arg.msgs,
++ rdwr_arg.nmsgs * sizeof(struct i2c_msg))) {
++ kfree(rdwr_pa);
++ return -EFAULT;
++ }
++
++ data_ptrs = kmalloc(rdwr_arg.nmsgs * sizeof(u8 __user *), GFP_KERNEL);
++ if (data_ptrs == NULL) {
++ kfree(rdwr_pa);
++ return -ENOMEM;
++ }
++
++ res = 0;
++ for (i = 0; i < rdwr_arg.nmsgs; i++) {
++ /* Limit the size of the message to a sane amount;
++ * and don't let length change either. */
++ if (rdwr_pa[i].len > 8192) {
++ res = -EINVAL;
++ break;
++ }
++ data_ptrs[i] = (u8 __user *)rdwr_pa[i].buf;
++ rdwr_pa[i].buf = kmalloc(rdwr_pa[i].len, GFP_KERNEL);
++ if (rdwr_pa[i].buf == NULL) {
++ res = -ENOMEM;
++ break;
++ }
++ if (copy_from_user(rdwr_pa[i].buf, data_ptrs[i],
++ rdwr_pa[i].len)) {
++ ++i; /* Needs to be kfreed too */
++ res = -EFAULT;
++ break;
++ }
++
++ /* From Linux 3.5: */
++ /*
++ * If the message length is received from the slave (similar
++ * to SMBus block read), we must ensure that the buffer will
++ * be large enough to cope with a message length of
++ * I2C_SMBUS_BLOCK_MAX as this is the maximum underlying bus
++ * drivers allow. The first byte in the buffer must be
++ * pre-filled with the number of extra bytes, which must be
++ * at least one to hold the message length, but can be
++ * greater (for example to account for a checksum byte at
++ * the end of the message.)
++ */
++ if (rdwr_pa[i].flags & I2C_M_RECV_LEN) {
++ if (!(rdwr_pa[i].flags & I2C_M_RD) ||
++ rdwr_pa[i].buf[0] < 1 ||
++ rdwr_pa[i].len < rdwr_pa[i].buf[0] +
++ I2C_SMBUS_BLOCK_MAX) {
++ res = -EINVAL;
++ break;
++ }
++
++ rdwr_pa[i].len = rdwr_pa[i].buf[0];
++ }
++
++ }
++ if (res < 0) {
++ int j;
++ for (j = 0; j < i; ++j)
++ kfree(rdwr_pa[j].buf);
++ kfree(data_ptrs);
++ kfree(rdwr_pa);
++ return res;
++ }
++
++ res = i2c_slave_transfer(client->adapter, rdwr_pa, rdwr_arg.nmsgs);
++ while (i-- > 0) {
++ if (res >= 0 ) {
++ if (copy_to_user(data_ptrs[i], rdwr_pa[i].buf,
++ rdwr_pa[i].len))
++ res = -EFAULT;
++
++ rdwr_arg.msgs[i].len = rdwr_pa[i].len;
++ }
++ kfree(rdwr_pa[i].buf);
++ }
++ kfree(data_ptrs);
++ kfree(rdwr_pa);
++ return res;
++}
++
+ static noinline int i2cdev_ioctl_smbus(struct i2c_client *client,
+ unsigned long arg)
+ {
+@@ -448,8 +555,8 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+
+ #ifdef CONFIG_AST_I2C_SLAVE_RDWR
+ case I2C_SLAVE_RDWR:
+- return i2cdev_ioctl_slave_rdrw(client->adapter, (struct i2c_msg __user *)arg);
+-#endif
++ return i2cdev_ioctl_slave_rdrw(client, arg);
++#endif
+
+ case I2C_SMBUS:
+ return i2cdev_ioctl_smbus(client, arg);
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/net/ftgmac100_26.c b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/net/ftgmac100_26.c
+index fdc77fc..3a5d796 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/net/ftgmac100_26.c
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/net/ftgmac100_26.c
+@@ -1,16 +1,16 @@
+ /********************************************************************************
+ * File Name : ftgmac100_26.c
+-*
++*
+ * Copyright (C) 2012-2020 ASPEED Technology Inc.
+-* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ ********************************************************************************/
+ //-----------------------------------------------------------------------------
+ // "ASPEED MAC Driver, (Linux Kernel 2.6.15.7) 10/02/07 - by ASPEED\n"
+@@ -76,7 +76,7 @@
+ //AST2300 SDK 0.14
+ //19.09/13/2010 - by river@aspeed
+ // Support Realtek RTL8201EL 10/100M PHY
+-//AST2400
++//AST2400
+ //20.06/25/2013 - by CC@aspeed
+ // Support BCM54612E 10/100/1000M PHY
+ //-----------------------------------------------------------------------------
+@@ -120,7 +120,12 @@
+ #err "Not define include for GMAC"
+ #endif
+
++#ifdef CONFIG_WEDGE100
++#define PHY_DEFAULT_ADDR 0x18
++#else
++/* wedge */
+ #define PHY_DEFAULT_ADDR 0x1F
++#endif
+
+ /*------------------------------------------------------------------------
+ .
+@@ -172,7 +177,6 @@ static int ftgmac100_wait_to_send_packet(struct sk_buff * skb, struct net_device
+
+ static volatile int trans_busy = 0;
+
+-
+ void ftgmac100_phy_rw_waiting(unsigned int ioaddr)
+ {
+ unsigned int tmp;
+@@ -255,6 +259,7 @@ static void getMacHwConfig( struct net_device* dev, struct AstMacHwConfig* out )
+
+ // out->macId = dev->dev_id;
+ //.. getMacAndPhy(dev, out);
++ out->phyAddr = PHY_DEFAULT_ADDR;
+ out->miiPhyId = 0;
+
+ // We assume the Clock Stop register does not disable the MAC1 or MAC2 clock
+@@ -272,7 +277,7 @@ no_phy_access:
+ out->phyAddr = 1;
+ }
+ #if 0
+- if (out->miiPhyId == 0x0362) {
++ if (out->miiPhyId == 0x0362) {
+ out->phyAddr = 1;
+ }
+ #endif
+@@ -297,6 +302,902 @@ no_phy_access:
+ return;
+ }
+
++// --------------------------------------------------------------------
++// NCSI function
++// --------------------------------------------------------------------
++void NCSI_Struct_Initialize(struct net_device *dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long i;
++
++ for (i = 0; i < 6; i++) {
++ lp->NCSI_Request.DA[i] = 0xFF;
++ lp->NCSI_Respond.DA[i] = 0xFF;
++ lp->NCSI_Respond.SA[i] = 0xFF;
++ lp->NCSI_Request.SA[i] = dev->dev_addr[i];
++ }
++ lp->NCSI_Request.EtherType = 0xF888;
++ lp->NCSI_Request.MC_ID = 0;
++ lp->NCSI_Request.Header_Revision = 0x01;
++ lp->NCSI_Request.Reserved_1 = 0;
++ lp->NCSI_Request.Reserved_2 = 0;
++ lp->NCSI_Request.Reserved_3 = 0;
++ lp->NCSI_Respond.EtherType = 0xF888;
++ lp->NCSI_Respond.MC_ID = 0;
++ lp->NCSI_Respond.Header_Revision = 0x01;
++ lp->NCSI_Respond.Reserved_1 = 0;
++ lp->NCSI_Respond.Reserved_2 = 0;
++ lp->NCSI_Respond.Reserved_3 = 0;
++
++ lp->InstanceID = 0;
++ lp->Payload_Checksum = 0;
++ for (i = 0; i < 4; i++) {
++ lp->Payload_Pad[i] = 0;
++ }
++ for (i = 0; i < 64; i++) {
++ lp->Payload_Data[i] = 0;
++ }
++}
++
++void Calculate_Checksum(struct net_device * dev, unsigned char *buffer_base, int Length)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned int i, CheckSum = 0;
++ unsigned int Data, Data1;
++
++ for (i = 0; i < ((Length - 14) / 2); i++) {
++ Data = buffer_base[i * 2];
++ Data1 = buffer_base[i * 2 + 1];
++ CheckSum += ((Data << 8) + Data1);
++ }
++ lp->Payload_Checksum = (~(CheckSum) + 1); //2's complement
++//Inverse for insert into buffer
++ Data = (lp->Payload_Checksum & 0xFF000000) >> 24;
++ Data1 = (lp->Payload_Checksum & 0x000000FF) << 24;
++ lp->Payload_Checksum = (lp->Payload_Checksum & 0x00FFFF00) + Data + Data1;
++ Data = (lp->Payload_Checksum & 0x00FF0000) >> 8;
++ Data1 = (lp->Payload_Checksum & 0x0000FF00) << 8;
++ lp->Payload_Checksum = (lp->Payload_Checksum & 0xFF0000FF) + Data + Data1;
++}
++
++void copy_data (struct net_device * dev, struct sk_buff * skb, int Length)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++
++ memcpy ((unsigned char *)(skb->data + 30), &lp->Payload_Data, Length);
++ Calculate_Checksum(dev, skb->data + 14, 30 + Length);
++ memcpy ((unsigned char *)(skb->data + 30 + Length), &lp->Payload_Checksum, 4);
++}
++
++void NCSI_Rx (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long status, length, i = 0;
++ volatile RX_DESC *cur_desc;
++
++ncsi_rx:
++ i = 0;
++ cur_desc = &lp->rx_descs[lp->rx_idx];
++ do {
++ status = cur_desc->RXPKT_RDY;
++ i++;
++ } while (!(((status & RX_OWNBY_SOFTWARE) != 0) || (i >= NCSI_LOOP)));
++
++ if (i < NCSI_LOOP) {
++ if (cur_desc->LRS) {
++ length = cur_desc->VDBC;
++ unsigned char *tbuf = (unsigned char *)phys_to_virt(cur_desc->RXBUF_BADR);
++ if (length <= 128 && tbuf[12] == 0x88 && tbuf[13] == 0xF8) {
++ memcpy (&lp->NCSI_Respond, (unsigned char *)phys_to_virt(cur_desc->RXBUF_BADR), length);
++ } else {
++ printk("NCSI_RX: Skip len: %d, proto: %x:%x\n", length, tbuf[12], tbuf[13]);
++ lp->rx_descs[lp->rx_idx].RXPKT_RDY = RX_OWNBY_FTGMAC100;
++ lp->rx_idx = (lp->rx_idx+1)%RXDES_NUM;
++ goto ncsi_rx;
++ }
++
++ }
++ lp->rx_descs[lp->rx_idx].RXPKT_RDY = RX_OWNBY_FTGMAC100;
++ lp->rx_idx = (lp->rx_idx+1)%RXDES_NUM;
++ } else {
++ printk("NCSI_Rx: Failed\n");
++ }
++}
++
++void DeSelect_Package (struct net_device * dev, int Package_ID)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = DESELECT_PACKAGE;
++ Combined_Channel_ID = (Package_ID << 5) + 0x1F; //Internal Channel ID = 0x1F, 0x1F means all channel
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (DESELECT_PACKAGE | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++int Select_Package (struct net_device * dev, int Package_ID)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID, Found = 0;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = SELECT_PACKAGE;
++ Combined_Channel_ID = (Package_ID << 5) + 0x1F; //Internal Channel ID = 0x1F
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = (4 << 8);
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ lp->NCSI_Request.Payload_Length = 4;
++ memset ((void *)lp->Payload_Data, 0, 4);
++ lp->Payload_Data[3] = 1; //Arbitration Disable
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (SELECT_PACKAGE | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ Found = 0;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ Found = 1;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++
++ return Found;
++}
++
++
++void DeSelect_Active_Package (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = DESELECT_PACKAGE;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + 0x1F; //Internal Channel ID = 0x1F, 0x1F means all channel
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (DESELECT_PACKAGE | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++
++int Select_Active_Package (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID, Found = 0;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = SELECT_PACKAGE;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + 0x1F; //Internal Channel ID = 0x1F
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = (4 << 8);
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ lp->NCSI_Request.Payload_Length = 4;
++ memset ((void *)lp->Payload_Data, 0, 4);
++ lp->Payload_Data[3] = 1; //Arbitration Disable
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (SELECT_PACKAGE | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ Found = 0;
++ }
++ else {
++ lp->Retry = 0;
++ Found = 1;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++
++ return Found;
++}
++
++int Clear_Initial_State (struct net_device * dev, int Channel_ID)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID, Found = 0;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = CLEAR_INITIAL_STATE;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + Channel_ID; //Internal Channel ID = 0
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (CLEAR_INITIAL_STATE | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ Found = 0;
++ }
++ else {
++ lp->Retry = 0;
++ Found = 1;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++
++ return Found;
++}
++
++void Get_Version_ID (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = GET_VERSION_ID;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (GET_VERSION_ID | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++void Get_Capabilities (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = GET_CAPABILITIES;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (GET_CAPABILITIES | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ lp->NCSI_Cap.Capabilities_Flags = lp->NCSI_Respond.Payload_Data[0];
++ lp->NCSI_Cap.Broadcast_Packet_Filter_Capabilities = lp->NCSI_Respond.Payload_Data[1];
++ lp->NCSI_Cap.Multicast_Packet_Filter_Capabilities = lp->NCSI_Respond.Payload_Data[2];
++ lp->NCSI_Cap.Buffering_Capabilities = lp->NCSI_Respond.Payload_Data[3];
++ lp->NCSI_Cap.AEN_Control_Support = lp->NCSI_Respond.Payload_Data[4];
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++void Enable_AEN (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = AEN_ENABLE;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = (8 << 8);
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ lp->NCSI_Request.Payload_Length = 8;
++ lp->Payload_Data[3] = 0; //MC ID
++ lp->Payload_Data[7] = 1; //Link Status Change AEN
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (AEN_ENABLE | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++void Get_MAC_Address (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID, i;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = 0x50;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = (8 << 8);
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ lp->NCSI_Request.Payload_Length = 8;
++ lp->Payload_Data[0] = 0x00;
++ lp->Payload_Data[1] = 0x00;
++ lp->Payload_Data[2] = 0x81;
++ lp->Payload_Data[3] = 0x19;
++
++ lp->Payload_Data[4] = 0x00;
++ lp->Payload_Data[5] = 0x00;
++ lp->Payload_Data[6] = 0x1B;
++ lp->Payload_Data[7] = 0x00;
++
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (0x50 | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++
++ // Update MAC Address
++printk("NCSI: MAC ");
++for (i = 0; i < 6; i++)
++ printk("%02X:", lp->NCSI_Respond.Payload_Data[12+i]);
++printk("\n");
++ memcpy(lp->NCSI_Request.SA, &lp->NCSI_Respond.Payload_Data[12], 6);
++ memcpy(dev->dev_addr, &lp->NCSI_Respond.Payload_Data[12], 6);
++
++ /* Update the MAC address */
++ ast_gmac_set_mac(lp, dev->dev_addr);
++}
++
++void Set_MAC_Affinity (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID, i;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = 0x50;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = (60 << 8);
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++
++ lp->NCSI_Request.Payload_Length = 60;
++ memset(lp->Payload_Data, 0x00, 60);
++ lp->Payload_Data[0] = 0x00;
++ lp->Payload_Data[1] = 0x00;
++ lp->Payload_Data[2] = 0x81;
++ lp->Payload_Data[3] = 0x19;
++
++ lp->Payload_Data[4] = 0x00;
++ lp->Payload_Data[5] = 0x01;
++ lp->Payload_Data[6] = 0x07;
++ lp->Payload_Data[7] = 0x00;
++
++ for (i = 0; i < 6; i++) {
++ lp->Payload_Data[8+i] = lp->NCSI_Request.SA[i];
++ }
++
++ lp->Payload_Data[14] = 0x09;
++
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (0x50 | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++void Enable_Set_MAC_Address (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID, i;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = SET_MAC_ADDRESS;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = (8 << 8);
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ lp->NCSI_Request.Payload_Length = 8;
++ for (i = 0; i < 6; i++) {
++ lp->Payload_Data[i] = lp->NCSI_Request.SA[i];
++ }
++ lp->Payload_Data[6] = 1; //MAC Address Num = 1 --> address filter 1, fixed in sample code
++ lp->Payload_Data[7] = UNICAST + 0 + ENABLE_MAC_ADDRESS_FILTER; //AT + Reserved + E
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (SET_MAC_ADDRESS | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++void Enable_Broadcast_Filter (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = ENABLE_BROADCAST_FILTERING;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = (4 << 8);
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ lp->NCSI_Request.Payload_Length = 4;
++ memset ((void *)lp->Payload_Data, 0, 4);
++ lp->Payload_Data[3] = 0x1; //ARP, DHCP, NetBIOS
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (ENABLE_BROADCAST_FILTERING | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++void Disable_VLAN (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = DISABLE_VLAN;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (DISABLE_VLAN | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++void Get_Parameters (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = GET_PARAMETERS;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (GET_PARAMETERS | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++// printk ("Retry: Command = %x, Response_Code = %x, Resonpd.Command = %x, IID = %x, lp->InstanceID = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code, lp->NCSI_Respond.Command, lp->NCSI_Respond.IID, lp->InstanceID);
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ lp->NCSI_Cap.Capabilities_Flags = lp->NCSI_Respond.Payload_Data[0];
++ lp->NCSI_Cap.Broadcast_Packet_Filter_Capabilities = lp->NCSI_Respond.Payload_Data[1];
++ lp->NCSI_Cap.Multicast_Packet_Filter_Capabilities = lp->NCSI_Respond.Payload_Data[2];
++ lp->NCSI_Cap.Buffering_Capabilities = lp->NCSI_Respond.Payload_Data[3];
++ lp->NCSI_Cap.AEN_Control_Support = lp->NCSI_Respond.Payload_Data[4];
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++void Enable_Network_TX (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = ENABLE_CHANNEL_NETWORK_TX;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (ENABLE_CHANNEL_NETWORK_TX | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++void Disable_Network_TX (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = DISABLE_CHANNEL_NETWORK_TX;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + (lp->NCSI_Request.Payload_Length % 4) + 8;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (DISABLE_CHANNEL_NETWORK_TX | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ } else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++void Enable_Channel (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = ENABLE_CHANNEL;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (ENABLE_CHANNEL | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++void Disable_Channel (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = DISABLE_CHANNEL;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = (4 << 8);
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ lp->NCSI_Request.Payload_Length = 4;
++ memset ((void *)lp->Payload_Data, 0, 4);
++ lp->Payload_Data[3] = 0x1; //ALD
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (DISABLE_CHANNEL | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++int Get_Link_Status (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = GET_LINK_STATUS;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (GET_LINK_STATUS | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++ if (lp->NCSI_Respond.Payload_Data[3] & 0x40) {
++ return (lp->NCSI_Respond.Payload_Data[3] & 0x01); //Link Up or Not
++ }
++ else {
++ return 0; //Auto Negotiate did not finish
++ }
++}
++
++void Set_Link (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = SET_LINK;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = (8 << 8);
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ lp->NCSI_Request.Payload_Length = 8;
++ memset ((void *)lp->Payload_Data, 0, 8);
++ lp->Payload_Data[2] = 0x02; //full duplex
++ lp->Payload_Data[3] = 0x04; //100M, auto-disable
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (SET_LINK | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
+
+ static void ftgmac100_reset( struct net_device* dev )
+ {
+@@ -308,64 +1209,71 @@ static void ftgmac100_reset( struct net_device* dev )
+ PRINTK("%s:ftgmac100_reset, phyAddr=0x%x, miiPhyId=0x%04x_%04x\n",
+ dev->name, ids->phyAddr, (ids->miiPhyId >> 16), (ids->miiPhyId & 0xffff));
+
+- if (ids->miiPhyId < 1)
+- return; // Cannot access MAC registers
+-
+- // Check the link speed and duplex.
+- // They are not valid until auto-neg is resolved, which is reg.1 bit[5],
+- // or the link is up, which is reg.1 bit[2].
+-
+- if (ids->phyAddr < 0xff)
+- tmp = ftgmac100_read_phy_register(dev->base_addr, ids->phyAddr, 0x1);
+- else tmp = 0;
+-
+- if (0==(tmp & (1u<<5 | 1u<<2)) || ids->phyAddr >= 0xff) {
+- // No PHY chip, or link has not negotiated.
+- speed = PHY_SPEED_100M;
+- duplex = 1;
+- netif_carrier_off(dev);
+- }
+- else if (((ids->miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8201EL)) {
+- tmp = ftgmac100_read_phy_register(dev->base_addr, priv->ids.phyAddr, 0x00);
+- duplex = (tmp & 0x0100) ? 1 : 0;
+- speed = (tmp & 0x2000) ? PHY_SPEED_100M : PHY_SPEED_10M;
+- }
+- else if (((ids->miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_MARVELL) ||
+- ((ids->miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8211)) {
+- // Use reg.17_0.bit[15:13] for {speed[1:0], duplex}.
+- tmp = ftgmac100_read_phy_register(dev->base_addr, ids->phyAddr, 0x11);
+- duplex = (tmp & PHY_DUPLEX_mask)>>13;
+- speed = (tmp & PHY_SPEED_mask)>>14;
+- netif_carrier_on(dev);
+- }
+- else if (priv->ids.miiPhyId == PHYID_BCM54612E
+- || priv->ids.miiPhyId == PHYID_BCM54616S) {
+- // Get link status
+- // First Switch shadow register selector
+- ftgmac100_write_phy_register(dev->base_addr, priv->ids.phyAddr, 0x1C, 0x2000);
+- tmp = ftgmac100_read_phy_register(dev->base_addr, priv->ids.phyAddr, 0x1C);
+- if ( (tmp & 0x0080) == 0x0080 )
+- duplex = 0;
+- else
+- duplex = 1;
+-
+- switch(tmp & 0x0018) {
+- case 0x0000:
+- speed = PHY_SPEED_1G; break;
+- case 0x0008:
+- speed = PHY_SPEED_100M; break;
+- case 0x0010:
+- speed = PHY_SPEED_10M; break;
+- default:
+- speed = PHY_SPEED_100M;
+- }
++ if ((priv->NCSI_support == 1) || (priv->INTEL_NCSI_EVA_support == 1)) {
++ ids->miiPhyId = 0xFFFF;
++ // NCSI mode always is 100M and full duplex
++ duplex = 1;
++ speed = PHY_SPEED_100M;
++ } else {
++ if (ids->miiPhyId < 1)
++ return; // Cannot access MAC registers
++
++ // Check the link speed and duplex.
++ // They are not valid until auto-neg is resolved, which is reg.1 bit[5],
++ // or the link is up, which is reg.1 bit[2].
++
++ if (ids->phyAddr < 0xff)
++ tmp = ftgmac100_read_phy_register(dev->base_addr, ids->phyAddr, 0x1);
++ else tmp = 0;
++
++ if (0==(tmp & (1u<<5 | 1u<<2)) || ids->phyAddr >= 0xff) {
++ // No PHY chip, or link has not negotiated.
++ speed = PHY_SPEED_100M;
++ duplex = 1;
++ netif_carrier_off(dev);
+ }
+- else {
+- // Assume Broadcom BCM5221. Use reg.18 bits [1:0] for {100Mb/s, fdx}.
+- tmp = ftgmac100_read_phy_register(dev->base_addr, ids->phyAddr, 0x18);
+- duplex = (tmp & 0x0001);
+- speed = (tmp & 0x0002) ? PHY_SPEED_100M : PHY_SPEED_10M;
+- }
++ else if (((ids->miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8201EL)) {
++ tmp = ftgmac100_read_phy_register(dev->base_addr, priv->ids.phyAddr, 0x00);
++ duplex = (tmp & 0x0100) ? 1 : 0;
++ speed = (tmp & 0x2000) ? PHY_SPEED_100M : PHY_SPEED_10M;
++ }
++ else if (((ids->miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_MARVELL) ||
++ ((ids->miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8211)) {
++ // Use reg.17_0.bit[15:13] for {speed[1:0], duplex}.
++ tmp = ftgmac100_read_phy_register(dev->base_addr, ids->phyAddr, 0x11);
++ duplex = (tmp & PHY_DUPLEX_mask)>>13;
++ speed = (tmp & PHY_SPEED_mask)>>14;
++ netif_carrier_on(dev);
++ }
++ else if (priv->ids.miiPhyId == PHYID_BCM54612E
++ || priv->ids.miiPhyId == PHYID_BCM54616S) {
++ // Get link status
++ // First Switch shadow register selector
++ ftgmac100_write_phy_register(dev->base_addr, priv->ids.phyAddr, 0x1C, 0x2000);
++ tmp = ftgmac100_read_phy_register(dev->base_addr, priv->ids.phyAddr, 0x1C);
++ if ( (tmp & 0x0080) == 0x0080 )
++ duplex = 0;
++ else
++ duplex = 1;
++
++ switch(tmp & 0x0018) {
++ case 0x0000:
++ speed = PHY_SPEED_1G; break;
++ case 0x0008:
++ speed = PHY_SPEED_100M; break;
++ case 0x0010:
++ speed = PHY_SPEED_10M; break;
++ default:
++ speed = PHY_SPEED_100M;
++ }
++ }
++ else {
++ // Assume Broadcom BCM5221. Use reg.18 bits [1:0] for {100Mb/s, fdx}.
++ tmp = ftgmac100_read_phy_register(dev->base_addr, ids->phyAddr, 0x18);
++ duplex = (tmp & 0x0001);
++ speed = (tmp & 0x0002) ? PHY_SPEED_100M : PHY_SPEED_10M;
++ }
++ }// NCSI_Check
+
+ if (speed == PHY_SPEED_1G) {
+ // Set SPEED_100_bit too, for consistency.
+@@ -385,9 +1293,9 @@ static void ftgmac100_reset( struct net_device* dev )
+ }
+ if (duplex)
+ priv->maccr_val |= FULLDUP_bit;
+- else
++ else
+ priv->maccr_val &= ~FULLDUP_bit;
+-
++
+ outl( SW_RST_bit, dev->base_addr + MACCR_REG );
+
+ #ifdef not_complete_yet
+@@ -419,6 +1327,7 @@ static void ftgmac100_enable( struct net_device *dev )
+ unsigned int rfifo_rsize; //Richard
+ unsigned int tfifo_rsize; //Richard
+ unsigned int rxbuf_size;
++ unsigned long Package_Found = 0, Channel_Found = 0, Re_Send = 0, Link_Status;
+
+ rxbuf_size = RX_BUF_SIZE & 0x3fff;
+ outl( rxbuf_size , dev->base_addr + RBSR_REG); //for NC Body
+@@ -475,7 +1384,7 @@ static void ftgmac100_enable( struct net_device *dev )
+
+ /// enable trans/recv,...
+ outl(priv->maccr_val, dev->base_addr + MACCR_REG );
+-#if 0
++
+ //NCSI Start
+ //DeSelect Package/ Select Package
+ if ((priv->NCSI_support == 1) || (priv->INTEL_NCSI_EVA_support == 1)) {
+@@ -491,16 +1400,18 @@ static void ftgmac100_enable( struct net_device *dev )
+ }
+ if (Package_Found != 0) {
+ //Initiali State
+- for (i = 0; i < 2; i++) { //Suppose 2 channels in current version, You could modify it to 0x1F to support 31 channels
+- Channel_Found = Clear_Initial_State(dev, i);
++ for (i = 0; i < 1; i++) { //Suppose 2 channels in current version, You could modify it to 0x1F to support 31 channels
++ //Channel_Found = Clear_Initial_State(dev, i);
++ Channel_Found = 1;
+ if (Channel_Found == 1) {
+ priv->NCSI_Cap.Channel_ID = i;
+ printk ("Found NCSI Network Controller at (%d, %d)\n", priv->NCSI_Cap.Package_ID, priv->NCSI_Cap.Channel_ID);
++ Get_MAC_Address(dev);
++ Set_MAC_Affinity(dev);
++ Clear_Initial_State(dev, i);
+ //Get Version and Capabilities
+ Get_Version_ID(dev);
+ Get_Capabilities(dev);
+-//Configuration
+- Select_Active_Package(dev);
+ //Set MAC Address
+ Enable_Set_MAC_Address(dev);
+ //Enable Broadcast Filter
+@@ -508,16 +1419,18 @@ static void ftgmac100_enable( struct net_device *dev )
+ //Disable VLAN
+ Disable_VLAN(dev);
+ //Enable AEN
+- Enable_AEN(dev);
++ //Enable_AEN(dev);
+ //Get Parameters
+ Get_Parameters(dev);
+-//Enable TX
++//Enable TX
+ Enable_Network_TX(dev);
+ //Enable Channel
+ Enable_Channel(dev);
+ //Get Link Status
+ Re_Get_Link_Status:
+- Link_Status = Get_Link_Status(dev);
++ //TODO: Workaround for CX4 Link status issue
++ //Link_Status = Get_Link_Status(dev);
++ Link_Status = LINK_UP;
+ if (Link_Status == LINK_UP) {
+ printk ("Using NCSI Network Controller (%d, %d)\n", priv->NCSI_Cap.Package_ID, priv->NCSI_Cap.Channel_ID);
+ netif_carrier_on(dev);
+@@ -528,7 +1441,7 @@ Re_Get_Link_Status:
+ netif_carrier_off(dev);
+ goto Re_Get_Link_Status;
+ }
+-//Disable TX
++//Disable TX
+ Disable_Network_TX(dev);
+ //Disable Channel
+ // Disable_Channel(dev);
+@@ -537,9 +1450,19 @@ Re_Get_Link_Status:
+ }
+ }
+ }
++ // Enable Interrupts
++ outl(
++ AHB_ERR_bit |
++ TPKT_LOST_bit |
++ TPKT2E_bit |
++ RXBUF_UNAVA_bit |
++ RPKT2B_bit
++ ,dev->base_addr + IER_REG
++ );
++
++ return;
+ }
+ /* now, enable interrupts */
+-#endif
+ if (((priv->ids.miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_MARVELL) ||
+ ((priv->ids.miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8211)) {
+ outl(
+@@ -564,7 +1487,7 @@ Re_Get_Link_Status:
+ );
+ }
+ else if (priv->ids.miiPhyId == PHYID_BCM54612E
+- || priv->ids.miiPhyId == PHYID_BCM54616S) {
++ || priv->ids.miiPhyId == PHYID_BCM54616S) {
+ outl(
+ // no link PHY link status pin PHYSTS_CHG_bit |
+ AHB_ERR_bit |
+@@ -583,7 +1506,7 @@ Re_Get_Link_Status:
+ RXBUF_UNAVA_bit |
+ RPKT2B_bit
+ ,dev->base_addr + IER_REG
+- );
++ );
+ }
+ }
+
+@@ -619,7 +1542,7 @@ static void aspeed_mac_timer(unsigned long data)
+ speed = (tmp & PHY_SPEED_mask)>>14;
+ }
+ else if (priv->ids.miiPhyId == PHYID_BCM54612E
+- || priv->ids.miiPhyId == PHYID_BCM54616S) {
++ || priv->ids.miiPhyId == PHYID_BCM54616S) {
+ // Get link status
+ // First Switch shadow register selector
+ ftgmac100_write_phy_register(dev->base_addr, priv->ids.phyAddr, 0x1C, 0x2000);
+@@ -628,23 +1551,23 @@ static void aspeed_mac_timer(unsigned long data)
+ duplex = 0;
+ else
+ duplex = 1;
+-
++
+ switch(tmp & 0x0018) {
+ case 0x0000:
+- speed = PHY_SPEED_1G;
+-
++ speed = PHY_SPEED_1G;
++
+ break;
+- case 0x0008:
+- speed = PHY_SPEED_100M;
+-
++ case 0x0008:
++ speed = PHY_SPEED_100M;
++
+ break;
+- case 0x0010:
+- speed = PHY_SPEED_10M;
+-
++ case 0x0010:
++ speed = PHY_SPEED_10M;
++
+ break;
+ default:
+ speed = PHY_SPEED_100M;
+- }
++ }
+ }
+ else {
+ duplex = 1; speed = PHY_SPEED_100M;
+@@ -730,27 +1653,26 @@ static int ftgmac100_wait_to_send_packet( struct sk_buff * skb, struct net_devic
+ PRINTK3("%s:ftgmac100_wait_to_send_packet, skb=%x\n", dev->name, skb);
+ cur_desc = &priv->tx_descs[priv->tx_idx];
+
+-#ifdef not_complete_yet
+- if (cur_desc->TXDMA_OWN != TX_OWNBY_SOFTWARE) /// no empty transmit descriptor
++#ifdef not_complete_yet
++ if (cur_desc->TXDMA_OWN != TX_OWNBY_SOFTWARE) /// no empty transmit descriptor
+ {
+ DO_PRINT("no empty transmit descriptor\n");
+ DO_PRINT("jiffies = %d\n", jiffies);
+ priv->stats.tx_dropped++;
+- netif_stop_queue(dev); /// waiting to do:
++ netif_stop_queue(dev); /// waiting to do:
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+
+ return 1;
+ }
+ #endif /* end_of_not */
+
+- if (cur_desc->TXDMA_OWN != TX_OWNBY_SOFTWARE) /// no empty transmit descriptor
++ if (cur_desc->TXDMA_OWN != TX_OWNBY_SOFTWARE) /// no empty transmit descriptor
+ {
+ DO_PRINT("no empty TX descriptor:0x%x:0x%x\n",
+ (unsigned int)cur_desc,((unsigned int *)cur_desc)[0]);
+ priv->stats.tx_dropped++;
+- netif_stop_queue(dev); /// waiting to do:
++ netif_stop_queue(dev); /// waiting to do:
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+-
+ return 1;
+ }
+ priv->tx_skbuff[priv->tx_idx] = skb;
+@@ -803,18 +1725,18 @@ static int ftgmac100_ringbuf_alloc(struct ftgmac100_priv *priv)
+ int i;
+ struct sk_buff *skb;
+
+- priv->rx_descs = dma_alloc_coherent(priv->dev,
+- sizeof(RX_DESC)*RXDES_NUM,
++ priv->rx_descs = dma_alloc_coherent(priv->dev,
++ sizeof(RX_DESC)*RXDES_NUM,
+ &priv->rx_descs_dma, GFP_KERNEL);
+
+ if(!priv->rx_descs)
+ return -ENOMEM;
+-
++
+ memset(priv->rx_descs, 0, sizeof(RX_DESC)*RXDES_NUM);
+ priv->rx_descs[RXDES_NUM-1].EDORR = 1;
+
+ for (i=0; i<RXDES_NUM; i++) {
+- dma_addr_t mapping;
++ dma_addr_t mapping;
+ skb = dev_alloc_skb(RX_BUF_SIZE + NET_IP_ALIGN);
+ skb_reserve(skb, NET_IP_ALIGN);
+
+@@ -829,8 +1751,8 @@ static int ftgmac100_ringbuf_alloc(struct ftgmac100_priv *priv)
+ priv->rx_descs[i].VIR_RXBUF_BADR = skb->data;
+ }
+
+- priv->tx_descs = dma_alloc_coherent(priv->dev,
+- sizeof(TX_DESC)*TXDES_NUM,
++ priv->tx_descs = dma_alloc_coherent(priv->dev,
++ sizeof(TX_DESC)*TXDES_NUM,
+ &priv->tx_descs_dma ,GFP_KERNEL);
+
+ if(!priv->tx_descs)
+@@ -838,7 +1760,7 @@ static int ftgmac100_ringbuf_alloc(struct ftgmac100_priv *priv)
+
+ memset((void*)priv->tx_descs, 0, sizeof(TX_DESC)*TXDES_NUM);
+ priv->tx_descs[TXDES_NUM-1].EDOTR = 1; // is last descriptor
+-
++
+ }
+
+ #if FTMAC100_DEBUG > 2
+@@ -918,20 +1840,14 @@ static void ftgmac100_phy_configure(struct net_device* dev)
+ }
+ break;
+ case PHYID_VENDOR_BROADCOM:
+- switch (priv->ids.miiPhyId) {
+- case PHYID_BCM54612E:
+- case PHYID_BCM54616S:
+- ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x1C, 0x8C00); // Disable GTXCLK Clock Delay Enable
+- ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x18, 0xF0E7); // Disable RGMII RXD to RXC Skew
+- break;
+- case PHYID_BCM5221A4:
+- default:
+- tmp = ftgmac100_read_phy_register(ioaddr, priv->ids.phyAddr, 0x1b);
+- tmp |= 0x0004;
+- ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x1b, (u16) tmp);
+- break;
+- }
+- break;
++ tmp = ftgmac100_read_phy_register(ioaddr, priv->ids.phyAddr, 0x1b);
++ tmp |= 0x0004;
++ ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x1b, (u16) tmp);
++ break;
++ case PHYID_VENDOR_BCM5461X:
++ ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x1C, 0x8C00); // Disable GTXCLK Clock Delay Enable
++ ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x18, 0xF0E7); // Disable RGMII RXD to RXC Skew
++ break;
+ }
+ }
+
+@@ -960,26 +1876,26 @@ static void ftgmac100_timeout (struct net_device *dev)
+ }
+
+
+-static void ftgmac100_free_tx (struct net_device *dev)
++static void ftgmac100_free_tx (struct net_device *dev)
+ {
+ struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
+- int entry = priv->old_tx % TXDES_NUM;
++ int entry = priv->old_tx % TXDES_NUM;
+ unsigned long flags = 0;
+-
++
+ spin_lock_irqsave(&priv->tx_lock,flags);
+-
++
+ /* Free used tx skbuffs */
+
+ while ((priv->tx_descs[entry].TXDMA_OWN == TX_OWNBY_SOFTWARE) && (priv->tx_skbuff[entry] != NULL)) {
+ struct sk_buff *skb;
+-
++
+ skb = priv->tx_skbuff[entry];
+ dev_kfree_skb_any (skb);
+ priv->tx_skbuff[entry] = 0;
+ entry = (entry + 1) % TXDES_NUM;
+ priv->tx_free++;
+ }
+-
++
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+ priv->old_tx = entry;
+ if ((netif_queue_stopped(dev)) && (priv->tx_free > 0)) {
+@@ -1295,7 +2211,7 @@ static irqreturn_t ftgmac100_interrupt(int irq, void * dev_id, struct pt_regs *
+ DO_PRINT("PHYSTS_CHG \n");
+ // Is this interrupt for changes of the PHYLINK pin?
+ // Note: PHYLINK is optional; not all boards connect it.
+- if (((priv->ids.miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_MARVELL) ||
++ if (((priv->ids.miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_MARVELL) ||
+ ((priv->ids.miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8211))
+ {
+ tmp = ftgmac100_read_phy_register(ioaddr, priv->ids.phyAddr, 0x13);
+@@ -1312,7 +2228,7 @@ static irqreturn_t ftgmac100_interrupt(int irq, void * dev_id, struct pt_regs *
+ tmp &= 0x000e;
+ }
+ else if (priv->ids.miiPhyId == PHYID_BCM54612E
+- || priv->ids.miiPhyId == PHYID_BCM54616S) {
++ || priv->ids.miiPhyId == PHYID_BCM54616S) {
+ tmp = ftgmac100_read_phy_register(ioaddr, priv->ids.phyAddr, 0x1A);
+ PRINTK("%s: PHY interrupt status, read_phy_reg(0x1A) = 0x%04x\n",
+ dev->name, tmp);
+@@ -1403,10 +2319,10 @@ static irqreturn_t ftgmac100_interrupt(int irq, void * dev_id, struct pt_regs *
+ . Get the current statistics.
+ . This may be called with the card open or closed.
+ .-------------------------------------------------------------*/
+-static struct net_device_stats* ftgmac100_query_statistics(struct net_device *dev)
++static struct net_device_stats* ftgmac100_query_statistics(struct net_device *dev)
+ {
+ struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
+-
++
+ return &priv->stats;
+ }
+
+@@ -1416,7 +2332,7 @@ static struct net_device_stats* ftgmac100_query_statistics(struct net_device *de
+ // Finds the CRC32 of a set of bytes.
+ // Again, from Peter Cammaert's code.
+ // --------------------------------------------------------------------
+-static int crc32( char * s, int length )
++static int crc32( char * s, int length )
+ {
+ /* indices */
+ int perByte;
+@@ -1446,7 +2362,7 @@ static int crc32( char * s, int length )
+ . packets before they take up memory.
+ */
+
+-static void ftgmac100_setmulticast( struct net_device *dev, int count, struct dev_mc_list * addrs )
++static void ftgmac100_setmulticast( struct net_device *dev, int count, struct dev_mc_list * addrs )
+ {
+ struct dev_mc_list * cur_addr;
+ int crc_val;
+@@ -1455,12 +2371,12 @@ static void ftgmac100_setmulticast( struct net_device *dev, int count, struct de
+ struct AstMacHwConfig* ids = &priv->ids;
+ unsigned long Combined_Channel_ID, i;
+ struct sk_buff * skb;
+- cur_addr = addrs;
++ cur_addr = addrs;
+
+ //TX
+-#if 0
++#if 1
+ if (priv->NCSI_support == 1) {
+- skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
+ priv->InstanceID++;
+ priv->NCSI_Request.IID = priv->InstanceID;
+ priv->NCSI_Request.Command = SET_MAC_ADDRESS;
+@@ -1597,7 +2513,7 @@ static int ast_gmac_stop(struct net_device *dev)
+ priv->rx_descs = NULL; priv->rx_descs_dma = 0;
+ priv->tx_descs = NULL; priv->tx_descs_dma = 0;
+ priv->tx_buf = NULL; priv->tx_buf_dma = 0;
+-
++
+
+ return 0;
+ }
+@@ -1651,10 +2567,10 @@ static int ftgmac100_open(struct net_device *netdev)
+ ftgmac100_reset(netdev);
+ ftgmac100_enable(netdev);
+
+- if (((priv->ids.miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_BROADCOM) ||
++ if (((priv->ids.miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_BROADCOM) ||
+ ((priv->ids.miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8201EL) ||
+ (priv->ids.miiPhyId == PHYID_BCM54612E) ||
+- (priv->ids.miiPhyId == PHYID_BCM54616S)) {
++ (priv->ids.miiPhyId == PHYID_BCM54616S)) {
+
+ init_timer(&priv->timer);
+ priv->timer.data = (unsigned long)netdev;
+@@ -1702,7 +2618,7 @@ static int __init ast_gmac_probe(struct platform_device *pdev)
+
+
+ // SET_ETHTOOL_OPS(netdev, &ftgmac100_ethtool_ops);
+-
++
+ #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30))
+ netdev->netdev_ops = &ftgmac100_netdev_ops;
+ #else
+@@ -1715,13 +2631,12 @@ static int __init ast_gmac_probe(struct platform_device *pdev)
+ netdev->hard_start_xmit = ftgmac100_wait_to_send_packet;
+ netdev->tx_timeout = ftgmac100_timeout;
+ netdev->get_stats = ftgmac100_query_statistics;
+-//#ifdef HAVE_MULTICAST
+-#if 0
++#ifdef HAVE_MULTICAST
+ netdev->set_multicast_list = &ftgmac100_set_multicast_list;
+ #endif
+
+ #endif
+-
++
+
+ #ifdef CONFIG_AST_NPAI
+ // netdev->features = NETIF_F_GRO;
+@@ -1734,12 +2649,12 @@ static int __init ast_gmac_probe(struct platform_device *pdev)
+ priv = netdev_priv(netdev);
+ priv->netdev = netdev;
+ priv->dev = &pdev->dev;
+-
++
+
+ priv->ids.macId = pdev->id;
+-
++
+ priv->NCSI_support = ast_eth_data->NCSI_support;
+- priv->INTEL_NCSI_EVA_support= ast_eth_data->INTEL_NCSI_EVA_support;
++ priv->INTEL_NCSI_EVA_support= ast_eth_data->INTEL_NCSI_EVA_support;
+ spin_lock_init(&priv->tx_lock);
+
+ #if 0
+@@ -1833,7 +2748,7 @@ err_ioremap:
+ err_req_mem:
+ // netif_napi_del(&priv->napi);
+ platform_set_drvdata(pdev, NULL);
+-err_netdev:
++err_netdev:
+ free_netdev(netdev);
+ err_alloc_etherdev:
+ return err;
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/net/ftgmac100_26.h b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/net/ftgmac100_26.h
+index 0d47024..2493111 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/net/ftgmac100_26.h
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/net/ftgmac100_26.h
+@@ -1,16 +1,16 @@
+ /********************************************************************************
+ * File Name : ftgmac100_26.h
+-*
++*
+ * Copyright (C) 2012-2020 ASPEED Technology Inc.
+-* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ ********************************************************************************/
+ // --------------------------------------------------------------------
+
+@@ -78,7 +78,7 @@
+
+
+ // --------------------------------------------------------------------
+-// APTC_REG
++// APTC_REG
+ // --------------------------------------------------------------------
+
+
+@@ -99,18 +99,18 @@ typedef struct
+ #define PHY_READ_bit (1UL<<26)
+ #define PHY_WRITE_bit (1UL<<27)
+ // --------------------------------------------------------------------
+-// PHYCR_REG
++// PHYCR_REG
+ // --------------------------------------------------------------------
+ #define PHY_AUTO_OK_bit (1UL<<5)
+ // --------------------------------------------------------------------
+-// PHY INT_STAT_REG
++// PHY INT_STAT_REG
+ // --------------------------------------------------------------------
+ #define PHY_SPEED_CHG_bit (1UL<<14)
+ #define PHY_DUPLEX_CHG_bit (1UL<<13)
+ #define PHY_LINK_CHG_bit (1UL<<10)
+ #define PHY_AUTO_COMP_bit (1UL<<11)
+ // --------------------------------------------------------------------
+-// PHY SPE_STAT_REG
++// PHY SPE_STAT_REG
+ // --------------------------------------------------------------------
+ #define PHY_RESOLVED_bit (1UL<<11)
+ #define PHY_SPEED_mask 0xC000
+@@ -269,7 +269,7 @@ typedef struct {
+ unsigned short Reserved_5;
+ unsigned short Response_Code;
+ unsigned short Reason_Code;
+- unsigned char Payload_Data[64];
++ unsigned char Payload_Data[128];
+ } NCSI_Response_Packet;
+
+ //Standard Response Code
+@@ -365,30 +365,30 @@ typedef struct
+ u32 FRS:1;
+ u32 EDORR:1;
+ u32 RXPKT_RDY:1; // 1 ==> owned by FTMAC100, 0 ==> owned by software
+-
++
+ // RXDES1
+ u32 VLAN_TAGC:16;
+ u32 Reserved4:4;
+ u32 PROTL_TYPE:2;
+ u32 LLC_PKT:1;
+ u32 DF:1;
+- u32 VLAN_AVA:1;
++ u32 VLAN_AVA:1;
+ u32 TCPCS_FAIL:1;
+ u32 UDPCS_FAIL:1;
+ u32 IPCS_FAIL:1;
+ u32 Reserved5:4;
+-
++
+ // RXDES2
+ u32 Reserved6:32;
+-
++
+ // RXDES3
+ u32 RXBUF_BADR;
+-
++
+ u32 VIR_RXBUF_BADR; // not defined, the virtual address of receive buffer is placed here
+-
+- u32 RESERVED;
+- u32 RESERVED1;
+- u32 RESERVED2;
++
++ u32 RESERVED;
++ u32 RESERVED1;
++ u32 RESERVED2;
+ }RX_DESC;
+
+
+@@ -405,7 +405,7 @@ typedef struct
+ u32 FTS:1;
+ u32 EDOTR:1;
+ u32 TXDMA_OWN:1;
+-
++
+ // TXDES1
+ u32 VLAN_TAGC:16;
+ u32 INS_VLAN:1;
+@@ -416,8 +416,8 @@ typedef struct
+ u32 LLC_PKT:1;
+ u32 Reserved6:7;
+ u32 TX2FIC:1;
+- u32 TXIC:1;
+-
++ u32 TXIC:1;
++
+ // TXDES2
+ u32 Reserved7:32;
+
+@@ -427,8 +427,8 @@ typedef struct
+ u32 VIR_TXBUF_BADR; // Reserve, the virtual address of transmit buffer is placed here
+
+ u32 RESERVED;
+- u32 RESERVED1;
+- u32 RESERVED2;
++ u32 RESERVED1;
++ u32 RESERVED2;
+
+ }TX_DESC;
+
+@@ -450,7 +450,7 @@ typedef struct
+ // --------------------------------------------------------------------
+
+
+-//#define RXDES_NUM 64//64 // we defined 32 descriptor for OTG issue
++//#define RXDES_NUM 64//64 // we defined 32 descriptor for OTG issue
+ #define RXDES_NUM 32
+
+ #define RX_BUF_SIZE 1536
+@@ -464,6 +464,7 @@ typedef struct
+ #define PHYID_REVISION_MASK 0x0000000f
+ #define PHYID_VENDOR_MARVELL 0x01410c00
+ #define PHYID_VENDOR_BROADCOM 0x00406000
++#define PHYID_VENDOR_BCM5461X 0x03625c00
+ #define PHYID_VENDOR_REALTEK 0x001cc800
+
+ #define PHYID_BCM5221A4 0x004061e4
+@@ -521,7 +522,7 @@ struct ftgmac100_priv {
+ int tx_idx;
+ int old_tx;
+ struct sk_buff *tx_skbuff[TXDES_NUM];
+-
++
+ int maccr_val;
+ struct timer_list timer;
+ u32 GigaBit_MAHT0;
+@@ -533,7 +534,7 @@ struct ftgmac100_priv {
+ NCSI_Capability NCSI_Cap;
+ unsigned int InstanceID;
+ unsigned int Retry;
+- unsigned char Payload_Data[16];
++ unsigned char Payload_Data[64];
+ unsigned char Payload_Pad[4];
+ unsigned long Payload_Checksum;
+ int tx_free;
+@@ -575,7 +576,7 @@ struct ftgmac100_priv {
+ #define STOP_DONE (1 << 4)
+
+
+-
++
+ #endif /* _SMC_91111_H_ */
+
+
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/rtc/rtc-aspeed.c b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/rtc/rtc-aspeed.c
+index 477032e..de9e995 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/rtc/rtc-aspeed.c
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/rtc/rtc-aspeed.c
+@@ -7,11 +7,11 @@
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+@@ -67,8 +67,16 @@ ast_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+ {
+ struct ast_rtc *ast_rtc = dev_get_drvdata(dev);
+ pr_debug("cmd = 0x%08x, arg = 0x%08lx\n", cmd, arg);
+-
++
+ switch (cmd) {
++ case RTC_SET_TIME:
++ case RTC_RD_TIME:
++ case RTC_ALM_READ:
++ case RTC_ALM_SET:
++ {
++ // use rtc-dev.c fallback
++ return -ENOIOCTLCMD;
++ }
+ case RTC_AIE_ON: /* alarm on */
+ {
+ rtc_write(ast_rtc->base, rtc_read(ast_rtc->base, RTC_CONTROL) | ENABLE_ALL_ALARM, RTC_CONTROL);
+@@ -105,7 +113,7 @@ ast_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+ default:
+ return -ENOTTY;
+ }
+-
++
+ return 0;
+ }
+
+@@ -122,7 +130,7 @@ ast_rtc_get_time(struct device *dev, struct rtc_time *rtc_tm)
+
+ reg_time = rtc_read(ast_rtc->base, RTC_CNTR_STS_1);
+ reg_date = rtc_read(ast_rtc->base, RTC_CNTR_STS_2);
+-
++
+ spin_unlock_irqrestore(&ast_rtc->lock, flags);
+
+ rtc_tm->tm_year = GET_CENT_VAL(reg_date)*1000 | GET_YEAR_VAL(reg_date);
+@@ -132,7 +140,7 @@ ast_rtc_get_time(struct device *dev, struct rtc_time *rtc_tm)
+ rtc_tm->tm_hour = GET_HOUR_VAL(reg_time);
+ rtc_tm->tm_min = GET_MIN_VAL(reg_time);
+ rtc_tm->tm_sec = GET_SEC_VAL(reg_time);
+-
++
+ pr_debug("read time %02x.%02x.%02x %02x/%02x/%02x\n",
+ rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday,
+ rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec);
+@@ -155,7 +163,7 @@ ast_rtc_set_time(struct device *dev, struct rtc_time *tm)
+
+ /* set hours */
+ reg_time = SET_DAY_VAL(tm->tm_mday) | SET_HOUR_VAL(tm->tm_hour) | SET_MIN_VAL(tm->tm_min) | SET_SEC_VAL(tm->tm_sec);
+-
++
+ /* set century */
+ /* set mon */
+ reg_date = SET_CENT_VAL(tm->tm_year / 1000) | SET_YEAR_VAL(tm->tm_year % 1000) | SET_MON_VAL(tm->tm_mon);
+@@ -166,10 +174,10 @@ ast_rtc_set_time(struct device *dev, struct rtc_time *tm)
+ rtc_write(ast_rtc->base, reg_date, RTC_CNTR_STS_2);
+
+ rtc_write(ast_rtc->base, rtc_read(ast_rtc->base, RTC_CONTROL) &~RTC_LOCK , RTC_CONTROL);
+-
++
+ spin_unlock_irqrestore(&ast_rtc->lock, flags);
+
+- return 0;
++ return 0;
+ }
+ static int
+ ast_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+@@ -183,7 +191,7 @@ ast_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+ alarm_reg = rtc_read(ast_rtc->base, RTC_ALARM);
+ spin_unlock_irqrestore(&ast_rtc->lock, flags);
+
+-//DAY
++//DAY
+ alm_tm->tm_mday = GET_DAY_VAL(alarm_reg);
+
+ //HR
+@@ -221,7 +229,7 @@ ast_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+ if (tm->tm_mday <= 31 && tm->tm_mday >= 1) {
+ reg_alarm |= SET_DAY_VAL(tm->tm_mday);
+ }
+-
++
+ //HR
+ /* set ten hours */
+ if (tm->tm_hour <= 23 && tm->tm_hour >= 0) {
+@@ -245,8 +253,8 @@ ast_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+ spin_lock_irqsave(&ast_rtc->lock, flags);
+
+ rtc_write(ast_rtc->base, reg_alarm, RTC_ALARM);
+-
+- if(alarm->enabled)
++
++ if(alarm->enabled)
+ rtc_write(ast_rtc->base, reg_alarm, RTC_CONTROL);
+ else
+ rtc_write(ast_rtc->base, reg_alarm, RTC_CONTROL);
+@@ -366,14 +374,14 @@ static int __init ast_rtc_probe(struct platform_device *pdev)
+ ret = -EBUSY;
+ goto free_rtc;
+ }
+-
++
+ ast_rtc->base = ioremap(res->start, resource_size(res));
+ if (!ast_rtc->base) {
+ dev_err(&pdev->dev, "cannot map SocleDev registers\n");
+ ret = -ENOMEM;
+ goto release_mem;
+ }
+-
++
+ pr_debug("base = 0x%p, irq = %d\n", ast_rtc->base, ast_rtc->irq);
+
+ rtc_dev = rtc_device_register(pdev->name, &pdev->dev, &ast_rtcops, THIS_MODULE);
+@@ -381,7 +389,7 @@ static int __init ast_rtc_probe(struct platform_device *pdev)
+ ret = PTR_ERR(rtc_dev);
+ goto unmap;
+ }
+-
++
+ ast_rtc->res = res;
+ ast_rtc->rtc_dev = rtc_dev;
+ spin_lock_init(&ast_rtc->lock);
+@@ -406,7 +414,7 @@ static int __init ast_rtc_probe(struct platform_device *pdev)
+ printk("no need to enable RTC \n");
+
+ spin_unlock_irq(&ast_rtc->lock);
+-
++
+ /* register ISR */
+ ret = request_irq(ast_rtc->irq, ast_rtc_interrupt, IRQF_DISABLED, dev_name(&rtc_dev->dev), ast_rtc);
+ if (ret) {
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/serial/8250.c b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/serial/8250.c
+index a181ccf..f16da59 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/serial/8250.c
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/serial/8250.c
+@@ -38,6 +38,7 @@
+ #include <linux/serial_8250.h>
+ #include <linux/nmi.h>
+ #include <linux/mutex.h>
++#include <linux/gpio.h>
+
+ #include <asm/io.h>
+ #include <asm/irq.h>
+@@ -59,6 +60,8 @@ static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
+
+ static struct uart_driver serial8250_reg;
+
++DECLARE_WAIT_QUEUE_HEAD(thre_wait);
++
+ static int serial_index(struct uart_port *port)
+ {
+ return (serial8250_reg.minor - 64) + port->line;
+@@ -1225,7 +1228,10 @@ static void autoconfig_irq(struct uart_8250_port *up)
+
+ static inline void __stop_tx(struct uart_8250_port *p)
+ {
+- if (p->ier & UART_IER_THRI) {
++ int status = serial_in(p, UART_LSR);
++ // only turn off THRE interrupt if THRE is *currently* asserted
++ // (we still want to catch it a final time after the FIFO empties)
++ if ((p->ier & UART_IER_THRI) && (status & UART_LSR_THRE)) {
+ p->ier &= ~UART_IER_THRI;
+ serial_out(p, UART_IER, p->ier);
+ }
+@@ -1527,6 +1533,7 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
+
+ DEBUG_INTR("end.\n");
+
++ wake_up(&thre_wait);
+ return IRQ_RETVAL(handled);
+ }
+
+@@ -2526,6 +2533,35 @@ serial8250_type(struct uart_port *port)
+ return uart_config[type].name;
+ }
+
++static int serial8250_ioctl(struct uart_port *port, unsigned int cmd, unsigned long arg) {
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++ unsigned long flags;
++ int ret = -ENOIOCTLCMD;
++ // kernel-space RS485 drain-and-switch hack
++ if (cmd == TIOCSERWAITTEMT) {
++ // wait for kernel buffers and UART FIFO to both empty
++ struct circ_buf *xmit = &up->port.info->xmit;
++ wait_event_interruptible(
++ thre_wait,
++ uart_circ_empty(xmit) &&
++ (serial_in(up, UART_LSR) & UART_LSR_THRE));
++ // spin until TEMT (transmit shift register empty)
++ spin_lock_irqsave(&up->port.lock, flags);
++ wait_for_xmitr(up, BOTH_EMPTY);
++ if (arg != 0) {
++ // turn off RS485 DE pin
++ gpio_set_value(arg, 0);
++ }
++ // grab any phantom char seen on RX when transceiver switches
++ (void) serial_inp(up, UART_RX);
++ // enable read
++ up->port.ignore_status_mask &= ~UART_LSR_DR;
++ spin_unlock_irqrestore(&up->port.lock, flags);
++ return 0;
++ }
++ return ret;
++}
++
+ static struct uart_ops serial8250_pops = {
+ .tx_empty = serial8250_tx_empty,
+ .set_mctrl = serial8250_set_mctrl,
+@@ -2544,6 +2580,7 @@ static struct uart_ops serial8250_pops = {
+ .request_port = serial8250_request_port,
+ .config_port = serial8250_config_port,
+ .verify_port = serial8250_verify_port,
++ .ioctl = serial8250_ioctl,
+ #ifdef CONFIG_CONSOLE_POLL
+ .poll_get_char = serial8250_get_poll_char,
+ .poll_put_char = serial8250_put_poll_char,
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/watchdog/Kconfig b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/watchdog/Kconfig
+index 5702145..0b01ba8 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/watchdog/Kconfig
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/watchdog/Kconfig
+@@ -235,10 +235,17 @@ config ORION5X_WATCHDOG
+
+ config AST_WATCHDOG
+ tristate "ASPEED GUC watchdog"
+- depends on WATCHDOG
++ depends on WATCHDOG
+ help
+ Watchdog timer for ASPEED chips.
+
++config AST_WATCHDOG_REARM_DUAL_BOOT
++ bool "Rearm dual boot watchdog"
++ default n
++ depends on AST_WATCHDOG
++ help
++ Rearm dual boot watchdog or not during boot
++
+ # ARM26 Architecture
+
+ # AVR32 Architecture
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/watchdog/ast_wdt.c b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/watchdog/ast_wdt.c
+index 9e7e84f..e599a55 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/watchdog/ast_wdt.c
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/drivers/watchdog/ast_wdt.c
+@@ -68,6 +68,7 @@ typedef unsigned char bool_T;
+
+ #else
+ #define WDT_BASE_VA (IO_ADDRESS(AST_WDT_BASE))
++#define WDT2_BASE_VA (IO_ADDRESS(AST_WDT_BASE + 20))
+ #endif
+
+ #define WDT_CntSts (WDT_BASE_VA+0x00)
+@@ -78,6 +79,14 @@ typedef unsigned char bool_T;
+ #define WDT_Clr (WDT_BASE_VA+0x14)
+ #define WDT_RstWd (WDT_BASE_VA+0x18)
+
++#define WDT2_CntSts (WDT2_BASE_VA+0x00)
++#define WDT2_Reload (WDT2_BASE_VA+0x04)
++#define WDT2_Restart (WDT2_BASE_VA+0x08)
++#define WDT2_Ctrl (WDT2_BASE_VA+0x0C)
++#define WDT2_TimeOut (WDT2_BASE_VA+0x10)
++#define WDT2_Clr (WDT2_BASE_VA+0x14)
++#define WDT2_RstWd (WDT2_BASE_VA+0x18)
++
+ #define WDT_CTRL_B_SECOND_BOOT (0x1 << 7)
+ #define WDT_CTRL_B_RESET_SOC (0x00 << 5) /* yes, 0x00 */
+ #define WDT_CTRL_B_RESET_FULL (0x01 << 5)
+@@ -101,6 +110,11 @@ typedef unsigned char bool_T;
+ #define WDT_TIMO 30 /* Default heartbeat = 30 seconds */
+
+ #define WDT_INITIAL_TIMO (8*60) /* Initial timeout, 8m */
++/*
++ * Dual boot watchdog is 5s shorter so that dual boot watchdog
++ * will kick in first.
++ */
++#define WDT_DUAL_BOOT_TIMO (WDT_INITIAL_TIMO - 5)
+ #define WDT_TIMO2TICKS(t) (TICKS_PER_uSEC * 1000000 * (t))
+
+ static int heartbeat = WDT_TIMO;
+@@ -233,6 +247,14 @@ bool_T wdt_is_enabled(void)
+ return reg & WDT_CTRL_B_ENABLE;
+ }
+
++#ifdef CONFIG_AST_WATCHDOG_REARM_DUAL_BOOT
++void wdt_dual_boot_restart(unsigned int timeo)
++{
++ AST_WRITE_REG(WDT2_Reload, WDT_TIMO2TICKS(timeo));
++ AST_WRITE_REG(WDT2_Restart, 0x4755); /* reload! */
++ printk(KERN_INFO "Re-arm the dual boot watchdog for %u seconds\n", timeo);
++}
++#endif
+
+ void wdt_restart_new(unsigned int nPeriod, int sourceClk, bool_T bResetOut,
+ bool_T bIntrSys, bool_T bClrAfter, bool_T bResetARMOnly)
+@@ -542,6 +564,11 @@ static int ast_wdt_probe(struct platform_device *pdev)
+ return ret;
+ }
+
++#ifdef CONFIG_AST_WATCHDOG_REARM_DUAL_BOOT
++ /* re-arm dual boot watchdog */
++ wdt_dual_boot_restart(WDT_DUAL_BOOT_TIMO);
++#endif
++
+ /* interrupt the system while WDT timeout */
+ wdt_restart_new(WDT_TIMO2TICKS(WDT_INITIAL_TIMO), WDT_CLK_SRC_EXT,
+ /* No Ext, No intr, Self clear, Full chip reset */
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/fs/compat_ioctl.c b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/fs/compat_ioctl.c
+index 61cb48f..5dc69ab 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/fs/compat_ioctl.c
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/fs/compat_ioctl.c
+@@ -3,7 +3,7 @@
+ *
+ * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com)
+ * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
+- * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs
++ * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs
+ * Copyright (C) 2003 Pavel Machek (pavel@suse.cz)
+ *
+ * These routines maintain argument size conversion between 32bit and 64bit
+@@ -125,7 +125,7 @@ static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
+ mm_segment_t old_fs = get_fs();
+ int err;
+ unsigned long val;
+-
++
+ set_fs (KERNEL_DS);
+ err = sys_ioctl(fd, cmd, (unsigned long)&val);
+ set_fs (old_fs);
+@@ -133,14 +133,14 @@ static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
+ return -EFAULT;
+ return err;
+ }
+-
++
+ static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg)
+ {
+ mm_segment_t old_fs = get_fs();
+ u32 __user *argptr = compat_ptr(arg);
+ int err;
+ unsigned long val;
+-
++
+ if(get_user(val, argptr))
+ return -EFAULT;
+ set_fs (KERNEL_DS);
+@@ -365,17 +365,17 @@ static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
+ if (copy_in_user(ifr, ifr32, sizeof(struct ifreq32)))
+ return -EFAULT;
+ ifr++;
+- ifr32++;
++ ifr32++;
+ }
+ }
+ if (copy_to_user(uifc, &ifc, sizeof(struct ifconf)))
+ return -EFAULT;
+
+- err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)uifc);
++ err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)uifc);
+ if (err)
+ return err;
+
+- if (copy_from_user(&ifc, uifc, sizeof(struct ifconf)))
++ if (copy_from_user(&ifc, uifc, sizeof(struct ifconf)))
+ return -EFAULT;
+
+ ifr = ifc.ifc_req;
+@@ -411,7 +411,7 @@ static int ethtool_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+ struct ifreq32 __user *ifr32;
+ u32 data;
+ void __user *datap;
+-
++
+ ifr = compat_alloc_user_space(sizeof(*ifr));
+ ifr32 = compat_ptr(arg);
+
+@@ -507,7 +507,7 @@ static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
+ struct ifmap32 __user *uifmap32;
+ mm_segment_t old_fs;
+ int err;
+-
++
+ uifr32 = compat_ptr(arg);
+ uifmap32 = &uifr32->ifr_ifru.ifru_map;
+ switch (cmd) {
+@@ -610,7 +610,7 @@ static int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+ char devname[16];
+ u32 rtdev;
+ mm_segment_t old_fs = get_fs();
+-
++
+ struct socket *mysock = sockfd_lookup(fd, &ret);
+
+ if (mysock && mysock->sk && mysock->sk->sk_family == AF_INET6) { /* ipv6 */
+@@ -624,7 +624,7 @@ static int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+ ret |= __get_user (r6.rtmsg_info, &(ur6->rtmsg_info));
+ ret |= __get_user (r6.rtmsg_flags, &(ur6->rtmsg_flags));
+ ret |= __get_user (r6.rtmsg_ifindex, &(ur6->rtmsg_ifindex));
+-
++
+ r = (void *) &r6;
+ } else { /* ipv4 */
+ struct rtentry32 __user *ur4 = compat_ptr(arg);
+@@ -1046,14 +1046,14 @@ static int vt_check(struct file *file)
+ struct tty_struct *tty;
+ struct inode *inode = file->f_path.dentry->d_inode;
+ struct vc_data *vc;
+-
++
+ if (file->f_op->unlocked_ioctl != tty_ioctl)
+ return -EINVAL;
+-
++
+ tty = (struct tty_struct *)file->private_data;
+ if (tty_paranoia_check(tty, inode, "tty_ioctl"))
+ return -EINVAL;
+-
++
+ if (tty->ops->ioctl != vt_ioctl)
+ return -EINVAL;
+
+@@ -1067,7 +1067,7 @@ static int vt_check(struct file *file)
+ */
+ if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
+ return 1;
+- return 0;
++ return 0;
+ }
+
+ struct consolefontdesc32 {
+@@ -1085,7 +1085,7 @@ static int do_fontx_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg,
+
+ perm = vt_check(file);
+ if (perm < 0) return perm;
+-
++
+ switch (cmd) {
+ case PIO_FONTX:
+ if (!perm)
+@@ -1130,16 +1130,16 @@ struct console_font_op32 {
+ compat_uint_t charcount;
+ compat_caddr_t data; /* font data with height fixed to 32 */
+ };
+-
++
+ static int do_kdfontop_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file)
+ {
+ struct console_font_op op;
+ struct console_font_op32 __user *fontop = compat_ptr(arg);
+ int perm = vt_check(file), i;
+ struct vc_data *vc;
+-
++
+ if (perm < 0) return perm;
+-
++
+ if (copy_from_user(&op, fontop, sizeof(struct console_font_op32)))
+ return -EFAULT;
+ if (!perm && op.op != KD_FONT_OP_GET)
+@@ -1303,7 +1303,7 @@ static int do_atmif_sioc(unsigned int fd, unsigned int cmd, unsigned long arg)
+ u32 data;
+ void __user *datap;
+ int err;
+-
++
+ sioc = compat_alloc_user_space(sizeof(*sioc));
+ sioc32 = compat_ptr(arg);
+
+@@ -1328,7 +1328,7 @@ static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg)
+ {
+ int i;
+ unsigned int cmd = 0;
+-
++
+ switch (cmd32) {
+ case SONET_GETSTAT:
+ case SONET_GETSTATZ:
+@@ -1349,11 +1349,11 @@ static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg)
+ }
+ if (i == NR_ATM_IOCTL)
+ return -EINVAL;
+-
++
+ switch (cmd) {
+ case ATM_GETNAMES:
+ return do_atm_iobuf(fd, cmd, arg);
+-
++
+ case ATM_GETLINKRATE:
+ case ATM_GETTYPE:
+ case ATM_GETESI:
+@@ -1444,7 +1444,7 @@ static int mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg)
+ }
+
+ return err;
+-}
++}
+
+ #ifdef CONFIG_BLOCK
+ struct raw32_config_request
+@@ -1798,7 +1798,7 @@ static int rtc_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
+ val32 = kval;
+ return put_user(val32, (unsigned int __user *)arg);
+ case RTC_IRQP_SET32:
+- return sys_ioctl(fd, RTC_IRQP_SET, arg);
++ return sys_ioctl(fd, RTC_IRQP_SET, arg);
+ case RTC_EPOCH_SET32:
+ return sys_ioctl(fd, RTC_EPOCH_SET, arg);
+ default:
+@@ -2678,6 +2678,7 @@ COMPATIBLE_IOCTL(USBDEVFS_IOCTL32)
+ /* i2c */
+ HANDLE_IOCTL(I2C_FUNCS, w_long)
+ HANDLE_IOCTL(I2C_RDWR, do_i2c_rdwr_ioctl)
++HANDLE_IOCTL(I2C_SLAVE_RDWR, do_i2c_rdwr_ioctl)
+ HANDLE_IOCTL(I2C_SMBUS, do_i2c_smbus_ioctl)
+ /* bridge */
+ HANDLE_IOCTL(SIOCSIFBR, old_bridge_ioctl)
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/include/linux/i2c-dev.h b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/include/linux/i2c-dev.h
+index 311315b..ed9b48d 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/include/linux/i2c-dev.h
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/include/linux/i2c-dev.h
+@@ -46,6 +46,7 @@
+ #define I2C_FUNCS 0x0705 /* Get the adapter functionality mask */
+
+ #define I2C_RDWR 0x0707 /* Combined R/W transfer (one STOP only) */
++#define I2C_SLAVE_RDWR 0x0709 /* Slave Read Write */
+
+ #define I2C_PEC 0x0708 /* != 0 to use PEC with SMBus */
+ #define I2C_SMBUS 0x0720 /* SMBus transfer */
+diff --git a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/include/linux/i2c.h b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/include/linux/i2c.h
+index 59167e2..f037cde 100644
+--- a/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/include/linux/i2c.h
++++ b/meta-aspeed/recipes-kernel/linux/files/linux-aspeed-2.6.28.9/include/linux/i2c.h
+@@ -62,6 +62,9 @@ extern int i2c_master_recv(struct i2c_client *client, char *buf, int count);
+ extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+ int num);
+
++extern int i2c_slave_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
++ int num);
++
+ /* This is the very generalized SMBus access routine. You probably do not
+ want to use this, though; one of the functions below may be much easier,
+ and probably just as fast.
+@@ -333,6 +336,7 @@ struct i2c_algorithm {
+ processed, or a negative value on error */
+ int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,
+ int num);
++ int (*slave_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs);
+ int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,
+ unsigned short flags, char read_write,
+ u8 command, int size, union i2c_smbus_data *data);
+@@ -516,6 +520,8 @@ struct i2c_msg {
+ __u16 flags;
+ #define I2C_M_TEN 0x0010 /* this is a ten bit chip address */
+ #define I2C_M_RD 0x0001 /* read data, from slave to master */
++#define I2C_S_EN 0x0002 /* Slave Enable */
++#define I2C_S_ALT 0x0004 /* Slave Alert */
+ #define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */
+ #define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */
+ #define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
+diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0029-mtd-m25p80-Add-support-for-the-Winbond-W25Q64.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0029-mtd-m25p80-Add-support-for-the-Winbond-W25Q64.patch
+new file mode 100644
+index 0000000..52aef04
+--- /dev/null
++++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0029-mtd-m25p80-Add-support-for-the-Winbond-W25Q64.patch
+@@ -0,0 +1,29 @@
++From d2ac467a108400ff1ae682a423c7d41265e62d47 Mon Sep 17 00:00:00 2001
++From: Thierry Reding <thierry.reding@avionic-design.de>
++Date: Mon, 30 Aug 2010 13:00:48 +0200
++Subject: [PATCH] mtd: m25p80: Add support for the Winbond W25Q64
++
++This patch adds support for the Winbond W25Q64 serial flash.
++
++Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
++Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
++Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
++---
++ drivers/mtd/devices/m25p80.c | 1 +
++ 1 file changed, 1 insertion(+)
++
++diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
++index 1f0f703..b6fd7c2 100644
++--- a/drivers/mtd/devices/m25p80.c
+++++ b/drivers/mtd/devices/m25p80.c
++@@ -716,6 +716,7 @@ static const struct spi_device_id m25p_ids[] = {
++ { "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) },
++ { "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) },
++ { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
+++ { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
++
++ /* Catalyst / On Semiconductor -- non-JEDEC */
++ { "cat25c11", CAT25_INFO( 16, 8, 16, 1) },
++--
++1.8.5.6
++
+diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0030-net-Don-t-leak-packets-when-a-netns-is-going-down.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0030-net-Don-t-leak-packets-when-a-netns-is-going-down.patch
+new file mode 100644
+index 0000000..ad04217
+--- /dev/null
++++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0030-net-Don-t-leak-packets-when-a-netns-is-going-down.patch
+@@ -0,0 +1,56 @@
++From 0a36b345ab99d6b3c96999e7e3b79bd243cf9bf7 Mon Sep 17 00:00:00 2001
++From: "Eric W. Biederman" <ebiederm@xmission.com>
++Date: Wed, 5 Nov 2008 16:00:24 -0800
++Subject: [PATCH] net: Don't leak packets when a netns is going down
++
++I have been tracking for a while a case where when the
++network namespace exits the cleanup gets stck in an
++endless precessess of:
++
++unregister_netdevice: waiting for lo to become free. Usage count = 3
++unregister_netdevice: waiting for lo to become free. Usage count = 3
++unregister_netdevice: waiting for lo to become free. Usage count = 3
++unregister_netdevice: waiting for lo to become free. Usage count = 3
++unregister_netdevice: waiting for lo to become free. Usage count = 3
++unregister_netdevice: waiting for lo to become free. Usage count = 3
++unregister_netdevice: waiting for lo to become free. Usage count = 3
++
++It turns out that if you listen on a multicast address an unsubscribe
++packet is sent when the network device goes down. If you shutdown
++the network namespace without carefully cleaning up this can trigger
++the unsubscribe packet to be sent over the loopback interface while
++the network namespace is going down.
++
++All of which is fine except when we drop the packet and forget to
++free it leaking the skb and the dst entry attached to. As it
++turns out the dst entry hold a reference to the idev which holds
++the dev and keeps everything from being cleaned up. Yuck!
++
++By fixing my earlier thinko and add the needed kfree_skb and everything
++cleans up beautifully.
++
++Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
++Signed-off-by: David S. Miller <davem@davemloft.net>
++---
++ net/core/dev.c | 4 +++-
++ 1 file changed, 3 insertions(+), 1 deletion(-)
++
++diff --git a/net/core/dev.c b/net/core/dev.c
++index 811507c..a0c60607 100644
++--- a/net/core/dev.c
+++++ b/net/core/dev.c
++@@ -2253,8 +2253,10 @@ int netif_receive_skb(struct sk_buff *skb)
++ rcu_read_lock();
++
++ /* Don't receive packets in an exiting network namespace */
++- if (!net_alive(dev_net(skb->dev)))
+++ if (!net_alive(dev_net(skb->dev))) {
+++ kfree_skb(skb);
++ goto out;
+++ }
++
++ #ifdef CONFIG_NET_CLS_ACT
++ if (skb->tc_verd & TC_NCLS) {
++--
++1.8.1
++
+diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0031-IPv6-Print-error-value-when-skb-allocation-fails.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0031-IPv6-Print-error-value-when-skb-allocation-fails.patch
+new file mode 100644
+index 0000000..b638996
+--- /dev/null
++++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0031-IPv6-Print-error-value-when-skb-allocation-fails.patch
+@@ -0,0 +1,43 @@
++From 5777cee30776da63ecbe2b6d4929e01d82c7d72e Mon Sep 17 00:00:00 2001
++From: Brian Haley <brian.haley@hp.com>
++Date: Tue, 2 Jun 2009 00:20:26 -0700
++Subject: [PATCH] IPv6: Print error value when skb allocation fails
++
++Print-out the error value when sock_alloc_send_skb() fails in
++the IPv6 neighbor discovery code - can be useful for debugging.
++
++Signed-off-by: Brian Haley <brian.haley@hp.com>
++Signed-off-by: David S. Miller <davem@davemloft.net>
++---
++ net/ipv6/ndisc.c | 8 ++++----
++ 1 file changed, 4 insertions(+), 4 deletions(-)
++
++diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
++index d0f54d1..45529b1 100644
++--- a/net/ipv6/ndisc.c
+++++ b/net/ipv6/ndisc.c
++@@ -483,8 +483,8 @@ static void __ndisc_send(struct net_device *dev,
++ 1, &err);
++ if (!skb) {
++ ND_PRINTK0(KERN_ERR
++- "ICMPv6 ND: %s() failed to allocate an skb.\n",
++- __func__);
+++ "ICMPv6 ND: %s() failed to allocate an skb, err=%d.\n",
+++ __func__, err);
++ dst_release(dst);
++ return;
++ }
++@@ -1533,8 +1533,8 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
++ 1, &err);
++ if (buff == NULL) {
++ ND_PRINTK0(KERN_ERR
++- "ICMPv6 Redirect: %s() failed to allocate an skb.\n",
++- __func__);
+++ "ICMPv6 Redirect: %s() failed to allocate an skb, err=%d.\n",
+++ __func__, err);
++ dst_release(dst);
++ return;
++ }
++--
++1.8.1
++
+diff --git a/meta-aspeed/recipes-kernel/linux/linux-aspeed_2.6.28.9.bb b/meta-aspeed/recipes-kernel/linux/linux-aspeed_2.6.28.9.bb
+index 54f410a..c61e0c2 100644
+--- a/meta-aspeed/recipes-kernel/linux/linux-aspeed_2.6.28.9.bb
++++ b/meta-aspeed/recipes-kernel/linux/linux-aspeed_2.6.28.9.bb
+@@ -15,6 +15,9 @@ SRC_URI = "file://linux-aspeed-2.6.28.9 \
+ file://patch-2.6.28.9/0026-mtd-m25p80-modify-info-for-Micron-N25Q128.patch \
+ file://patch-2.6.28.9/0027-mtd-m25p80-n25q064-is-Micron-not-Intel-Numonyx.patch \
+ file://patch-2.6.28.9/0028-ipv6-Plug-sk_buff-leak-in-ipv6_rcv-net-ipv6-ip6_inpu.patch \
++ file://patch-2.6.28.9/0029-mtd-m25p80-Add-support-for-the-Winbond-W25Q64.patch \
++ file://patch-2.6.28.9/0030-net-Don-t-leak-packets-when-a-netns-is-going-down.patch \
++ file://patch-2.6.28.9/0031-IPv6-Print-error-value-when-skb-allocation-fails.patch \
+ file://patch-2.6.28.9/0001-bzip2-lzma-library-support-for-gzip-bzip2-and-lzma-d.patch \
+ file://patch-2.6.28.9/0002-bzip2-lzma-config-and-initramfs-support-for-bzip2-lz.patch \
+ "
+@@ -25,6 +28,16 @@ LINUX_VERSION_EXTENSION ?= "-aspeed"
+ PR = "r1"
+ PV = "${LINUX_VERSION}"
+
+-KERNEL_CONFIG_COMMAND = "oe_runmake wedge_defconfig && oe_runmake oldconfig"
+-
+ include linux-aspeed.inc
++
++# Install bounds.h for external module install
++# The default install script handles this. However, it looks for bounds.h from
++# 'include/generated', which doesnot match 2.6.28, where the file is in
++# 'include/linux'.
++do_install[postfuncs] += "install_bounds_h"
++install_bounds_h() {
++ kerneldir=${D}${KERNEL_SRC_PATH}
++ if [ -f include/linux/bounds.h ]; then
++ cp -l include/linux/bounds.h $kerneldir/include/linux/bounds.h
++ fi
++}
+--
+1.8.1
+
diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0029-mtd-m25p80-Add-support-for-the-Winbond-W25Q64.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0029-mtd-m25p80-Add-support-for-the-Winbond-W25Q64.patch
new file mode 100644
index 0000000..52aef04
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0029-mtd-m25p80-Add-support-for-the-Winbond-W25Q64.patch
@@ -0,0 +1,29 @@
+From d2ac467a108400ff1ae682a423c7d41265e62d47 Mon Sep 17 00:00:00 2001
+From: Thierry Reding <thierry.reding@avionic-design.de>
+Date: Mon, 30 Aug 2010 13:00:48 +0200
+Subject: [PATCH] mtd: m25p80: Add support for the Winbond W25Q64
+
+This patch adds support for the Winbond W25Q64 serial flash.
+
+Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
+Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
+Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
+---
+ drivers/mtd/devices/m25p80.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
+index 1f0f703..b6fd7c2 100644
+--- a/drivers/mtd/devices/m25p80.c
++++ b/drivers/mtd/devices/m25p80.c
+@@ -716,6 +716,7 @@ static const struct spi_device_id m25p_ids[] = {
+ { "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) },
+ { "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) },
+ { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
++ { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
+
+ /* Catalyst / On Semiconductor -- non-JEDEC */
+ { "cat25c11", CAT25_INFO( 16, 8, 16, 1) },
+--
+1.8.5.6
+
diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0030-net-Don-t-leak-packets-when-a-netns-is-going-down.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0030-net-Don-t-leak-packets-when-a-netns-is-going-down.patch
new file mode 100644
index 0000000..ad04217
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0030-net-Don-t-leak-packets-when-a-netns-is-going-down.patch
@@ -0,0 +1,56 @@
+From 0a36b345ab99d6b3c96999e7e3b79bd243cf9bf7 Mon Sep 17 00:00:00 2001
+From: "Eric W. Biederman" <ebiederm@xmission.com>
+Date: Wed, 5 Nov 2008 16:00:24 -0800
+Subject: [PATCH] net: Don't leak packets when a netns is going down
+
+I have been tracking for a while a case where when the
+network namespace exits the cleanup gets stck in an
+endless precessess of:
+
+unregister_netdevice: waiting for lo to become free. Usage count = 3
+unregister_netdevice: waiting for lo to become free. Usage count = 3
+unregister_netdevice: waiting for lo to become free. Usage count = 3
+unregister_netdevice: waiting for lo to become free. Usage count = 3
+unregister_netdevice: waiting for lo to become free. Usage count = 3
+unregister_netdevice: waiting for lo to become free. Usage count = 3
+unregister_netdevice: waiting for lo to become free. Usage count = 3
+
+It turns out that if you listen on a multicast address an unsubscribe
+packet is sent when the network device goes down. If you shutdown
+the network namespace without carefully cleaning up this can trigger
+the unsubscribe packet to be sent over the loopback interface while
+the network namespace is going down.
+
+All of which is fine except when we drop the packet and forget to
+free it leaking the skb and the dst entry attached to. As it
+turns out the dst entry hold a reference to the idev which holds
+the dev and keeps everything from being cleaned up. Yuck!
+
+By fixing my earlier thinko and add the needed kfree_skb and everything
+cleans up beautifully.
+
+Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ net/core/dev.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 811507c..a0c60607 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -2253,8 +2253,10 @@ int netif_receive_skb(struct sk_buff *skb)
+ rcu_read_lock();
+
+ /* Don't receive packets in an exiting network namespace */
+- if (!net_alive(dev_net(skb->dev)))
++ if (!net_alive(dev_net(skb->dev))) {
++ kfree_skb(skb);
+ goto out;
++ }
+
+ #ifdef CONFIG_NET_CLS_ACT
+ if (skb->tc_verd & TC_NCLS) {
+--
+1.8.1
+
diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0031-IPv6-Print-error-value-when-skb-allocation-fails.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0031-IPv6-Print-error-value-when-skb-allocation-fails.patch
new file mode 100644
index 0000000..b638996
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0031-IPv6-Print-error-value-when-skb-allocation-fails.patch
@@ -0,0 +1,43 @@
+From 5777cee30776da63ecbe2b6d4929e01d82c7d72e Mon Sep 17 00:00:00 2001
+From: Brian Haley <brian.haley@hp.com>
+Date: Tue, 2 Jun 2009 00:20:26 -0700
+Subject: [PATCH] IPv6: Print error value when skb allocation fails
+
+Print-out the error value when sock_alloc_send_skb() fails in
+the IPv6 neighbor discovery code - can be useful for debugging.
+
+Signed-off-by: Brian Haley <brian.haley@hp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ net/ipv6/ndisc.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
+index d0f54d1..45529b1 100644
+--- a/net/ipv6/ndisc.c
++++ b/net/ipv6/ndisc.c
+@@ -483,8 +483,8 @@ static void __ndisc_send(struct net_device *dev,
+ 1, &err);
+ if (!skb) {
+ ND_PRINTK0(KERN_ERR
+- "ICMPv6 ND: %s() failed to allocate an skb.\n",
+- __func__);
++ "ICMPv6 ND: %s() failed to allocate an skb, err=%d.\n",
++ __func__, err);
+ dst_release(dst);
+ return;
+ }
+@@ -1533,8 +1533,8 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
+ 1, &err);
+ if (buff == NULL) {
+ ND_PRINTK0(KERN_ERR
+- "ICMPv6 Redirect: %s() failed to allocate an skb.\n",
+- __func__);
++ "ICMPv6 Redirect: %s() failed to allocate an skb, err=%d.\n",
++ __func__, err);
+ dst_release(dst);
+ return;
+ }
+--
+1.8.1
+
diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0032-Create-snapshot-of-OpenBMC.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0032-Create-snapshot-of-OpenBMC.patch
new file mode 100644
index 0000000..f84dc62
--- /dev/null
+++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0032-Create-snapshot-of-OpenBMC.patch
@@ -0,0 +1,8462 @@
+From 19459c799ac0a521082d6d79e68ffc3decb18ea2 Mon Sep 17 00:00:00 2001
+From: Ori Bernstein <orib@fb.com>
+Date: Thu, 3 Sep 2015 11:28:27 -0700
+Subject: [PATCH] Create snapshot of OpenBMC
+
+---
+ .../arch/arm/configs/wedge_defconfig | 1 +
+ .../arch/arm/configs/yosemite_defconfig | 1480 ++++++++++++++++++++
+ .../arch/arm/include/asm/ioctls.h | 1 +
+ .../arch/arm/mach-aspeed/Kconfig | 12 +
+ .../arch/arm/mach-aspeed/gpio.c | 2 +-
+ .../arm/mach-aspeed/include/mach/debug-macro.S | 4 +-
+ .../arch/arm/mach-aspeed/include/mach/platform.h | 17 +-
+ .../arch/arm/mach-aspeed/include/mach/uncompress.h | 6 +-
+ .../arch/arm/mach-aspeed/include/mach/vmalloc.h | 4 +-
+ .../arch/arm/plat-aspeed/ast-scu.c | 372 ++---
+ .../arch/arm/plat-aspeed/dev-eth.c | 35 +-
+ .../arch/arm/plat-aspeed/dev-i2c.c | 385 +++--
+ .../arch/arm/plat-aspeed/dev-spi.c | 27 +-
+ .../arch/arm/plat-aspeed/dev-uart.c | 50 +-
+ .../arch/arm/plat-aspeed/irq.c | 28 +-
+ .../linux-aspeed-2.6.28.9/drivers/hwmon/ast_adc.c | 233 +--
+ .../drivers/i2c/busses/i2c-ast.c | 689 +++++----
+ .../linux-aspeed-2.6.28.9/drivers/i2c/i2c-core.c | 15 +-
+ .../linux-aspeed-2.6.28.9/drivers/i2c/i2c-dev.c | 113 +-
+ .../drivers/net/ftgmac100_26.c | 1211 ++++++++++++++--
+ .../drivers/net/ftgmac100_26.h | 67 +-
+ .../linux-aspeed-2.6.28.9/drivers/rtc/rtc-aspeed.c | 42 +-
+ .../linux-aspeed-2.6.28.9/drivers/serial/8250.c | 39 +-
+ .../linux-aspeed-2.6.28.9/drivers/watchdog/Kconfig | 9 +-
+ .../drivers/watchdog/ast_wdt.c | 27 +
+ .../files/linux-aspeed-2.6.28.9/fs/compat_ioctl.c | 51 +-
+ .../linux-aspeed-2.6.28.9/include/linux/i2c-dev.h | 1 +
+ .../linux-aspeed-2.6.28.9/include/linux/i2c.h | 6 +
+ ...m25p80-Add-support-for-the-Winbond-W25Q64.patch | 29 +
+ ...t-leak-packets-when-a-netns-is-going-down.patch | 56 +
+ ...int-error-value-when-skb-allocation-fails.patch | 43 +
+ .../recipes-kernel/linux/linux-aspeed_2.6.28.9.bb | 17 +-
+ 34 files changed, 7064 insertions(+), 950 deletions(-)
+ create mode 100644 arch/arm/configs/fbplatform1_defconfig
+ create mode 100644 arch/arm/configs/yosemite_defconfig
+ create mode 100644 meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0029-mtd-m25p80-Add-support-for-the-Winbond-W25Q64.patch
+ create mode 100644 meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0030-net-Don-t-leak-packets-when-a-netns-is-going-down.patch
+ create mode 100644 meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0031-IPv6-Print-error-value-when-skb-allocation-fails.patch
+
+diff --git a/arch/arm/configs/wedge_defconfig b/arch/arm/configs/wedge_defconfig
+index 23a9fe3..41fe288 100644
+--- a/arch/arm/configs/wedge_defconfig
++++ b/arch/arm/configs/wedge_defconfig
+@@ -174,6 +174,7 @@ CONFIG_IRMP=y
+ # CONFIG_ARCH_AST2200 is not set
+ # CONFIG_ARCH_AST2300 is not set
+ CONFIG_ARCH_AST2400=y
++CONFIG_WEDGE=y
+ # CONFIG_ARCH_AST2500 is not set
+
+ #
+diff --git a/arch/arm/configs/yosemite_defconfig b/arch/arm/configs/yosemite_defconfig
+new file mode 100644
+index 0000000..d32f18e
+--- /dev/null
++++ b/arch/arm/configs/yosemite_defconfig
+@@ -0,0 +1,1480 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.28.9
++# Tue Feb 3 16:41:40 2015
++#
++CONFIG_ARM=y
++CONFIG_SYS_SUPPORTS_APM_EMULATION=y
++CONFIG_GENERIC_GPIO=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_CLOCKEVENTS=y
++CONFIG_MMU=y
++# CONFIG_NO_IOPORT is not set
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_STACKTRACE_SUPPORT=y
++CONFIG_HAVE_LATENCYTOP_SUPPORT=y
++CONFIG_LOCKDEP_SUPPORT=y
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++# CONFIG_ARCH_HAS_ILOG2_U32 is not set
++# CONFIG_ARCH_HAS_ILOG2_U64 is not set
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
++CONFIG_VECTORS_BASE=0xffff0000
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# General setup
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_KERNEL_GZIP=y
++# CONFIG_KERNEL_BZIP2 is not set
++# CONFIG_KERNEL_LZMA is not set
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_SYSVIPC_SYSCTL=y
++CONFIG_POSIX_MQUEUE=y
++# CONFIG_BSD_PROCESS_ACCT is not set
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++CONFIG_IKCONFIG=m
++CONFIG_IKCONFIG_PROC=y
++CONFIG_LOG_BUF_SHIFT=16
++# CONFIG_CGROUPS is not set
++# CONFIG_GROUP_SCHED is not set
++CONFIG_SYSFS_DEPRECATED=y
++CONFIG_SYSFS_DEPRECATED_V2=y
++# CONFIG_RELAY is not set
++CONFIG_NAMESPACES=y
++# CONFIG_UTS_NS is not set
++# CONFIG_IPC_NS is not set
++# CONFIG_USER_NS is not set
++# CONFIG_PID_NS is not set
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_SYSCTL=y
++CONFIG_ANON_INODES=y
++# CONFIG_EMBEDDED is not set
++CONFIG_UID16=y
++CONFIG_SYSCTL_SYSCALL=y
++CONFIG_KALLSYMS=y
++CONFIG_KALLSYMS_EXTRA_PASS=y
++CONFIG_HOTPLUG=y
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_ELF_CORE=y
++CONFIG_BASE_FULL=y
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SIGNALFD=y
++CONFIG_TIMERFD=y
++CONFIG_EVENTFD=y
++CONFIG_SHMEM=y
++CONFIG_AIO=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_SLUB_DEBUG=y
++CONFIG_COMPAT_BRK=y
++# CONFIG_SLAB is not set
++CONFIG_SLUB=y
++# CONFIG_SLOB is not set
++# CONFIG_PROFILING is not set
++# CONFIG_MARKERS is not set
++CONFIG_HAVE_OPROFILE=y
++# CONFIG_KPROBES is not set
++CONFIG_HAVE_KPROBES=y
++CONFIG_HAVE_KRETPROBES=y
++CONFIG_HAVE_GENERIC_DMA_COHERENT=y
++CONFIG_SLABINFO=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
++CONFIG_MODULES=y
++# CONFIG_MODULE_FORCE_LOAD is not set
++CONFIG_MODULE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++CONFIG_BLOCK=y
++# CONFIG_LBD is not set
++# CONFIG_BLK_DEV_IO_TRACE is not set
++# CONFIG_LSF is not set
++# CONFIG_BLK_DEV_BSG is not set
++# CONFIG_BLK_DEV_INTEGRITY is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_DEFAULT_AS is not set
++# CONFIG_DEFAULT_DEADLINE is not set
++CONFIG_DEFAULT_CFQ=y
++# CONFIG_DEFAULT_NOOP is not set
++CONFIG_DEFAULT_IOSCHED="cfq"
++CONFIG_CLASSIC_RCU=y
++CONFIG_FREEZER=y
++
++#
++# System Type
++#
++CONFIG_ARCH_ASPEED=y
++# CONFIG_ARCH_AAEC2000 is not set
++# CONFIG_ARCH_INTEGRATOR is not set
++# CONFIG_ARCH_REALVIEW is not set
++# CONFIG_ARCH_VERSATILE is not set
++# CONFIG_ARCH_AT91 is not set
++# CONFIG_ARCH_CLPS7500 is not set
++# CONFIG_ARCH_CLPS711X is not set
++# CONFIG_ARCH_EBSA110 is not set
++# CONFIG_ARCH_EP93XX is not set
++# CONFIG_ARCH_FOOTBRIDGE is not set
++# CONFIG_ARCH_NETX is not set
++# CONFIG_ARCH_H720X is not set
++# CONFIG_ARCH_IMX is not set
++# CONFIG_ARCH_IOP13XX is not set
++# CONFIG_ARCH_IOP32X is not set
++# CONFIG_ARCH_IOP33X is not set
++# CONFIG_ARCH_IXP23XX is not set
++# CONFIG_ARCH_IXP2000 is not set
++# CONFIG_ARCH_IXP4XX is not set
++# CONFIG_ARCH_L7200 is not set
++# CONFIG_ARCH_KIRKWOOD is not set
++# CONFIG_ARCH_KS8695 is not set
++# CONFIG_ARCH_NS9XXX is not set
++# CONFIG_ARCH_LOKI is not set
++# CONFIG_ARCH_MV78XX0 is not set
++# CONFIG_ARCH_MXC is not set
++# CONFIG_ARCH_ORION5X is not set
++# CONFIG_ARCH_PNX4008 is not set
++# CONFIG_ARCH_PXA is not set
++# CONFIG_ARCH_RPC is not set
++# CONFIG_ARCH_SA1100 is not set
++# CONFIG_ARCH_S3C2410 is not set
++# CONFIG_ARCH_SHARK is not set
++# CONFIG_ARCH_LH7A40X is not set
++# CONFIG_ARCH_DAVINCI is not set
++# CONFIG_ARCH_OMAP is not set
++# CONFIG_ARCH_MSM is not set
++CONFIG_IRMP=y
++# CONFIG_PCEXT is not set
++# CONFIG_REMOTEFX is not set
++# CONFIG_ARCH_AST1100 is not set
++# CONFIG_ARCH_AST2100 is not set
++# CONFIG_ARCH_AST2200 is not set
++# CONFIG_ARCH_AST2300 is not set
++CONFIG_ARCH_AST2400=y
++CONFIG_YOSEMITE=y
++# CONFIG_ARCH_AST2500 is not set
++
++#
++# FLASH Chip Select
++#
++# CONFIG_AST_CS0_NOR is not set
++# CONFIG_AST_CS0_NAND is not set
++CONFIG_AST_CS0_SPI=y
++# CONFIG_AST_CS0_NONE is not set
++# CONFIG_AST_CS1_NOR is not set
++# CONFIG_AST_CS1_NAND is not set
++# CONFIG_AST_CS1_SPI is not set
++CONFIG_AST_CS1_NONE=y
++# CONFIG_AST_CS2_NOR is not set
++# CONFIG_AST_CS2_NAND is not set
++# CONFIG_AST_CS2_SPI is not set
++CONFIG_AST_CS2_NONE=y
++# CONFIG_AST_CS3_NOR is not set
++# CONFIG_AST_CS3_NAND is not set
++# CONFIG_AST_CS3_SPI is not set
++CONFIG_AST_CS3_NONE=y
++# CONFIG_AST_CS4_NOR is not set
++# CONFIG_AST_CS4_NAND is not set
++# CONFIG_AST_CS4_SPI is not set
++CONFIG_AST_CS4_NONE=y
++# CONFIG_ARCH_AST1070 is not set
++# CONFIG_AST_SCU_LOCK is not set
++
++#
++# Boot options
++#
++
++#
++# Power management
++#
++CONFIG_PLAT_ASPEED=y
++
++#
++# Processor Type
++#
++CONFIG_CPU_32=y
++CONFIG_CPU_ARM926T=y
++CONFIG_CPU_32v5=y
++CONFIG_CPU_ABRT_EV5TJ=y
++CONFIG_CPU_PABRT_NOIFAR=y
++CONFIG_CPU_CACHE_VIVT=y
++CONFIG_CPU_COPY_V4WB=y
++CONFIG_CPU_TLB_V4WBI=y
++CONFIG_CPU_CP15=y
++CONFIG_CPU_CP15_MMU=y
++
++#
++# Processor Features
++#
++CONFIG_ARM_THUMB=y
++# CONFIG_CPU_ICACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_DISABLE is not set
++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
++# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
++# CONFIG_OUTER_CACHE is not set
++
++#
++# Bus support
++#
++CONFIG_ARM_AMBA=y
++# CONFIG_PCI_SYSCALL is not set
++# CONFIG_ARCH_SUPPORTS_MSI is not set
++# CONFIG_PCCARD is not set
++
++#
++# Kernel Features
++#
++CONFIG_TICK_ONESHOT=y
++CONFIG_NO_HZ=y
++CONFIG_HIGH_RES_TIMERS=y
++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
++CONFIG_VMSPLIT_3G=y
++# CONFIG_VMSPLIT_2G is not set
++# CONFIG_VMSPLIT_1G is not set
++CONFIG_PAGE_OFFSET=0xC0000000
++# CONFIG_PREEMPT is not set
++CONFIG_HZ=100
++CONFIG_AEABI=y
++CONFIG_OABI_COMPAT=y
++CONFIG_ARCH_FLATMEM_HAS_HOLES=y
++# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
++# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++CONFIG_PAGEFLAGS_EXTENDED=y
++CONFIG_SPLIT_PTLOCK_CPUS=4096
++# CONFIG_RESOURCES_64BIT is not set
++# CONFIG_PHYS_ADDR_T_64BIT is not set
++CONFIG_ZONE_DMA_FLAG=0
++CONFIG_VIRT_TO_BUS=y
++CONFIG_UNEVICTABLE_LRU=y
++CONFIG_ALIGNMENT_TRAP=y
++
++#
++# Boot options
++#
++CONFIG_ZBOOT_ROM_TEXT=0
++CONFIG_ZBOOT_ROM_BSS=0
++CONFIG_CMDLINE=""
++# CONFIG_XIP_KERNEL is not set
++# CONFIG_KEXEC is not set
++
++#
++# CPU Power Management
++#
++# CONFIG_CPU_IDLE is not set
++
++#
++# Floating point emulation
++#
++
++#
++# At least one emulation must be selected
++#
++CONFIG_FPE_NWFPE=y
++CONFIG_FPE_NWFPE_XP=y
++# CONFIG_FPE_FASTFPE is not set
++CONFIG_VFP=y
++
++#
++# Userspace binary formats
++#
++CONFIG_BINFMT_ELF=y
++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
++CONFIG_HAVE_AOUT=y
++CONFIG_BINFMT_AOUT=y
++# CONFIG_BINFMT_MISC is not set
++
++#
++# Power management options
++#
++CONFIG_PM=y
++# CONFIG_PM_DEBUG is not set
++CONFIG_PM_SLEEP=y
++CONFIG_SUSPEND=y
++CONFIG_SUSPEND_FREEZER=y
++# CONFIG_APM_EMULATION is not set
++CONFIG_ARCH_SUSPEND_POSSIBLE=y
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++# CONFIG_PACKET_MMAP is not set
++CONFIG_UNIX=y
++CONFIG_XFRM=y
++# CONFIG_XFRM_USER is not set
++# CONFIG_XFRM_SUB_POLICY is not set
++# CONFIG_XFRM_MIGRATE is not set
++# CONFIG_XFRM_STATISTICS is not set
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++CONFIG_IP_MULTICAST=y
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_IP_MROUTE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++CONFIG_INET_TUNNEL=m
++CONFIG_INET_XFRM_MODE_TRANSPORT=y
++CONFIG_INET_XFRM_MODE_TUNNEL=y
++CONFIG_INET_XFRM_MODE_BEET=y
++# CONFIG_INET_LRO is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_CUBIC=y
++CONFIG_DEFAULT_TCP_CONG="cubic"
++# CONFIG_TCP_MD5SIG is not set
++CONFIG_IPV6=m
++# CONFIG_IPV6_PRIVACY is not set
++# CONFIG_IPV6_ROUTER_PREF is not set
++# CONFIG_IPV6_OPTIMISTIC_DAD is not set
++# CONFIG_INET6_AH is not set
++# CONFIG_INET6_ESP is not set
++# CONFIG_INET6_IPCOMP is not set
++# CONFIG_IPV6_MIP6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++CONFIG_INET6_XFRM_MODE_TRANSPORT=m
++CONFIG_INET6_XFRM_MODE_TUNNEL=m
++CONFIG_INET6_XFRM_MODE_BEET=m
++# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
++CONFIG_IPV6_SIT=m
++CONFIG_IPV6_NDISC_NODETYPE=y
++# CONFIG_IPV6_TUNNEL is not set
++# CONFIG_IPV6_MULTIPLE_TABLES is not set
++# CONFIG_IPV6_MROUTE is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++# CONFIG_IP_DCCP is not set
++# CONFIG_IP_SCTP is not set
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_NET_DSA is not set
++CONFIG_VLAN_8021Q=m
++# CONFIG_VLAN_8021Q_GVRP is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_ECONET is not set
++CONFIG_WAN_ROUTER=y
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_CAN is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_AF_RXRPC is not set
++# CONFIG_PHONET is not set
++# CONFIG_WIRELESS is not set
++# CONFIG_RFKILL is not set
++# CONFIG_NET_9P is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++CONFIG_FW_LOADER=y
++CONFIG_FIRMWARE_IN_KERNEL=y
++CONFIG_EXTRA_FIRMWARE=""
++# CONFIG_SYS_HYPERVISOR is not set
++CONFIG_CONNECTOR=y
++CONFIG_PROC_EVENTS=y
++CONFIG_MTD=y
++# CONFIG_MTD_DEBUG is not set
++CONFIG_MTD_CONCAT=y
++CONFIG_MTD_PARTITIONS=y
++# CONFIG_MTD_REDBOOT_PARTS is not set
++CONFIG_MTD_CMDLINE_PARTS=y
++# CONFIG_MTD_AFS_PARTS is not set
++# CONFIG_MTD_AR7_PARTS is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=y
++CONFIG_MTD_BLKDEVS=y
++CONFIG_MTD_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL is not set
++# CONFIG_SSFDC is not set
++# CONFIG_MTD_OOPS is not set
++
++#
++# RAM/ROM/Flash chip drivers
++#
++# CONFIG_MTD_CFI is not set
++# CONFIG_MTD_JEDECPROBE is not set
++CONFIG_MTD_MAP_BANK_WIDTH_1=y
++CONFIG_MTD_MAP_BANK_WIDTH_2=y
++CONFIG_MTD_MAP_BANK_WIDTH_4=y
++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
++CONFIG_MTD_CFI_I1=y
++CONFIG_MTD_CFI_I2=y
++# CONFIG_MTD_CFI_I4 is not set
++# CONFIG_MTD_CFI_I8 is not set
++# CONFIG_MTD_RAM is not set
++# CONFIG_MTD_ROM is not set
++# CONFIG_MTD_ABSENT is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++CONFIG_MTD_DATAFLASH=m
++CONFIG_MTD_DATAFLASH_WRITE_VERIFY=y
++# CONFIG_MTD_DATAFLASH_OTP is not set
++CONFIG_MTD_M25P80=y
++CONFIG_M25PXX_USE_FAST_READ=y
++# CONFIG_MTD_SLRAM is not set
++# CONFIG_MTD_PHRAM is not set
++# CONFIG_MTD_MTDRAM is not set
++# CONFIG_MTD_BLOCK2MTD is not set
++
++#
++# Disk-On-Chip Device Drivers
++#
++# CONFIG_MTD_DOC2000 is not set
++# CONFIG_MTD_DOC2001 is not set
++# CONFIG_MTD_DOC2001PLUS is not set
++# CONFIG_MTD_NAND is not set
++# CONFIG_MTD_ONENAND is not set
++
++#
++# UBI - Unsorted block images
++#
++# CONFIG_MTD_UBI is not set
++# CONFIG_PARPORT is not set
++CONFIG_BLK_DEV=y
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
++CONFIG_BLK_DEV_NBD=y
++# CONFIG_BLK_DEV_UB is not set
++CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
++CONFIG_BLK_DEV_RAM_SIZE=16384
++# CONFIG_BLK_DEV_XIP is not set
++# CONFIG_RD_BZIP2 is not set
++CONFIG_RD_LZMA=y
++CONFIG_RD_GZIP=y
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++CONFIG_MISC_DEVICES=y
++# CONFIG_EEPROM_93CX6 is not set
++# CONFIG_ICS932S401 is not set
++# CONFIG_ENCLOSURE_SERVICES is not set
++# CONFIG_C2PORT is not set
++CONFIG_HAVE_IDE=y
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++CONFIG_SCSI=y
++CONFIG_SCSI_DMA=y
++CONFIG_SCSI_TGT=y
++# CONFIG_SCSI_NETLINK is not set
++CONFIG_SCSI_PROC_FS=y
++
++#
++# SCSI support type (disk, tape, CD-ROM)
++#
++CONFIG_BLK_DEV_SD=y
++# CONFIG_CHR_DEV_ST is not set
++# CONFIG_CHR_DEV_OSST is not set
++# CONFIG_BLK_DEV_SR is not set
++CONFIG_CHR_DEV_SG=y
++# CONFIG_CHR_DEV_SCH is not set
++
++#
++# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
++#
++# CONFIG_SCSI_MULTI_LUN is not set
++# CONFIG_SCSI_CONSTANTS is not set
++# CONFIG_SCSI_LOGGING is not set
++CONFIG_SCSI_SCAN_ASYNC=y
++CONFIG_SCSI_WAIT_SCAN=m
++
++#
++# SCSI Transports
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++CONFIG_SCSI_ISCSI_ATTRS=m
++# CONFIG_SCSI_SAS_LIBSAS is not set
++# CONFIG_SCSI_SRP_ATTRS is not set
++# CONFIG_SCSI_LOWLEVEL is not set
++# CONFIG_SCSI_DH is not set
++# CONFIG_ATA is not set
++# CONFIG_MD is not set
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++CONFIG_BONDING=m
++# CONFIG_MACVLAN is not set
++# CONFIG_EQUALIZER is not set
++CONFIG_TUN=m
++# CONFIG_VETH is not set
++# CONFIG_NET_ETHERNET is not set
++CONFIG_NETDEV_1000=y
++CONFIG_ASPEEDMAC=y
++# CONFIG_NETDEV_10000 is not set
++
++#
++# Wireless LAN
++#
++# CONFIG_WLAN_PRE80211 is not set
++# CONFIG_WLAN_80211 is not set
++# CONFIG_IWLWIFI_LEDS is not set
++
++#
++# USB Network Adapters
++#
++# CONFIG_USB_CATC is not set
++# CONFIG_USB_KAWETH is not set
++# CONFIG_USB_PEGASUS is not set
++# CONFIG_USB_RTL8150 is not set
++# CONFIG_USB_USBNET is not set
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++# CONFIG_ISDN is not set
++
++#
++# Input device support
++#
++CONFIG_INPUT=y
++# CONFIG_INPUT_FF_MEMLESS is not set
++# CONFIG_INPUT_POLLDEV is not set
++
++#
++# Userland interfaces
++#
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_MOUSEDEV_PSAUX=y
++CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
++CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
++# CONFIG_INPUT_JOYDEV is not set
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_EVBUG is not set
++
++#
++# Input Device Drivers
++#
++CONFIG_INPUT_KEYBOARD=y
++CONFIG_KEYBOARD_ATKBD=y
++# CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
++# CONFIG_KEYBOARD_XTKBD is not set
++# CONFIG_KEYBOARD_NEWTON is not set
++# CONFIG_KEYBOARD_STOWAWAY is not set
++# CONFIG_KEYBOARD_GPIO is not set
++CONFIG_INPUT_MOUSE=y
++CONFIG_MOUSE_PS2=y
++CONFIG_MOUSE_PS2_ALPS=y
++CONFIG_MOUSE_PS2_LOGIPS2PP=y
++CONFIG_MOUSE_PS2_SYNAPTICS=y
++CONFIG_MOUSE_PS2_LIFEBOOK=y
++CONFIG_MOUSE_PS2_TRACKPOINT=y
++# CONFIG_MOUSE_PS2_ELANTECH is not set
++# CONFIG_MOUSE_PS2_TOUCHKIT is not set
++CONFIG_MOUSE_SERIAL=y
++# CONFIG_MOUSE_APPLETOUCH is not set
++# CONFIG_MOUSE_BCM5974 is not set
++# CONFIG_MOUSE_VSXXXAA is not set
++# CONFIG_MOUSE_GPIO is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TABLET is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
++
++#
++# Hardware I/O ports
++#
++CONFIG_SERIO=y
++CONFIG_SERIO_SERPORT=y
++# CONFIG_SERIO_AMBAKMI is not set
++CONFIG_SERIO_LIBPS2=y
++# CONFIG_SERIO_RAW is not set
++# CONFIG_GAMEPORT is not set
++
++#
++# Character devices
++#
++CONFIG_VT=y
++CONFIG_CONSOLE_TRANSLATIONS=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
++CONFIG_DEVKMEM=y
++CONFIG_SERIAL_NONSTANDARD=y
++# CONFIG_N_HDLC is not set
++# CONFIG_RISCOM8 is not set
++# CONFIG_SPECIALIX is not set
++# CONFIG_RIO is not set
++# CONFIG_STALDRV is not set
++
++#
++# Serial drivers
++#
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_NR_UARTS=5
++CONFIG_SERIAL_8250_RUNTIME_UARTS=5
++# CONFIG_SERIAL_AST_DMA_UART is not set
++# CONFIG_SERIAL_8250_EXTENDED is not set
++
++#
++# Non-8250 serial port support
++#
++# CONFIG_SERIAL_AMBA_PL010 is not set
++# CONFIG_SERIAL_AMBA_PL011 is not set
++# CONFIG_SERIAL_AST is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
++# CONFIG_IPMI_HANDLER is not set
++CONFIG_AST_MISC=y
++# CONFIG_AST_VIDEO is not set
++# CONFIG_ADC_CAT9883 is not set
++# CONFIG_AST_SPI_BIOS is not set
++CONFIG_AST_PECI=y
++# CONFIG_AST_KCS is not set
++# CONFIG_AST_GPIO is not set
++# CONFIG_HW_RANDOM is not set
++CONFIG_NVRAM=y
++# CONFIG_R3964 is not set
++# CONFIG_RAW_DRIVER is not set
++# CONFIG_TCG_TPM is not set
++CONFIG_I2C=y
++CONFIG_I2C_BOARDINFO=y
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_HELPER_AUTO=y
++
++#
++# I2C Hardware Bus support
++#
++
++#
++# I2C system bus drivers (mostly embedded / system-on-chip)
++#
++# CONFIG_I2C_GPIO is not set
++# CONFIG_I2C_OCORES is not set
++CONFIG_I2C_AST=y
++CONFIG_AST_I2C_SLAVE_MODE=y
++# CONFIG_AST_I2C_SLAVE_EEPROM is not set
++CONFIG_AST_I2C_SLAVE_RDWR=y
++# CONFIG_I2C_SIMTEC is not set
++
++#
++# External I2C/SMBus adapter drivers
++#
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_TAOS_EVM is not set
++# CONFIG_I2C_TINY_USB is not set
++
++#
++# Other I2C/SMBus bus drivers
++#
++# CONFIG_I2C_PCA_PLATFORM is not set
++# CONFIG_I2C_STUB is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_DS1682 is not set
++CONFIG_AT24=m
++# CONFIG_SENSORS_EEPROM is not set
++CONFIG_SENSORS_PCF8574=m
++# CONFIG_PCF8575 is not set
++# CONFIG_SENSORS_PCA9539 is not set
++# CONFIG_SENSORS_PCF8591 is not set
++# CONFIG_TPS65010 is not set
++# CONFIG_SENSORS_MAX6875 is not set
++# CONFIG_SENSORS_TSL2550 is not set
++# CONFIG_I2C_DEBUG_CORE is not set
++# CONFIG_I2C_DEBUG_ALGO is not set
++# CONFIG_I2C_DEBUG_BUS is not set
++# CONFIG_I2C_DEBUG_CHIP is not set
++CONFIG_SPI=y
++CONFIG_SPI_MASTER=y
++
++#
++# SPI Master Controller Drivers
++#
++CONFIG_SPI_AST=y
++CONFIG_SPI_FMC=y
++CONFIG_SPI_BITBANG=y
++
++#
++# SPI Protocol Masters
++#
++CONFIG_SPI_AT25=m
++# CONFIG_SPI_SPIDEV is not set
++# CONFIG_SPI_TLE62X0 is not set
++CONFIG_ARCH_REQUIRE_GPIOLIB=y
++CONFIG_GPIOLIB=y
++CONFIG_GPIO_SYSFS=y
++
++#
++# Memory mapped GPIO expanders:
++#
++
++#
++# I2C GPIO expanders:
++#
++# CONFIG_GPIO_MAX732X is not set
++# CONFIG_GPIO_PCA953X is not set
++# CONFIG_GPIO_PCF857X is not set
++
++#
++# PCI GPIO expanders:
++#
++
++#
++# SPI GPIO expanders:
++#
++# CONFIG_GPIO_MAX7301 is not set
++# CONFIG_GPIO_MCP23S08 is not set
++# CONFIG_W1 is not set
++# CONFIG_POWER_SUPPLY is not set
++CONFIG_HWMON=y
++# CONFIG_HWMON_VID is not set
++# CONFIG_SENSORS_AD7414 is not set
++# CONFIG_SENSORS_AD7418 is not set
++# CONFIG_SENSORS_ADCXX is not set
++# CONFIG_SENSORS_ADM1021 is not set
++# CONFIG_SENSORS_ADM1025 is not set
++# CONFIG_SENSORS_ADM1026 is not set
++# CONFIG_SENSORS_ADM1029 is not set
++# CONFIG_SENSORS_ADM1031 is not set
++# CONFIG_SENSORS_ADM9240 is not set
++# CONFIG_SENSORS_ADT7462 is not set
++# CONFIG_SENSORS_ADT7470 is not set
++# CONFIG_SENSORS_ADT7473 is not set
++# CONFIG_SENSORS_ATXP1 is not set
++# CONFIG_SENSORS_DS1621 is not set
++# CONFIG_SENSORS_F71805F is not set
++# CONFIG_SENSORS_F71882FG is not set
++# CONFIG_SENSORS_F75375S is not set
++# CONFIG_SENSORS_GL518SM is not set
++# CONFIG_SENSORS_GL520SM is not set
++# CONFIG_SENSORS_IT87 is not set
++# CONFIG_SENSORS_LM63 is not set
++# CONFIG_SENSORS_LM70 is not set
++CONFIG_SENSORS_LM75=m
++# CONFIG_SENSORS_LM77 is not set
++# CONFIG_SENSORS_LM78 is not set
++# CONFIG_SENSORS_LM80 is not set
++# CONFIG_SENSORS_LM83 is not set
++# CONFIG_SENSORS_LM85 is not set
++# CONFIG_SENSORS_LM87 is not set
++# CONFIG_SENSORS_LM90 is not set
++# CONFIG_SENSORS_LM92 is not set
++# CONFIG_SENSORS_LM93 is not set
++CONFIG_SENSORS_MAX127=m
++# CONFIG_SENSORS_MAX1111 is not set
++# CONFIG_SENSORS_MAX1619 is not set
++# CONFIG_SENSORS_MAX6650 is not set
++# CONFIG_SENSORS_PC87360 is not set
++# CONFIG_SENSORS_PC87427 is not set
++# CONFIG_SENSORS_DME1737 is not set
++# CONFIG_SENSORS_SMSC47M1 is not set
++# CONFIG_SENSORS_SMSC47M192 is not set
++# CONFIG_SENSORS_SMSC47B397 is not set
++CONFIG_SENSORS_ADS7828=m
++# CONFIG_SENSORS_THMC50 is not set
++# CONFIG_SENSORS_VT1211 is not set
++# CONFIG_SENSORS_W83781D is not set
++# CONFIG_SENSORS_W83791D is not set
++# CONFIG_SENSORS_W83792D is not set
++# CONFIG_SENSORS_W83793 is not set
++# CONFIG_SENSORS_W83L785TS is not set
++# CONFIG_SENSORS_W83L786NG is not set
++# CONFIG_SENSORS_W83627HF is not set
++# CONFIG_SENSORS_W83627EHF is not set
++CONFIG_SENSORS_AST_ADC=y
++CONFIG_SENSORS_AST_PWM_FAN=y
++# CONFIG_SENSORS_FB_PANTHER_PLUS is not set
++CONFIG_PMBUS=m
++CONFIG_SENSORS_PMBUS=m
++CONFIG_SENSORS_ADM1275=m
++# CONFIG_SENSORS_LM25066 is not set
++# CONFIG_SENSORS_LTC2978 is not set
++# CONFIG_SENSORS_MAX16064 is not set
++# CONFIG_SENSORS_MAX34440 is not set
++# CONFIG_SENSORS_MAX8688 is not set
++CONFIG_SENSORS_PFE1100=m
++CONFIG_SENSORS_PFE3000=m
++# CONFIG_SENSORS_UCD9000 is not set
++# CONFIG_SENSORS_UCD9200 is not set
++# CONFIG_SENSORS_ZL6100 is not set
++# CONFIG_HWMON_DEBUG_CHIP is not set
++CONFIG_THERMAL=y
++CONFIG_THERMAL_HWMON=y
++CONFIG_WATCHDOG=y
++# CONFIG_WATCHDOG_NOWAYOUT is not set
++
++#
++# Watchdog Device Drivers
++#
++# CONFIG_SOFT_WATCHDOG is not set
++CONFIG_AST_WATCHDOG=y
++
++#
++# USB-based Watchdog Cards
++#
++# CONFIG_USBPCWATCHDOG is not set
++CONFIG_SSB_POSSIBLE=y
++
++#
++# Sonics Silicon Backplane
++#
++# CONFIG_SSB is not set
++
++#
++# Multifunction device drivers
++#
++# CONFIG_MFD_CORE is not set
++# CONFIG_MFD_SM501 is not set
++# CONFIG_MFD_ASIC3 is not set
++# CONFIG_HTC_EGPIO is not set
++# CONFIG_HTC_PASIC3 is not set
++# CONFIG_MFD_TMIO is not set
++# CONFIG_MFD_TC6393XB is not set
++# CONFIG_PMIC_DA903X is not set
++# CONFIG_MFD_WM8400 is not set
++# CONFIG_MFD_WM8350_I2C is not set
++
++#
++# Multimedia devices
++#
++
++#
++# Multimedia core support
++#
++# CONFIG_VIDEO_DEV is not set
++# CONFIG_DVB_CORE is not set
++# CONFIG_VIDEO_MEDIA is not set
++
++#
++# Multimedia drivers
++#
++# CONFIG_DAB is not set
++
++#
++# Graphics support
++#
++# CONFIG_VGASTATE is not set
++# CONFIG_VIDEO_OUTPUT_CONTROL is not set
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Display device support
++#
++# CONFIG_DISPLAY_SUPPORT is not set
++
++#
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_SOUND is not set
++# CONFIG_HID_SUPPORT is not set
++CONFIG_USB_SUPPORT=y
++CONFIG_USB_ARCH_HAS_HCD=y
++# CONFIG_USB_ARCH_HAS_OHCI is not set
++CONFIG_USB_ARCH_HAS_EHCI=y
++CONFIG_USB=m
++# CONFIG_USB_DEBUG is not set
++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
++
++#
++# Miscellaneous USB options
++#
++CONFIG_USB_DEVICEFS=y
++CONFIG_USB_DEVICE_CLASS=y
++# CONFIG_USB_DYNAMIC_MINORS is not set
++# CONFIG_USB_SUSPEND is not set
++# CONFIG_USB_OTG is not set
++# CONFIG_USB_MON is not set
++# CONFIG_USB_WUSB is not set
++# CONFIG_USB_WUSB_CBAF is not set
++
++#
++# USB Host Controller Drivers
++#
++# CONFIG_USB_C67X00_HCD is not set
++# CONFIG_USB_EHCI_HCD is not set
++# CONFIG_USB_ISP116X_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
++# CONFIG_USB_R8A66597_HCD is not set
++# CONFIG_USB_HWA_HCD is not set
++
++#
++# AST USB Drivers
++#
++CONFIG_AST_USB_UHCI_HCD=y
++# CONFIG_AST_USB_UHCI_MULTIPORT_1 is not set
++# CONFIG_AST_USB_UHCI_MULTIPORT_2 is not set
++CONFIG_AST_USB_UHCI_MULTIPORT_4=y
++# CONFIG_USB_EHCI_SPLIT_ISO is not set
++
++#
++# USB Device Class drivers
++#
++# CONFIG_USB_ACM is not set
++# CONFIG_USB_PRINTER is not set
++# CONFIG_USB_WDM is not set
++# CONFIG_USB_TMC is not set
++
++#
++# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
++#
++
++#
++# see USB_STORAGE Help for more information
++#
++CONFIG_USB_STORAGE=m
++# CONFIG_USB_STORAGE_DEBUG is not set
++# CONFIG_USB_STORAGE_DATAFAB is not set
++# CONFIG_USB_STORAGE_FREECOM is not set
++# CONFIG_USB_STORAGE_ISD200 is not set
++# CONFIG_USB_STORAGE_DPCM is not set
++# CONFIG_USB_STORAGE_USBAT is not set
++# CONFIG_USB_STORAGE_SDDR09 is not set
++# CONFIG_USB_STORAGE_SDDR55 is not set
++# CONFIG_USB_STORAGE_JUMPSHOT is not set
++# CONFIG_USB_STORAGE_ALAUDA is not set
++# CONFIG_USB_STORAGE_ONETOUCH is not set
++# CONFIG_USB_STORAGE_KARMA is not set
++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
++# CONFIG_USB_LIBUSUAL is not set
++
++#
++# USB Imaging devices
++#
++# CONFIG_USB_MDC800 is not set
++# CONFIG_USB_MICROTEK is not set
++
++#
++# USB port drivers
++#
++# CONFIG_USB_SERIAL is not set
++
++#
++# USB Miscellaneous drivers
++#
++# CONFIG_USB_EMI62 is not set
++# CONFIG_USB_EMI26 is not set
++# CONFIG_USB_ADUTUX is not set
++# CONFIG_USB_SEVSEG is not set
++# CONFIG_USB_RIO500 is not set
++# CONFIG_USB_LEGOTOWER is not set
++# CONFIG_USB_LCD is not set
++# CONFIG_USB_BERRY_CHARGE is not set
++# CONFIG_USB_LED is not set
++# CONFIG_USB_CYPRESS_CY7C63 is not set
++# CONFIG_USB_CYTHERM is not set
++# CONFIG_USB_PHIDGET is not set
++# CONFIG_USB_IDMOUSE is not set
++# CONFIG_USB_FTDI_ELAN is not set
++# CONFIG_USB_APPLEDISPLAY is not set
++# CONFIG_USB_LD is not set
++# CONFIG_USB_TRANCEVIBRATOR is not set
++# CONFIG_USB_IOWARRIOR is not set
++# CONFIG_USB_TEST is not set
++# CONFIG_USB_ISIGHTFW is not set
++# CONFIG_USB_VST is not set
++CONFIG_USB_GADGET=y
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_VBUS_DRAW=2
++CONFIG_USB_GADGET_SELECTED=y
++# CONFIG_USB_GADGET_AT91 is not set
++# CONFIG_USB_GADGET_ATMEL_USBA is not set
++# CONFIG_USB_GADGET_FSL_USB2 is not set
++# CONFIG_USB_GADGET_LH7A40X is not set
++# CONFIG_USB_GADGET_OMAP is not set
++# CONFIG_USB_GADGET_PXA25X is not set
++# CONFIG_USB_GADGET_PXA27X is not set
++# CONFIG_USB_GADGET_S3C2410 is not set
++# CONFIG_USB_GADGET_M66592 is not set
++# CONFIG_USB_GADGET_AMD5536UDC is not set
++# CONFIG_USB_GADGET_FSL_QE is not set
++# CONFIG_USB_GADGET_NET2280 is not set
++# CONFIG_USB_GADGET_GOKU is not set
++CONFIG_USB_GADGET_ASPEED_AST=y
++CONFIG_USB_ASPEED_AST=y
++# CONFIG_USB_GADGET_DUMMY_HCD is not set
++CONFIG_USB_GADGET_DUALSPEED=y
++CONFIG_USB_ZERO=m
++CONFIG_USB_ETH=m
++CONFIG_USB_ETH_RNDIS=y
++CONFIG_USB_GADGETFS=m
++CONFIG_USB_FILE_STORAGE=m
++# CONFIG_USB_FILE_STORAGE_TEST is not set
++CONFIG_USB_G_SERIAL=m
++# CONFIG_USB_MIDI_GADGET is not set
++# CONFIG_USB_G_PRINTER is not set
++CONFIG_USB_CDC_COMPOSITE=m
++# CONFIG_MMC is not set
++# CONFIG_MEMSTICK is not set
++# CONFIG_ACCESSIBILITY is not set
++# CONFIG_NEW_LEDS is not set
++CONFIG_RTC_LIB=y
++CONFIG_RTC_CLASS=y
++# CONFIG_RTC_HCTOSYS is not set
++# CONFIG_RTC_DEBUG is not set
++
++#
++# RTC interfaces
++#
++CONFIG_RTC_INTF_SYSFS=y
++CONFIG_RTC_INTF_PROC=y
++CONFIG_RTC_INTF_DEV=y
++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
++# CONFIG_RTC_DRV_TEST is not set
++
++#
++# I2C RTC drivers
++#
++# CONFIG_RTC_DRV_DS1307 is not set
++# CONFIG_RTC_DRV_DS1374 is not set
++# CONFIG_RTC_DRV_DS1672 is not set
++# CONFIG_RTC_DRV_MAX6900 is not set
++# CONFIG_RTC_DRV_RS5C372 is not set
++# CONFIG_RTC_DRV_ISL1208 is not set
++# CONFIG_RTC_DRV_X1205 is not set
++# CONFIG_RTC_DRV_PCF8563 is not set
++# CONFIG_RTC_DRV_PCF8583 is not set
++# CONFIG_RTC_DRV_M41T80 is not set
++# CONFIG_RTC_DRV_S35390A is not set
++# CONFIG_RTC_DRV_FM3130 is not set
++# CONFIG_RTC_DRV_RX8581 is not set
++
++#
++# SPI RTC drivers
++#
++# CONFIG_RTC_DRV_M41T94 is not set
++# CONFIG_RTC_DRV_DS1305 is not set
++# CONFIG_RTC_DRV_DS1390 is not set
++# CONFIG_RTC_DRV_MAX6902 is not set
++# CONFIG_RTC_DRV_R9701 is not set
++# CONFIG_RTC_DRV_RS5C348 is not set
++# CONFIG_RTC_DRV_DS3234 is not set
++
++#
++# Platform RTC drivers
++#
++# CONFIG_RTC_DRV_CMOS is not set
++# CONFIG_RTC_DRV_DS1286 is not set
++# CONFIG_RTC_DRV_DS1511 is not set
++# CONFIG_RTC_DRV_DS1553 is not set
++# CONFIG_RTC_DRV_DS1742 is not set
++# CONFIG_RTC_DRV_STK17TA8 is not set
++# CONFIG_RTC_DRV_M48T86 is not set
++# CONFIG_RTC_DRV_M48T35 is not set
++# CONFIG_RTC_DRV_M48T59 is not set
++# CONFIG_RTC_DRV_BQ4802 is not set
++# CONFIG_RTC_DRV_V3020 is not set
++
++#
++# on-CPU RTC drivers
++#
++# CONFIG_RTC_DRV_PL030 is not set
++# CONFIG_RTC_DRV_PL031 is not set
++CONFIG_RTC_DRV_ASPEED=y
++# CONFIG_DMADEVICES is not set
++# CONFIG_REGULATOR is not set
++# CONFIG_UIO is not set
++
++#
++# File systems
++#
++CONFIG_EXT2_FS=y
++CONFIG_EXT2_FS_XATTR=y
++CONFIG_EXT2_FS_POSIX_ACL=y
++CONFIG_EXT2_FS_SECURITY=y
++# CONFIG_EXT2_FS_XIP is not set
++# CONFIG_EXT3_FS is not set
++# CONFIG_EXT4_FS is not set
++CONFIG_FS_MBCACHE=y
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++CONFIG_FS_POSIX_ACL=y
++CONFIG_FILE_LOCKING=y
++# CONFIG_XFS_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_DNOTIFY=y
++CONFIG_INOTIFY=y
++CONFIG_INOTIFY_USER=y
++# CONFIG_QUOTA is not set
++# CONFIG_AUTOFS_FS is not set
++# CONFIG_AUTOFS4_FS is not set
++# CONFIG_FUSE_FS is not set
++CONFIG_GENERIC_ACL=y
++
++#
++# CD-ROM/DVD Filesystems
++#
++# CONFIG_ISO9660_FS is not set
++# CONFIG_UDF_FS is not set
++
++#
++# DOS/FAT/NT Filesystems
++#
++CONFIG_FAT_FS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++CONFIG_NTFS_FS=y
++# CONFIG_NTFS_DEBUG is not set
++CONFIG_NTFS_RW=y
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++CONFIG_PROC_SYSCTL=y
++CONFIG_PROC_PAGE_MONITOR=y
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_CONFIGFS_FS=m
++
++#
++# Miscellaneous filesystems
++#
++# CONFIG_ADFS_FS is not set
++# CONFIG_AFFS_FS is not set
++# CONFIG_HFS_FS is not set
++# CONFIG_HFSPLUS_FS is not set
++# CONFIG_BEFS_FS is not set
++# CONFIG_BFS_FS is not set
++# CONFIG_EFS_FS is not set
++CONFIG_YAFFS_FS=y
++CONFIG_YAFFS_YAFFS1=y
++# CONFIG_YAFFS_9BYTE_TAGS is not set
++# CONFIG_YAFFS_DOES_ECC is not set
++CONFIG_YAFFS_YAFFS2=y
++CONFIG_YAFFS_AUTO_YAFFS2=y
++# CONFIG_YAFFS_DISABLE_TAGS_ECC is not set
++# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
++# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
++# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
++CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
++# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
++# CONFIG_JFFS2_SUMMARY is not set
++# CONFIG_JFFS2_FS_XATTR is not set
++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
++CONFIG_JFFS2_ZLIB=y
++# CONFIG_JFFS2_LZO is not set
++CONFIG_JFFS2_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_OMFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_ROMFS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++CONFIG_NETWORK_FILESYSTEMS=y
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 is not set
++# CONFIG_NFS_V4 is not set
++CONFIG_ROOT_NFS=y
++# CONFIG_NFSD is not set
++CONFIG_LOCKD=y
++CONFIG_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_SUNRPC_REGISTER_V4 is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS is not set
++# CONFIG_CIFS is not set
++# CONFIG_NCP_FS is not set
++# CONFIG_CODA_FS is not set
++# CONFIG_AFS_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="utf8"
++CONFIG_NLS_CODEPAGE_437=y
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++# CONFIG_NLS_CODEPAGE_850 is not set
++# CONFIG_NLS_CODEPAGE_852 is not set
++# CONFIG_NLS_CODEPAGE_855 is not set
++# CONFIG_NLS_CODEPAGE_857 is not set
++# CONFIG_NLS_CODEPAGE_860 is not set
++# CONFIG_NLS_CODEPAGE_861 is not set
++# CONFIG_NLS_CODEPAGE_862 is not set
++# CONFIG_NLS_CODEPAGE_863 is not set
++# CONFIG_NLS_CODEPAGE_864 is not set
++# CONFIG_NLS_CODEPAGE_865 is not set
++# CONFIG_NLS_CODEPAGE_866 is not set
++# CONFIG_NLS_CODEPAGE_869 is not set
++CONFIG_NLS_CODEPAGE_936=y
++CONFIG_NLS_CODEPAGE_950=y
++CONFIG_NLS_CODEPAGE_932=y
++# CONFIG_NLS_CODEPAGE_949 is not set
++# CONFIG_NLS_CODEPAGE_874 is not set
++# CONFIG_NLS_ISO8859_8 is not set
++# CONFIG_NLS_CODEPAGE_1250 is not set
++# CONFIG_NLS_CODEPAGE_1251 is not set
++CONFIG_NLS_ASCII=y
++CONFIG_NLS_ISO8859_1=y
++# CONFIG_NLS_ISO8859_2 is not set
++# CONFIG_NLS_ISO8859_3 is not set
++# CONFIG_NLS_ISO8859_4 is not set
++# CONFIG_NLS_ISO8859_5 is not set
++# CONFIG_NLS_ISO8859_6 is not set
++# CONFIG_NLS_ISO8859_7 is not set
++# CONFIG_NLS_ISO8859_9 is not set
++# CONFIG_NLS_ISO8859_13 is not set
++# CONFIG_NLS_ISO8859_14 is not set
++# CONFIG_NLS_ISO8859_15 is not set
++# CONFIG_NLS_KOI8_R is not set
++# CONFIG_NLS_KOI8_U is not set
++CONFIG_NLS_UTF8=y
++# CONFIG_DLM is not set
++
++#
++# Kernel hacking
++#
++# CONFIG_PRINTK_TIME is not set
++# CONFIG_ENABLE_WARN_DEPRECATED is not set
++CONFIG_ENABLE_MUST_CHECK=y
++CONFIG_FRAME_WARN=1024
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_HEADERS_CHECK is not set
++# CONFIG_DEBUG_KERNEL is not set
++# CONFIG_SLUB_DEBUG_ON is not set
++# CONFIG_SLUB_STATS is not set
++CONFIG_DEBUG_BUGVERBOSE=y
++CONFIG_DEBUG_MEMORY_INIT=y
++CONFIG_FRAME_POINTER=y
++# CONFIG_RCU_CPU_STALL_DETECTOR is not set
++# CONFIG_LATENCYTOP is not set
++# CONFIG_SYSCTL_SYSCALL_CHECK is not set
++CONFIG_HAVE_FUNCTION_TRACER=y
++
++#
++# Tracers
++#
++# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
++# CONFIG_SAMPLES is not set
++CONFIG_HAVE_ARCH_KGDB=y
++# CONFIG_DEBUG_USER is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++# CONFIG_SECURITYFS is not set
++# CONFIG_SECURITY_FILE_CAPABILITIES is not set
++CONFIG_CRYPTO=y
++
++#
++# Crypto core or helper
++#
++# CONFIG_CRYPTO_FIPS is not set
++CONFIG_CRYPTO_ALGAPI=y
++CONFIG_CRYPTO_ALGAPI2=y
++CONFIG_CRYPTO_AEAD=m
++CONFIG_CRYPTO_AEAD2=y
++CONFIG_CRYPTO_BLKCIPHER=y
++CONFIG_CRYPTO_BLKCIPHER2=y
++CONFIG_CRYPTO_HASH=y
++CONFIG_CRYPTO_HASH2=y
++CONFIG_CRYPTO_RNG2=y
++CONFIG_CRYPTO_MANAGER=y
++CONFIG_CRYPTO_MANAGER2=y
++# CONFIG_CRYPTO_GF128MUL is not set
++CONFIG_CRYPTO_NULL=y
++# CONFIG_CRYPTO_CRYPTD is not set
++CONFIG_CRYPTO_AUTHENC=m
++# CONFIG_CRYPTO_TEST is not set
++
++#
++# Authenticated Encryption with Associated Data
++#
++# CONFIG_CRYPTO_CCM is not set
++# CONFIG_CRYPTO_GCM is not set
++# CONFIG_CRYPTO_SEQIV is not set
++
++#
++# Block modes
++#
++CONFIG_CRYPTO_CBC=y
++# CONFIG_CRYPTO_CTR is not set
++# CONFIG_CRYPTO_CTS is not set
++# CONFIG_CRYPTO_ECB is not set
++# CONFIG_CRYPTO_LRW is not set
++# CONFIG_CRYPTO_PCBC is not set
++# CONFIG_CRYPTO_XTS is not set
++
++#
++# Hash modes
++#
++CONFIG_CRYPTO_HMAC=y
++# CONFIG_CRYPTO_XCBC is not set
++
++#
++# Digest
++#
++# CONFIG_CRYPTO_CRC32C is not set
++# CONFIG_CRYPTO_MD4 is not set
++CONFIG_CRYPTO_MD5=y
++# CONFIG_CRYPTO_MICHAEL_MIC is not set
++# CONFIG_CRYPTO_RMD128 is not set
++# CONFIG_CRYPTO_RMD160 is not set
++# CONFIG_CRYPTO_RMD256 is not set
++# CONFIG_CRYPTO_RMD320 is not set
++CONFIG_CRYPTO_SHA1=y
++# CONFIG_CRYPTO_SHA256 is not set
++# CONFIG_CRYPTO_SHA512 is not set
++# CONFIG_CRYPTO_TGR192 is not set
++# CONFIG_CRYPTO_WP512 is not set
++
++#
++# Ciphers
++#
++# CONFIG_CRYPTO_AES is not set
++# CONFIG_CRYPTO_ANUBIS is not set
++# CONFIG_CRYPTO_ARC4 is not set
++# CONFIG_CRYPTO_BLOWFISH is not set
++# CONFIG_CRYPTO_CAMELLIA is not set
++# CONFIG_CRYPTO_CAST5 is not set
++# CONFIG_CRYPTO_CAST6 is not set
++CONFIG_CRYPTO_DES=y
++# CONFIG_CRYPTO_FCRYPT is not set
++# CONFIG_CRYPTO_KHAZAD is not set
++# CONFIG_CRYPTO_SALSA20 is not set
++# CONFIG_CRYPTO_SEED is not set
++# CONFIG_CRYPTO_SERPENT is not set
++# CONFIG_CRYPTO_TEA is not set
++# CONFIG_CRYPTO_TWOFISH is not set
++
++#
++# Compression
++#
++CONFIG_CRYPTO_DEFLATE=m
++# CONFIG_CRYPTO_LZO is not set
++
++#
++# Random Number Generation
++#
++# CONFIG_CRYPTO_ANSI_CPRNG is not set
++# CONFIG_CRYPTO_HW is not set
++
++#
++# Library routines
++#
++CONFIG_BITREVERSE=y
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++# CONFIG_CRC_T10DIF is not set
++CONFIG_CRC_ITU_T=m
++CONFIG_CRC32=y
++# CONFIG_CRC7 is not set
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
++CONFIG_HAS_IOMEM=y
++CONFIG_HAS_IOPORT=y
++CONFIG_HAS_DMA=y
++
++
++# GUC USB Drivers
++#
++CONFIG_GUC_USB_UHCI_HCD=m
++# CONFIG_GUC_USB_UHCI_MULTIPORT_1 is not set
++# CONFIG_GUC_USB_UHCI_MULTIPORT_2 is not set
++CONFIG_GUC_USB_UHCI_MULTIPORT_4=y
++# CONFIG_USB_GADGET_MUSB_HDRC is not set
+diff --git a/arch/arm/include/asm/ioctls.h b/arch/arm/include/asm/ioctls.h
+index a91d8a1..fd50ffe 100644
+--- a/arch/arm/include/asm/ioctls.h
++++ b/arch/arm/include/asm/ioctls.h
+@@ -65,6 +65,7 @@
+ #define TIOCSERGETLSR 0x5459 /* Get line status register */
+ #define TIOCSERGETMULTI 0x545A /* Get multiport config */
+ #define TIOCSERSETMULTI 0x545B /* Set multiport config */
++#define TIOCSERWAITTEMT 0x5499 /* Wait for empty */
+
+ #define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
+ #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
+diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
+index a948ab8..6d548f8 100644
+--- a/arch/arm/mach-aspeed/Kconfig
++++ b/arch/arm/mach-aspeed/Kconfig
+@@ -203,6 +203,18 @@ endchoice
+ config AST_SCU_LOCK
+ bool "AST SCU Protection Key"
+
++config WEDGE
++ bool "Facebook Wedge/6-Pack"
++
++config WEDGE100
++ bool "Facebook Wedge100"
++
++config YOSEMITE
++ bool "Facebook Yosemite"
++
++config FBPLATFORM1
++ bool "Facebook Platform1"
++
+ # Support PCIE
+ config PCIE
+ bool "ASPEED PCIE support"
+diff --git a/arch/arm/mach-aspeed/gpio.c b/arch/arm/mach-aspeed/gpio.c
+index 3a633e9..e56ca35 100644
+--- a/arch/arm/mach-aspeed/gpio.c
++++ b/arch/arm/mach-aspeed/gpio.c
+@@ -232,7 +232,7 @@ static struct ast_gpio_bank ast_gpio_gp[] = {
+ AST_GPIO_BANK("GPIOR", IO_ADDRESS(AST_GPIO_BASE), 1, 0x080, 0x084, 0x118, 0x11c, 0x128, 0x12c, 0x130, 0x110),
+ AST_GPIO_BANK("GPIOS", IO_ADDRESS(AST_GPIO_BASE), 2, 0x080, 0x084, 0x118, 0x11c, 0x128, 0x12c, 0x130, 0x110),
+ #if defined(CONFIG_ARCH_AST2400)
+- AST_GPIO_BANK("GPIOT", IO_ADDRESS(AST_GPIO_BASE), 4, 0x080, 0x084, 0x118, 0x11c, 0x128, 0x12c, 0x130, 0x110),
++ AST_GPIO_BANK("GPIOT", IO_ADDRESS(AST_GPIO_BASE), 3, 0x080, 0x084, 0x118, 0x11c, 0x128, 0x12c, 0x130, 0x110),
+ AST_GPIO_BANK("GPIOU", IO_ADDRESS(AST_GPIO_BASE), 0, 0x088, 0x08c, 0x148, 0x14c, 0x158, 0x15c, 0x160, 0x140),
+ AST_GPIO_BANK("GPIOV", IO_ADDRESS(AST_GPIO_BASE), 1, 0x088, 0x08c, 0x148, 0x14c, 0x158, 0x15c, 0x160, 0x140),
+ AST_GPIO_BANK("GPIOW", IO_ADDRESS(AST_GPIO_BASE), 2, 0x088, 0x08c, 0x148, 0x14c, 0x158, 0x15c, 0x160, 0x140),
+diff --git a/arch/arm/mach-aspeed/include/mach/debug-macro.S b/arch/arm/mach-aspeed/include/mach/debug-macro.S
+index ff3195a..33fc879 100644
+--- a/arch/arm/mach-aspeed/include/mach/debug-macro.S
++++ b/arch/arm/mach-aspeed/include/mach/debug-macro.S
+@@ -13,8 +13,8 @@
+ .macro addruart, rx, tmp
+ mrc p15, 0, \rx, c1, c0
+ tst \rx, #1 @ MMU enabled?
+- ldreq \rx, =AST_UART3_BASE
+- ldrne \rx, =IO_ADDRESS(AST_UART3_BASE)
++ ldreq \rx, =AST_UART_BASE
++ ldrne \rx, =IO_ADDRESS(AST_UART_BASE)
+ .endm
+
+ #define UART_SHIFT 2
+diff --git a/arch/arm/mach-aspeed/include/mach/platform.h b/arch/arm/mach-aspeed/include/mach/platform.h
+index 8951ffc..4d6c50c 100644
+--- a/arch/arm/mach-aspeed/include/mach/platform.h
++++ b/arch/arm/mach-aspeed/include/mach/platform.h
+@@ -62,5 +62,20 @@
+ * Watchdog
+ */
+ #define AST_WDT_VA_BASE (IO_ADDRESS(AST_WDT_BASE))
+-
++
++/*
++ * Console UART
++ */
++#ifdef CONFIG_WEDGE
++#define AST_UART_BASE AST_UART3_BASE
++#elif defined(CONFIG_WEDGE100)
++#define AST_UART_BASE AST_UART3_BASE
++#elif defined(CONFIG_YOSEMITE)
++#define AST_UART_BASE AST_UART0_BASE
++#elif defined(CONFIG_FBPLATFORM1)
++#define AST_UART_BASE AST_UART0_BASE
++#else
++#define AST_UART_BASE AST_UART0_BASE
++#endif
++
+ #endif
+diff --git a/arch/arm/mach-aspeed/include/mach/uncompress.h b/arch/arm/mach-aspeed/include/mach/uncompress.h
+index 80e560d..3be04b0 100644
+--- a/arch/arm/mach-aspeed/include/mach/uncompress.h
++++ b/arch/arm/mach-aspeed/include/mach/uncompress.h
+@@ -12,8 +12,8 @@
+ #include <mach/platform.h>
+ #include <mach/aspeed_serial.h>
+
+-#define UART_PUT_CHAR (*(volatile unsigned char *)(AST_UART3_BASE + UART_THR))
+-#define UART_GET_LSR (*(volatile unsigned char *)(AST_UART3_BASE + UART_LSR))
++#define UART_PUT_CHAR (*(volatile unsigned char *)(AST_UART_BASE + UART_THR))
++#define UART_GET_LSR (*(volatile unsigned char *)(AST_UART_BASE + UART_LSR))
+
+ static void putc(int c)
+ {
+@@ -21,7 +21,7 @@ static void putc(int c)
+ /* wait for space in the UART's transmitter */
+ while (!(UART_GET_LSR & UART_LSR_THRE))
+ barrier();
+-
++
+ /* send the character out. */
+ UART_PUT_CHAR = c;
+ }
+diff --git a/arch/arm/mach-aspeed/include/mach/vmalloc.h b/arch/arm/mach-aspeed/include/mach/vmalloc.h
+index 51912ae..bc1b471 100644
+--- a/arch/arm/mach-aspeed/include/mach/vmalloc.h
++++ b/arch/arm/mach-aspeed/include/mach/vmalloc.h
+@@ -25,5 +25,5 @@
+ #define VMALLOC_VMADDR(x) ((unsigned long)(x))
+ #define VMALLOC_END (PAGE_OFFSET + 0x20000000)
+ #else
+-#define VMALLOC_END 0xf8000000UL
+-#endif
+\ No newline at end of file
++#define VMALLOC_END 0xf8000000UL
++#endif
+diff --git a/arch/arm/plat-aspeed/ast-scu.c b/arch/arm/plat-aspeed/ast-scu.c
+index 76722f4..101b141 100644
+--- a/arch/arm/plat-aspeed/ast-scu.c
++++ b/arch/arm/plat-aspeed/ast-scu.c
+@@ -1,20 +1,20 @@
+ /********************************************************************************
+-* File Name : arch/arm/plat-aspeed/ast-scu.c
++* File Name : arch/arm/plat-aspeed/ast-scu.c
+ * Author : Ryan Chen
+-* Description : AST SCU
+-*
++* Description : AST SCU
++*
+ * Copyright (C) 2012-2020 ASPEED Technology Inc.
+-* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+-
+-CLK24M
++* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++CLK24M
+ |
+ |--> H-PLL -->HCLK
+ |
+@@ -27,9 +27,9 @@ CLK24M
+ |--> USB2PHY -->UTMICLK
+
+
+-* History :
++* History :
+ * 1. 2012/08/15 Ryan Chen Create
+-*
++*
+ ********************************************************************************/
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+@@ -56,34 +56,34 @@ CLK24M
+
+ static u32 ast_scu_base = IO_ADDRESS(AST_SCU_BASE);
+
+-static inline u32
++static inline u32
+ ast_scu_read(u32 reg)
+ {
+ u32 val;
+-
++
+ val = readl(ast_scu_base + reg);
+-
++
+ SCUDBUG("ast_scu_read : reg = 0x%08x, val = 0x%08x\n", reg, val);
+-
++
+ return val;
+ }
+
+ static inline void
+-ast_scu_write(u32 val, u32 reg)
++ast_scu_write(u32 val, u32 reg)
+ {
+ SCUDBUG("ast_scu_write : reg = 0x%08x, val = 0x%08x\n", reg, val);
+ #ifdef CONFIG_AST_SCU_LOCK
+- //unlock
++ //unlock
+ writel(SCU_PROTECT_UNLOCK, ast_scu_base);
+ writel(val, ast_scu_base + reg);
+ //lock
+- writel(0xaa,ast_scu_base);
++ writel(0xaa,ast_scu_base);
+ #else
+ writel(val, ast_scu_base + reg);
+ #endif
+ }
+
+-//SoC mapping Table
++//SoC mapping Table
+ struct soc_id {
+ const char * name;
+ u32 rev_id;
+@@ -180,9 +180,9 @@ ast_scu_init_video(u8 dynamic_en)
+ ast_scu_write((ast_scu_read(AST_SCU_CLK_SEL) & ~SCU_CLK_VIDEO_SLOW_MASK) | SCU_CLK_VIDEO_SLOW_EN | SCU_CLK_VIDEO_SLOW_SET(0), AST_SCU_CLK_SEL);
+ else
+ ast_scu_write((ast_scu_read(AST_SCU_CLK_SEL) & ~SCU_ECLK_SOURCE_MASK) | SCU_ECLK_SOURCE(2), AST_SCU_CLK_SEL);
+-
++
+ // Enable CLK
+- ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~(SCU_ECLK_STOP_EN | SCU_VCLK_STOP_EN), AST_SCU_CLK_STOP);
++ ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~(SCU_ECLK_STOP_EN | SCU_VCLK_STOP_EN), AST_SCU_CLK_STOP);
+ mdelay(10);
+ ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_VIDEO, AST_SCU_RESET);
+ udelay(100);
+@@ -201,32 +201,32 @@ ast_scu_init_eth(u8 num)
+ ast_scu_write((ast_scu_read(AST_SCU_CLK_SEL) & ~SCU_CLK_MAC_MASK) | SCU_CLK_MAC_DIV(4), AST_SCU_CLK_SEL);
+
+ //Set MAC delay Timing
+- ast_scu_write(0x2255, AST_SCU_MAC_CLK);
++ ast_scu_write(0x2255, AST_SCU_MAC_CLK);
+
+ switch(num) {
+ case 0:
+- ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_MAC0,
+- AST_SCU_RESET);
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_MAC0,
++ AST_SCU_RESET);
+ udelay(100);
+- ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~SCU_MAC0CLK_STOP_EN,
+- AST_SCU_CLK_STOP);
++ ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~SCU_MAC0CLK_STOP_EN,
++ AST_SCU_CLK_STOP);
+ udelay(1000);
+- ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_MAC0,
+- AST_SCU_RESET);
+-
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_MAC0,
++ AST_SCU_RESET);
++
+ break;
+ case 1:
+- ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_MAC1,
+- AST_SCU_RESET);
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_MAC1,
++ AST_SCU_RESET);
+ udelay(100);
+- ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~SCU_MAC1CLK_STOP_EN,
+- AST_SCU_CLK_STOP);
++ ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~SCU_MAC1CLK_STOP_EN,
++ AST_SCU_CLK_STOP);
+ udelay(1000);
+- ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_MAC1,
+- AST_SCU_RESET);
++ ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_MAC1,
++ AST_SCU_RESET);
+ break;
+-
+- }
++
++ }
+ }
+
+
+@@ -292,7 +292,7 @@ ast_scu_init_sdhci(void)
+ {
+ //SDHCI Host's Clock Enable and Reset
+ ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_SD, AST_SCU_RESET);
+-
++
+ ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) & ~SCU_SDCLK_STOP_EN, AST_SCU_CLK_STOP);
+ mdelay(10);
+
+@@ -300,10 +300,10 @@ ast_scu_init_sdhci(void)
+ mdelay(10);
+
+ // SDCLK = H-PLL / 4
+- ast_scu_write((ast_scu_read(AST_SCU_CLK_SEL) & ~SCU_CLK_SD_MASK) | SCU_CLK_SD_DIV(1),
++ ast_scu_write((ast_scu_read(AST_SCU_CLK_SEL) & ~SCU_CLK_SD_MASK) | SCU_CLK_SD_DIV(1),
+ AST_SCU_CLK_SEL);
+ mdelay(10);
+-
++
+ ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_SD, AST_SCU_RESET);
+ }
+
+@@ -358,13 +358,13 @@ EXPORT_SYMBOL(ast_scu_init_jtag);
+ extern void
+ ast_scu_init_lpc(void)
+ {
+- //Note .. It have been enable in U-boot.....
++ //Note .. It have been enable in U-boot.....
+ // ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_LPC, AST_SCU_RESET);
+
+ //enable LPC clock LHCLK = H-PLL/8
+- ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) |
+- SCU_SET_LHCLK_DIV(3) |
+- SCU_LHCLK_SOURCE_EN,
++ ast_scu_write(ast_scu_read(AST_SCU_CLK_STOP) |
++ SCU_SET_LHCLK_DIV(3) |
++ SCU_LHCLK_SOURCE_EN,
+ AST_SCU_CLK_STOP);
+
+ }
+@@ -377,7 +377,7 @@ ast_scu_get_lpc_plus_enable(void)
+ {
+ if(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & SCU_FUN_PIN_LPC_PLUS)
+ return 1;
+- else
++ else
+ return 0;
+ }
+
+@@ -390,10 +390,10 @@ ast_scu_init_crt(void)
+ #if defined(CONFIG_AST_DAC) || defined(CONFIG_AST_DVO)
+ ast_scu_write((ast_scu_read(AST_SCU_MISC1_CTRL) & ~(SCU_MISC_D2_PLL_DIS | SCU_MISC_DAC_MASK))
+ | SCU_MISC_DAC_SOURCE_CRT | SCU_MISC_DVO_SOURCE_CRT | SCU_MISC_2D_CRT_EN , AST_SCU_MISC1_CTRL);
+-#elif defined(CONFIG_AST_DVO)
++#elif defined(CONFIG_AST_DVO)
+ ast_scu_write((ast_scu_read(AST_SCU_MISC1_CTRL) & ~(SCU_MISC_D2_PLL_DIS)) |
+ SCU_MISC_DVO_SOURCE_CRT| SCU_MISC_2D_CRT_EN, AST_SCU_MISC1_CTRL);
+-#else //default(CONFIG_AST_DAC)
++#else //default(CONFIG_AST_DAC)
+ ast_scu_write((ast_scu_read(AST_SCU_MISC1_CTRL) & ~(SCU_MISC_D2_PLL_DIS | SCU_MISC_DAC_MASK))
+ | SCU_MISC_DAC_SOURCE_CRT | SCU_MISC_2D_CRT_EN, AST_SCU_MISC1_CTRL);
+ #endif
+@@ -401,7 +401,7 @@ ast_scu_init_crt(void)
+ ast_scu_write((ast_scu_read(AST_SCU_CLK_SEL) & ~SCU_CLK_VIDEO_DELAY_MASK) |
+ SCU_CLK_VIDEO_DELAY(5), AST_SCU_CLK_SEL);
+
+- /* Reset CRT */
++ /* Reset CRT */
+ ast_scu_write(ast_scu_read(AST_SCU_RESET) | SCU_RESET_CRT, AST_SCU_RESET);
+
+ //enable D2 CLK
+@@ -409,7 +409,7 @@ ast_scu_init_crt(void)
+
+ udelay(10);
+ ast_scu_write(ast_scu_read(AST_SCU_RESET) & ~SCU_RESET_CRT, AST_SCU_RESET);
+-
++
+ }
+
+ EXPORT_SYMBOL(ast_scu_init_crt);
+@@ -448,7 +448,7 @@ ast_get_h_pll_clk(void)
+
+ if(h_pll_set & SCU_H_PLL_OFF)
+ return 0;
+-
++
+ if(h_pll_set & SCU_H_PLL_PARAMETER) {
+ // Programming
+ clk = ast_get_clk_source();
+@@ -470,21 +470,21 @@ ast_get_h_pll_clk(void)
+ speed = SCU_HW_STRAP_GET_H_PLL_CLK(ast_scu_read(AST_SCU_HW_STRAP1));
+ switch (speed) {
+ case 0:
+- clk = 384000000;
++ clk = 384000000;
+ break;
+ case 1:
+- clk = 360000000;
++ clk = 360000000;
+ break;
+ case 2:
+- clk = 336000000;
++ clk = 336000000;
+ break;
+ case 3:
+- clk = 408000000;
++ clk = 408000000;
+ break;
+ default:
+- BUG();
++ BUG();
+ break;
+- }
++ }
+ }
+ SCUDBUG("h_pll = %d\n",clk);
+ return clk;
+@@ -500,7 +500,7 @@ ast_get_m_pll_clk(void)
+
+ if(m_pll_set & SCU_M_PLL_OFF)
+ return 0;
+-
++
+ // Programming
+ clk = ast_get_clk_source();
+ if(m_pll_set & SCU_M_PLL_BYPASS_EN) {
+@@ -542,10 +542,10 @@ ast_get_ahbclk(void)
+ case 3:
+ div = 4;
+ break;
+-
++
+ }
+-
+- SCUDBUG("HPLL=%d, Div=%d, AHB CLK=%d\n", hpll, div, hpll/div);
++
++ SCUDBUG("HPLL=%d, Div=%d, AHB CLK=%d\n", hpll, div, hpll/div);
+ return (hpll/div);
+
+ }
+@@ -559,8 +559,8 @@ ast_get_pclk(void)
+ hpll = ast_get_h_pll_clk();
+ div = SCU_GET_PCLK_DIV(ast_scu_read(AST_SCU_CLK_SEL));
+ div = (div+1) << 1;
+-
+- SCUDBUG("HPLL=%d, Div=%d, PCLK=%d\n", hpll, div, hpll/div);
++
++ SCUDBUG("HPLL=%d, Div=%d, PCLK=%d\n", hpll, div, hpll/div);
+ return (hpll/div);
+
+ }
+@@ -572,7 +572,7 @@ ast_get_lhclk(void)
+ unsigned int div, hpll;
+ u32 clk_sel = ast_scu_read(AST_SCU_CLK_SEL);
+ //FPGA AST1070 is default 100/2 Mhz input
+-// return 50000000;
++// return 50000000;
+ hpll = ast_get_h_pll_clk();
+ if(SCU_LHCLK_SOURCE_EN & clk_sel) {
+ div = SCU_GET_LHCLK_DIV(clk_sel);
+@@ -600,10 +600,10 @@ ast_get_lhclk(void)
+ break;
+ case 7:
+ div = 16;
+- break;
++ break;
+ }
+-
+- SCUDBUG("HPLL=%d, Div=%d, LHCLK = %d\n", hpll, div, hpll/div);
++
++ SCUDBUG("HPLL=%d, Div=%d, LHCLK = %d\n", hpll, div, hpll/div);
+ return (hpll/div);
+ } else {
+ SCUMSG("LPC CLK not enable \n");
+@@ -704,7 +704,7 @@ ast_get_sd_clock_src(void)
+ sd_div = SCU_CLK_SD_GET_DIV(ast_scu_read(AST_SCU_CLK_SEL));
+ SCUDBUG("div %d, sdclk =%d \n",((sd_div + 1) * 2),clk/((sd_div + 1) * 2));
+ clk /= ((sd_div + 1) * 2);
+-
++
+ #endif
+ return clk;
+ }
+@@ -717,7 +717,7 @@ ast_scu_show_system_info (void)
+ u32 h_pll, div;
+
+ h_pll = ast_get_h_pll_clk();
+-
++
+ div = SCU_HW_STRAP_GET_CPU_AHB_RATIO(ast_scu_read(AST_SCU_HW_STRAP1));
+ switch(div) {
+ case 0:
+@@ -732,10 +732,10 @@ ast_scu_show_system_info (void)
+ case 3:
+ div = 4;
+ break;
+-
++
+ }
+
+- SCUMSG("CPU = %d MHz ,AHB = %d MHz (%d:1) \n", h_pll/1000000, h_pll/div/1000000,div);
++ SCUMSG("CPU = %d MHz ,AHB = %d MHz (%d:1) \n", h_pll/1000000, h_pll/div/1000000,div);
+
+ return ;
+ }
+@@ -750,54 +750,68 @@ ast_scu_multi_func_uart(u8 uart)
+ case 1:
+ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL2) |
+ SCU_FUN_PIN_UART1_RXD |
++#ifdef CONFIG_YOSEMITE
++ SCU_FUN_PIN_UART1_TXD,
++#else
+ SCU_FUN_PIN_UART1_TXD |
+ SCU_FUN_PIN_UART1_NRTS |
+ SCU_FUN_PIN_UART1_NDTR |
+ SCU_FUN_PIN_UART1_NRI |
+ SCU_FUN_PIN_UART1_NDSR |
+ SCU_FUN_PIN_UART1_NDCD |
+- SCU_FUN_PIN_UART1_NCTS,
+- AST_SCU_FUN_PIN_CTRL2);
+- break;
++ SCU_FUN_PIN_UART1_NCTS,
++#endif
++ AST_SCU_FUN_PIN_CTRL2);
++ break;
+ case 2:
+ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL2) |
+ SCU_FUN_PIN_UART2_RXD |
++#ifdef CONFIG_YOSEMITE
++ SCU_FUN_PIN_UART2_TXD,
++#else
+ SCU_FUN_PIN_UART2_TXD |
+ SCU_FUN_PIN_UART2_NRTS |
+ SCU_FUN_PIN_UART2_NDTR |
+ SCU_FUN_PIN_UART2_NRI |
+ SCU_FUN_PIN_UART2_NDSR |
+ SCU_FUN_PIN_UART2_NDCD |
+- SCU_FUN_PIN_UART2_NCTS,
+- AST_SCU_FUN_PIN_CTRL2);
+- break;
++ SCU_FUN_PIN_UART2_NCTS,
++#endif
++ AST_SCU_FUN_PIN_CTRL2);
++ break;
+ case 3:
+ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) |
+ SCU_FUN_PIN_UART3_RXD |
++#ifdef CONFIG_YOSEMITE
++ SCU_FUN_PIN_UART3_TXD,
++#else
+ SCU_FUN_PIN_UART3_TXD |
+ SCU_FUN_PIN_UART3_NRTS |
+ SCU_FUN_PIN_UART3_NDTR |
+ SCU_FUN_PIN_UART3_NRI |
+ SCU_FUN_PIN_UART3_NDSR |
+ SCU_FUN_PIN_UART3_NDCD |
+- SCU_FUN_PIN_UART3_NCTS,
+- AST_SCU_FUN_PIN_CTRL1);
++ SCU_FUN_PIN_UART3_NCTS,
++#endif
++ AST_SCU_FUN_PIN_CTRL1);
+ break;
+ case 4:
+ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) |
+ SCU_FUN_PIN_UART4_RXD |
++#ifdef CONFIG_YOSEMITE
++ SCU_FUN_PIN_UART4_TXD,
++#else
+ SCU_FUN_PIN_UART4_TXD |
+ SCU_FUN_PIN_UART4_NRTS |
+ SCU_FUN_PIN_UART4_NDTR |
+ SCU_FUN_PIN_UART4_NRI |
+ SCU_FUN_PIN_UART4_NDSR |
+ SCU_FUN_PIN_UART4_NDCD |
+- SCU_FUN_PIN_UART4_NCTS,
+- AST_SCU_FUN_PIN_CTRL1);
++ SCU_FUN_PIN_UART4_NCTS,
++#endif
++ AST_SCU_FUN_PIN_CTRL1);
+ break;
+ }
+-
+-
+ }
+
+ extern void
+@@ -806,13 +820,13 @@ ast_scu_multi_func_video()
+ #if defined(CONFIG_ARCH_2100) || defined(CONFIG_ARCH_2200)
+ ast_scu_write(ast_scu_read(AST_SCU_MULTI_FUNC_2) |
+ MULTI_FUNC_VIDEO_RGB18 |
+- MULTI_FUNC_VIDEO_SINGLE_EDGE,
+- AST_SCU_MULTI_FUNC_2);
++ MULTI_FUNC_VIDEO_SINGLE_EDGE,
++ AST_SCU_MULTI_FUNC_2);
+ #elif defined(CONFIG_ARCH_1100) || defined(CONFIG_ARCH_2050)
+ ast_scu_write(ast_scu_read(AST_SCU_MULTI_FUNC_2) |
+ MULTI_FUNC_VIDEO_RGB18 |
+- MULTI_FUNC_VIDEO_SINGLE_EDGE,
+- AST_SCU_MULTI_FUNC_2);
++ MULTI_FUNC_VIDEO_SINGLE_EDGE,
++ AST_SCU_MULTI_FUNC_2);
+ #else
+
+ #endif
+@@ -823,40 +837,40 @@ ast_scu_multi_func_eth(u8 num)
+ {
+ switch(num) {
+ case 0:
+- if(ast_scu_read(AST_SCU_HW_STRAP1) && SCU_HW_STRAP_MAC0_RGMII) {
++ if(ast_scu_read(AST_SCU_HW_STRAP1) & SCU_HW_STRAP_MAC0_RGMII) {
+ SCUMSG("MAC0 : RGMII \n");
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) |
+- SCU_FUN_PIN_MAC0_PHY_LINK,
+- AST_SCU_FUN_PIN_CTRL1);
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) |
++ SCU_FUN_PIN_MAC0_PHY_LINK,
++ AST_SCU_FUN_PIN_CTRL1);
+ } else {
+- SCUMSG("MAC0 : RMII/NCSI \n");
++ SCUMSG("MAC0 : RMII/NCSI \n");
+ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) &
+- ~SCU_FUN_PIN_MAC0_PHY_LINK,
+- AST_SCU_FUN_PIN_CTRL1);
++ ~SCU_FUN_PIN_MAC0_PHY_LINK,
++ AST_SCU_FUN_PIN_CTRL1);
+ }
+
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL3) |
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL3) |
+ SCU_FUN_PIN_MAC0_MDIO |
+- SCU_FUN_PIN_MAC0_MDC,
+- AST_SCU_FUN_PIN_CTRL3);
+-
++ SCU_FUN_PIN_MAC0_MDC,
++ AST_SCU_FUN_PIN_CTRL3);
++
+ break;
+ case 1:
+- if(ast_scu_read(AST_SCU_HW_STRAP1) && SCU_HW_STRAP_MAC1_RGMII) {
++ if(ast_scu_read(AST_SCU_HW_STRAP1) & SCU_HW_STRAP_MAC1_RGMII) {
+ SCUMSG("MAC1 : RGMII \n");
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) |
+- SCU_FUN_PIN_MAC1_PHY_LINK,
+- AST_SCU_FUN_PIN_CTRL1);
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) |
++ SCU_FUN_PIN_MAC1_PHY_LINK,
++ AST_SCU_FUN_PIN_CTRL1);
+ } else {
+ SCUMSG("MAC1 : RMII/NCSI \n");
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) &
+- ~SCU_FUN_PIN_MAC1_PHY_LINK,
+- AST_SCU_FUN_PIN_CTRL1);
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) &
++ ~SCU_FUN_PIN_MAC1_PHY_LINK,
++ AST_SCU_FUN_PIN_CTRL1);
+ }
+-
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) |
++
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) |
+ SCU_FUC_PIN_MAC1_MDIO,
+- AST_SCU_FUN_PIN_CTRL5);
++ AST_SCU_FUN_PIN_CTRL5);
+
+ break;
+ }
+@@ -866,18 +880,18 @@ extern void
+ ast_scu_multi_func_nand(void)
+ {
+ //enable NAND flash multipin FLBUSY and FLWP
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL2) |
+- SCU_FUN_PIN_NAND_FLBUSY | SCU_FUN_PIN_NAND_FLWP,
+- AST_SCU_FUN_PIN_CTRL2);
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL2) |
++ SCU_FUN_PIN_NAND_FLBUSY | SCU_FUN_PIN_NAND_FLWP,
++ AST_SCU_FUN_PIN_CTRL2);
+
+ }
+
+ extern void
+ ast_scu_multi_func_nor(void)
+ {
+- //Address
++ //Address
+ //ROMA2~17
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL8) |
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL8) |
+ SCU_FUN_PIN_ROMA2 | SCU_FUN_PIN_ROMA3 |
+ SCU_FUN_PIN_ROMA4 | SCU_FUN_PIN_ROMA5 |
+ SCU_FUN_PIN_ROMA6 | SCU_FUN_PIN_ROMA7 |
+@@ -885,39 +899,39 @@ ast_scu_multi_func_nor(void)
+ SCU_FUN_PIN_ROMA10 | SCU_FUN_PIN_ROMA11 |
+ SCU_FUN_PIN_ROMA12 | SCU_FUN_PIN_ROMA13 |
+ SCU_FUN_PIN_ROMA14 | SCU_FUN_PIN_ROMA15 |
+- SCU_FUN_PIN_ROMA16 | SCU_FUN_PIN_ROMA17,
++ SCU_FUN_PIN_ROMA16 | SCU_FUN_PIN_ROMA17,
+ AST_SCU_FUN_PIN_CTRL8);
+
+ //ROMA18~21
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL9) |
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL9) |
+ SCU_FUN_PIN_ROMA18 | SCU_FUN_PIN_ROMA19 |
+- SCU_FUN_PIN_ROMA20 | SCU_FUN_PIN_ROMA21,
+- AST_SCU_FUN_PIN_CTRL9);
+-
++ SCU_FUN_PIN_ROMA20 | SCU_FUN_PIN_ROMA21,
++ AST_SCU_FUN_PIN_CTRL9);
++
+ //ROMA22,23
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL4) | SCU_FUN_PIN_ROMA22 | SCU_FUN_PIN_ROMA23,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL4) | SCU_FUN_PIN_ROMA22 | SCU_FUN_PIN_ROMA23,
+ AST_SCU_FUN_PIN_CTRL4);
+-
++
+ //ROMA24,25
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL3) | SCU_FUN_PIN_ROMA24 | SCU_FUN_PIN_ROMA25,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL3) | SCU_FUN_PIN_ROMA24 | SCU_FUN_PIN_ROMA25,
+ AST_SCU_FUN_PIN_CTRL3);
+
+ //SCU94 [1] = 0
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL6) & SCU_VIDEO_OUT_MASK,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL6) & SCU_VIDEO_OUT_MASK,
+ AST_SCU_FUN_PIN_CTRL6);
+
+-
++
+ //data
+ //ROMD 4~7 //ROMWE#, OE#
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL4) |
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL4) |
+ SCU_FUN_PIN_ROMOE | SCU_FUN_PIN_ROMWE |
+ SCU_FUN_PIN_ROMD4 | SCU_FUN_PIN_ROMD5 |
+ SCU_FUN_PIN_ROMD6 | SCU_FUN_PIN_ROMD7,
+ AST_SCU_FUN_PIN_CTRL4);
+-
++
+ //ROMD 8~15
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) |
+- SCU_FUC_PIN_ROM_16BIT,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) |
++ SCU_FUC_PIN_ROM_16BIT,
+ AST_SCU_FUN_PIN_CTRL5);
+
+ }
+@@ -925,44 +939,44 @@ ast_scu_multi_func_nor(void)
+ extern void
+ ast_scu_multi_func_romcs(u8 num)
+ {
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL3) |
+- SCU_FUN_PIN_ROMCS(num),
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL3) |
++ SCU_FUN_PIN_ROMCS(num),
+ AST_SCU_FUN_PIN_CTRL3);
+ }
+
+ extern void
+ ast_scu_multi_func_i2c(void)
+ {
+- //TODO check ... //In AST2400 Due to share pin with SD , please not enable I2C 10 ~14
++ //TODO check ... //In AST2400 Due to share pin with SD , please not enable I2C 10 ~14
+ // AST 2400 have 14 , AST 2300 9 ...
+ #ifdef CONFIG_MMC_AST
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) |
+- SCU_FUC_PIN_I2C3 |
+- SCU_FUC_PIN_I2C4 |
+- SCU_FUC_PIN_I2C5 |
+- SCU_FUC_PIN_I2C6 |
+- SCU_FUC_PIN_I2C7 |
+- SCU_FUC_PIN_I2C8 |
+- SCU_FUC_PIN_I2C9,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) |
++ SCU_FUC_PIN_I2C3 |
++ SCU_FUC_PIN_I2C4 |
++ SCU_FUC_PIN_I2C5 |
++ SCU_FUC_PIN_I2C6 |
++ SCU_FUC_PIN_I2C7 |
++ SCU_FUC_PIN_I2C8 |
++ SCU_FUC_PIN_I2C9,
+ AST_SCU_FUN_PIN_CTRL5);
+ #else
+- ast_scu_write((ast_scu_read(AST_SCU_FUN_PIN_CTRL5) |
+- SCU_FUC_PIN_I2C3 |
+- SCU_FUC_PIN_I2C4 |
+- SCU_FUC_PIN_I2C5 |
+- SCU_FUC_PIN_I2C6 |
+- SCU_FUC_PIN_I2C7 |
+- SCU_FUC_PIN_I2C8 |
+- SCU_FUC_PIN_I2C9 |
+- SCU_FUC_PIN_I2C10 |
+- SCU_FUC_PIN_I2C11 |
+- SCU_FUC_PIN_I2C12 |
+- SCU_FUC_PIN_I2C13 |
++ ast_scu_write((ast_scu_read(AST_SCU_FUN_PIN_CTRL5) |
++ SCU_FUC_PIN_I2C3 |
++ SCU_FUC_PIN_I2C4 |
++ SCU_FUC_PIN_I2C5 |
++ SCU_FUC_PIN_I2C6 |
++ SCU_FUC_PIN_I2C7 |
++ SCU_FUC_PIN_I2C8 |
++ SCU_FUC_PIN_I2C9 |
++ SCU_FUC_PIN_I2C10 |
++ SCU_FUC_PIN_I2C11 |
++ SCU_FUC_PIN_I2C12 |
++ SCU_FUC_PIN_I2C13 |
+ SCU_FUC_PIN_I2C14) &
+- ~(SCU_FUC_PIN_SD1 | SCU_FUC_PIN_SD2),
++ ~(SCU_FUC_PIN_SD1 | SCU_FUC_PIN_SD2),
+ AST_SCU_FUN_PIN_CTRL5);
+ #endif
+-}
++}
+
+ EXPORT_SYMBOL(ast_scu_multi_func_i2c);
+
+@@ -972,7 +986,7 @@ ast_scu_multi_func_pwm_tacho(void)
+ //TODO check
+ u32 sts = ast_scu_read(AST_SCU_FUN_PIN_CTRL3) &~0xcfffff;
+ ast_scu_write(sts | 0xc000ff, AST_SCU_FUN_PIN_CTRL3);
+-}
++}
+
+ EXPORT_SYMBOL(ast_scu_multi_func_pwm_tacho);
+
+@@ -981,12 +995,12 @@ extern void
+ ast_scu_multi_func_usb20_host_hub(u8 mode)
+ {
+ if(mode)
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_USB20_HOST,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_USB20_HOST,
+ AST_SCU_FUN_PIN_CTRL5);
+ else
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_USB20_HOST,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_USB20_HOST,
+ AST_SCU_FUN_PIN_CTRL5);
+-}
++}
+
+ EXPORT_SYMBOL(ast_scu_multi_func_usb20_host_hub);
+
+@@ -995,12 +1009,12 @@ extern void
+ ast_scu_multi_func_usb11_host_port4(u8 mode)
+ {
+ if(mode)
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_USB11_PORT4,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_USB11_PORT4,
+ AST_SCU_FUN_PIN_CTRL5);
+ else
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_USB11_PORT4,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_USB11_PORT4,
+ AST_SCU_FUN_PIN_CTRL5);
+-}
++}
+
+ EXPORT_SYMBOL(ast_scu_multi_func_usb11_host_port4);
+
+@@ -1009,26 +1023,26 @@ extern void
+ ast_scu_multi_func_usb11_host_port2(u8 mode)
+ {
+ if(mode)
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_USB11_PORT2,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_USB11_PORT2,
+ AST_SCU_FUN_PIN_CTRL5);
+ else
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_USB11_PORT2,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_USB11_PORT2,
+ AST_SCU_FUN_PIN_CTRL5);
+-}
++}
+
+ EXPORT_SYMBOL(ast_scu_multi_func_usb11_host_port2);
+
+-//0 : 1: SD1 function
++//0 : 1: SD1 function
+ extern void
+ ast_scu_multi_func_sdhc_slot1(u8 mode)
+ {
+ if(mode)
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_SD1,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_SD1,
+ AST_SCU_FUN_PIN_CTRL5);
+ else
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_SD1,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_SD1,
+ AST_SCU_FUN_PIN_CTRL5);
+-}
++}
+
+ EXPORT_SYMBOL(ast_scu_multi_func_sdhc_slot1);
+
+@@ -1036,13 +1050,13 @@ extern void
+ ast_scu_multi_func_sdhc_slot2(u8 mode)
+ {
+ if(mode)
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_SD2,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) | SCU_FUC_PIN_SD2,
+ AST_SCU_FUN_PIN_CTRL5);
+ else
+- ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_SD2,
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL5) & ~SCU_FUC_PIN_SD2,
+ AST_SCU_FUN_PIN_CTRL5);
+
+-}
++}
+
+ EXPORT_SYMBOL(ast_scu_multi_func_sdhc_slot2);
+
+@@ -1053,11 +1067,11 @@ ast_scu_multi_func_crt(void)
+
+ //Digital vodeo input function pins : 00 disable, 10 24bits mode 888,
+ ast_scu_write((ast_scu_read(AST_SCU_FUN_PIN_CTRL5) &
+- ~SCU_FUC_PIN_DIGI_V_OUT_MASK) |
++ ~SCU_FUC_PIN_DIGI_V_OUT_MASK) |
+ SCU_FUC_PIN_DIGI_V_OUT(VIDEO_24BITS),AST_SCU_FUN_PIN_CTRL5);
+
+ //VPI input
+-#if 0
++#if 0
+ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL2) |
+ SCU_FUN_PIN_VPIB9 | SCU_FUN_PIN_VPIB8 |
+ SCU_FUN_PIN_VPIB7 | SCU_FUN_PIN_VPIB6 |
+@@ -1070,11 +1084,11 @@ ast_scu_multi_func_crt(void)
+
+ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL3) |
+ SCU_FUN_PIN_VPIR9 | SCU_FUN_PIN_VPIR8 |
+- SCU_FUN_PIN_VPIR7 | SCU_FUN_PIN_VPIR6 |
++ SCU_FUN_PIN_VPIR7 | SCU_FUN_PIN_VPIR6 |
+ SCU_FUN_PIN_VPIR5 | SCU_FUN_PIN_VPIR4 |
+ SCU_FUN_PIN_VPIR3 | SCU_FUN_PIN_VPIR2 |
+ SCU_FUN_PIN_VPIR1 | SCU_FUN_PIN_VPIR0 |
+- SCU_FUN_PIN_VPIG9 | SCU_FUN_PIN_VPIG8 |
++ SCU_FUN_PIN_VPIG9 | SCU_FUN_PIN_VPIG8 |
+ SCU_FUN_PIN_VPIG7 | SCU_FUN_PIN_VPIG6 |
+ SCU_FUN_PIN_VPIG5 | SCU_FUN_PIN_VPIG4 |
+ SCU_FUN_PIN_VPIG3 | SCU_FUN_PIN_VPIG2 |
+@@ -1097,9 +1111,9 @@ ast_scu_revision_id(void)
+ SCUMSG("UnKnow-SOC : %x \n",rev_id);
+ else
+ SCUMSG("SOC : %4s \n",soc_map_table[i].name);
+-
++
+ return rev_id;
+-}
++}
+
+ EXPORT_SYMBOL(ast_scu_revision_id);
+
+diff --git a/arch/arm/plat-aspeed/dev-eth.c b/arch/arm/plat-aspeed/dev-eth.c
+index 5d33e33..b115c5a 100644
+--- a/arch/arm/plat-aspeed/dev-eth.c
++++ b/arch/arm/plat-aspeed/dev-eth.c
+@@ -7,11 +7,11 @@
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+@@ -37,7 +37,7 @@
+ #if defined(CONFIG_ASPEEDMAC) || defined(CONFIG_ASPEEDMAC_MODULE)
+ #ifdef AST_MAC0_BASE
+ static struct ftgmac100_eth_data ast_eth0_data = {
+- .dev_addr = { 0x00, 0x84, 0x14, 0xA0, 0xB0, 0x22},
++ .dev_addr = { 0x00, 0x84, 0x14, 0xA0, 0xB0, 0x22},
+ .phy_id = 1,
+ };
+
+@@ -69,7 +69,7 @@ static struct platform_device ast_eth0_device = {
+ #endif
+ #ifdef AST_MAC1_BASE
+ static struct ftgmac100_eth_data ast_eth1_data = {
+- .dev_addr = { 0x00, 0x84, 0x14, 0xA0, 0xB0, 0x23},
++ .dev_addr = { 0x00, 0x84, 0x14, 0xA0, 0xB0, 0x23},
+ .phy_id = 1,
+ };
+
+@@ -131,11 +131,16 @@ void __init ast_add_device_gmac(void)
+ }
+
+ ast_eth0_data.DF_support = !isRevA0;
+-
++
++ // Wedge/6-Pack hardware attaches to MAC1; there's nothing on
++ // MAC0. Older drivers would drop interfaces without PHYs, but
++ // the latest open source drivers do not, so we drop the first
++ // MAC specs.
++#if !defined(CONFIG_WEDGE) && !defined(CONFIG_WEDGE100)
+ ast_scu_init_eth(0);
+ ast_scu_multi_func_eth(0);
+-
+-
++
++
+ /*
+ * D[15:11] in 0x1E6E2040 is NCSI scratch from U-Boot. D[15:14] = MAC1, D[13:12] = MAC2
+ * The meanings of the 2 bits are:
+@@ -144,7 +149,7 @@ void __init ast_add_device_gmac(void)
+ * 10(2): ASPEED's MAC is connected to NC-SI PHY chip directly
+ * 11: Reserved
+ */
+-
++
+ phy_mode = ast_scu_get_phy_config(0);
+ switch(phy_mode) {
+ case 0:
+@@ -152,12 +157,12 @@ void __init ast_add_device_gmac(void)
+ ast_eth0_data.NCSI_support = 0;
+ break;
+ case 1:
+- ast_eth0_data.NCSI_support = 1;
++ ast_eth0_data.INTEL_NCSI_EVA_support = 1;
+ break;
+ case 2:
+- ast_eth0_data.INTEL_NCSI_EVA_support = 1;
++ ast_eth0_data.NCSI_support = 1;
+ break;
+-
++
+ }
+
+ phy_inter = ast_scu_get_phy_interface(0);
+@@ -165,12 +170,13 @@ void __init ast_add_device_gmac(void)
+ // We assume the Clock Stop register does not disable the MAC1 or MAC2 clock
+ // unless Reset Control also holds the MAC in reset.
+
+-
++
+ platform_device_register(&ast_eth0_device);
++#endif
+
+ #ifdef AST_MAC1_BASE
+ ast_scu_init_eth(1);
+- ast_scu_multi_func_eth(1);
++ ast_scu_multi_func_eth(1);
+
+ ast_eth1_data.DF_support = !isRevA0;
+
+@@ -186,7 +192,7 @@ void __init ast_add_device_gmac(void)
+ case 2:
+ ast_eth1_data.INTEL_NCSI_EVA_support = 1;
+ break;
+-
++
+ }
+ phy_inter = ast_scu_get_phy_interface(1);
+
+@@ -198,4 +204,3 @@ void __init ast_add_device_gmac(void)
+ #else
+ void __init ast_add_device_gmac(void) {}
+ #endif
+-
+diff --git a/arch/arm/plat-aspeed/dev-i2c.c b/arch/arm/plat-aspeed/dev-i2c.c
+index 9905390..fffa480 100644
+--- a/arch/arm/plat-aspeed/dev-i2c.c
++++ b/arch/arm/plat-aspeed/dev-i2c.c
+@@ -7,11 +7,11 @@
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+@@ -47,59 +47,59 @@
+ #if defined (CONFIG_ARCH_AST2400)
+ #define I2C_PAGE_SIZE 8
+ static spinlock_t page_info_lock = SPIN_LOCK_UNLOCKED;
+-static struct buf_page page_info[I2C_PAGE_SIZE] =
+-{
++static struct buf_page page_info[I2C_PAGE_SIZE] =
++{
+ [0] = {
+ .flag = 0,
+ .page_no = 0,
+ .page_size = 256,
+- .page_addr_point = 0,
++ .page_addr_point = 0,
+ },
+ [1] = {
+ .flag = 0,
+- .page_no = 1,
++ .page_no = 1,
+ .page_size = 256,
+- .page_addr_point = 0,
++ .page_addr_point = 0,
+ },
+ [2] = {
+ .flag = 0,
+- .page_no = 2,
++ .page_no = 2,
+ .page_size = 256,
+ .page_addr_point = 0,
+ },
+ [3] = {
+ .flag = 0,
+- .page_no = 3,
++ .page_no = 3,
+ .page_size = 256,
+ .page_addr_point = 0,
+ },
+ [4] = {
+ .flag = 0,
+- .page_no = 4,
++ .page_no = 4,
+ .page_size = 256,
+ .page_addr_point = 0,
+ },
+ [5] = {
+ .flag = 0,
+- .page_no = 5,
++ .page_no = 5,
+ .page_size = 256,
+ .page_addr_point = 0,
+ },
+ [6] = {
+ .flag = 0,
+- .page_no = 6,
++ .page_no = 6,
+ .page_size = 256,
+ .page_addr_point = 0,
+ },
+ [7] = {
+ .flag = 0,
+- .page_no = 7,
++ .page_no = 7,
+ .page_size = 256,
+ .page_addr_point = 0,
+ },
+ };
+
+-static void pool_buff_page_init(u32 buf_pool_addr)
++static void pool_buff_page_init(u32 buf_pool_addr)
+ {
+ u32 offset;
+ int i ,j;
+@@ -108,7 +108,7 @@ static void pool_buff_page_init(u32 buf_pool_addr)
+ offset = 0;
+ for(j=0;j<i;j++)
+ offset += page_info[i].page_size;
+-
++
+ page_info[i].page_addr = buf_pool_addr + offset;
+ // I2CDBUG( "page[%d],addr :%x \n", i, page_info[i].page_addr);
+ }
+@@ -130,7 +130,7 @@ static u8 request_pool_buff_page(struct buf_page **req_page)
+ break;
+ }
+ }
+- spin_unlock_irqrestore(&page_info_lock, flags);
++ spin_unlock_irqrestore(&page_info_lock, flags);
+ return (i >= I2C_PAGE_SIZE);
+ }
+
+@@ -140,17 +140,17 @@ static void free_pool_buff_page(struct buf_page *req_page)
+ spin_lock_irqsave(&page_info_lock, flags);
+
+ req_page->flag = 0;
+-// I2CDBUG( "free page addr %x \n", req_page->page_addr);
++// I2CDBUG( "free page addr %x \n", req_page->page_addr);
+ req_page = NULL;
+- spin_unlock_irqrestore(&page_info_lock, flags);
++ spin_unlock_irqrestore(&page_info_lock, flags);
+ }
+
+ #elif defined (CONFIG_ARCH_AST2300)
+ #define I2C_PAGE_SIZE 5
+
+ static spinlock_t page_info_lock = SPIN_LOCK_UNLOCKED;
+-static struct buf_page page_info[I2C_PAGE_SIZE] =
+-{
++static struct buf_page page_info[I2C_PAGE_SIZE] =
++{
+ [0] = {
+ .flag = 0,
+ .page_size = 128,
+@@ -173,7 +173,7 @@ static struct buf_page page_info[I2C_PAGE_SIZE] =
+ },
+ };
+
+-static void pool_buff_page_init(u32 buf_pool_addr)
++static void pool_buff_page_init(u32 buf_pool_addr)
+ {
+
+ u32 offset;
+@@ -183,7 +183,7 @@ static void pool_buff_page_init(u32 buf_pool_addr)
+ offset = 0;
+ for(j=0;j<i;j++)
+ offset += page_info[i].page_size;
+-
++
+ page_info[i].page_addr = buf_pool_addr + offset;
+ page_info[i].page_addr_point = page_info[i].page_addr/4;
+ // printk("page[%d],addr :%x , point : %d\n", i, page_info[i].page_addr, page_info[i].page_addr_point);
+@@ -201,11 +201,11 @@ static u8 request_pool_buff_page(struct buf_page **req_page)
+ if(page_info[i].flag ==0) {
+ page_info[i].flag = 1;
+ *req_page = &page_info[i];
+- spin_unlock_irqrestore(&page_info_lock, flags);
++ spin_unlock_irqrestore(&page_info_lock, flags);
+ return 0;
+ }
+ }
+- spin_unlock_irqrestore(&page_info_lock, flags);
++ spin_unlock_irqrestore(&page_info_lock, flags);
+ return 1;
+
+ }
+@@ -217,10 +217,10 @@ static void free_pool_buff_page(struct buf_page *req_page)
+ spin_lock_irqsave(&page_info_lock, flags);
+ req_page->flag = 0;
+ req_page = NULL;
+- spin_unlock_irqrestore(&page_info_lock, flags);
++ spin_unlock_irqrestore(&page_info_lock, flags);
+ }
+
+-#else
++#else
+ //DO nothing
+ static void pool_buff_page_init(void) {}
+ static u8 request_pool_buff_page(struct buf_page **req_page) {return 0;}
+@@ -228,15 +228,15 @@ static void free_pool_buff_page(struct buf_page *req_page) {}
+ #endif
+
+ static struct ast_i2c_driver_data ast_i2c_data = {
+- .bus_clk = 100000, //bus clock 100KHz
++ .bus_clk = 100000, //bus clock 100KHz
+ .master_dma = BUFF_MODE,
+ .slave_dma = BYTE_MODE,
+ .request_pool_buff_page = request_pool_buff_page,
+ .free_pool_buff_page = free_pool_buff_page,
+-#ifdef CONFIG_AST_I2C_SLAVE_MODE
++#ifdef CONFIG_AST_I2C_SLAVE_MODE
+ .slave_xfer = i2c_slave_xfer,
+ .slave_init = i2c_slave_init,
+-#endif
++#endif
+ .get_i2c_clock = ast_get_pclk,
+ };
+
+@@ -285,7 +285,7 @@ struct platform_device ast_i2c_dev2_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev2_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev2_resources),
+@@ -310,7 +310,7 @@ struct platform_device ast_i2c_dev3_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev3_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev3_resources),
+@@ -335,7 +335,7 @@ struct platform_device ast_i2c_dev4_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev4_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev4_resources),
+@@ -360,7 +360,7 @@ struct platform_device ast_i2c_dev5_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev5_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev5_resources),
+@@ -385,7 +385,7 @@ struct platform_device ast_i2c_dev6_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev6_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev6_resources),
+@@ -410,7 +410,7 @@ struct platform_device ast_i2c_dev7_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev7_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev7_resources),
+@@ -435,7 +435,7 @@ struct platform_device ast_i2c_dev8_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev8_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev8_resources),
+@@ -460,7 +460,7 @@ struct platform_device ast_i2c_dev9_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev9_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev9_resources),
+@@ -486,7 +486,7 @@ struct platform_device ast_i2c_dev10_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev10_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev10_resources),
+@@ -511,7 +511,7 @@ struct platform_device ast_i2c_dev11_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev11_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev11_resources),
+@@ -536,7 +536,7 @@ struct platform_device ast_i2c_dev12_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev12_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev12_resources),
+@@ -561,7 +561,7 @@ struct platform_device ast_i2c_dev13_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev13_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev13_resources),
+@@ -586,7 +586,7 @@ struct platform_device ast_i2c_dev14_device = {
+ .dev = {
+ .dma_mask = &ast_i2c_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+- .platform_data = &ast_i2c_data,
++ .platform_data = &ast_i2c_data,
+ },
+ .resource = ast_i2c_dev14_resources,
+ .num_resources = ARRAY_SIZE(ast_i2c_dev14_resources),
+@@ -594,12 +594,196 @@ struct platform_device ast_i2c_dev14_device = {
+ #endif
+
+ /*--------- I2C Board devices ------------*/
+-//ASPEED AST2300 EVB I2C Device
++//ASPEED AST2300 EVB I2C Device
+ #if defined(CONFIG_ARCH_AST2300) || defined(CONFIG_ARCH_AST2400)
++
++#if defined(CONFIG_WEDGE100)
++
++static struct i2c_board_info __initdata wedge100_i2c_bus1[] = {
++ /* shared NIC, no kernel driver */
++};
++
++static struct i2c_board_info __initdata wedge100_i2c_bus2[] = {
++ /* TODO: one IR3581 and two IR3584 */
++};
++
++static struct i2c_board_info __initdata wedge100_i2c_bus3[] = {
++ /* TODO: one PWR1014A */
++};
++
++static struct i2c_board_info __initdata wedge100_i2c_bus4[] = {
++ {
++ I2C_BOARD_INFO("tmp75", 0x48),
++ },
++ {
++ I2C_BOARD_INFO("tmp75", 0x49),
++ },
++ {
++ I2C_BOARD_INFO("tmp75", 0x4a),
++ },
++ {
++ I2C_BOARD_INFO("tmp75", 0x4b),
++ },
++ {
++ I2C_BOARD_INFO("tmp75", 0x4c),
++ },
++};
++
++static struct i2c_board_info __initdata wedge100_i2c_bus5[] = {
++ /* Panther+ microserver */
++ {
++ I2C_BOARD_INFO("fb_panther_plus", 0x40),
++ },
++};
++
++static struct i2c_board_info __initdata wedge100_i2c_bus6[] = {
++ /* TODO: USB hub */
++};
++
++static struct i2c_board_info __initdata wedge100_i2c_bus7[] = {
++ {
++ I2C_BOARD_INFO("pcf8574", 0x2f),
++ },
++ {
++ I2C_BOARD_INFO("24c64", 0x51),
++ }
++};
++
++static struct i2c_board_info __initdata wedge100_i2c_bus8[] = {
++ /* BMC PHY EEPROM */
++ {
++ I2C_BOARD_INFO("24c02", 0x50),
++ },
++ // EEPROM on the pfe1100 power supplies
++ {
++ I2C_BOARD_INFO("24c64", 0x51),
++ },
++ {
++ I2C_BOARD_INFO("24c64", 0x52),
++ },
++ /* PSU driver */
++ {
++ I2C_BOARD_INFO("pfe1100", 0x59),
++ },
++ {
++ I2C_BOARD_INFO("pfe1100", 0x5a),
++ },
++};
++
++static struct i2c_board_info __initdata wedge100_i2c_bus9[] = {
++ {
++ I2C_BOARD_INFO("fancpld", 0x33),
++ },
++ {
++ I2C_BOARD_INFO("tmp75", 0x48),
++ },
++ {
++ I2C_BOARD_INFO("tmp75", 0x49),
++ },
++};
++
++/* i2c bus 10-12 on wedge100 are not connected as i2c bus */
++
++static struct i2c_board_info __initdata wedge100_i2c_bus13[] = {
++ {
++ I2C_BOARD_INFO("syscpld", 0x31),
++ },
++};
++
++/* i2c bus 14 on wedge100 are not connected as i2c bus */
++
++/* end of defined(CONFIG_WEDGE100) */
++
++#elif defined(CONFIG_YOSEMITE) || defined(CONFIG_FBPLATFORM1)
++
++//Under I2C Dev 1
++static struct i2c_board_info __initdata ast_i2c_board_info_1[] = {
++ // Slot#0 NIC sideband
++};
++
++//Under I2C Dev 2
++static struct i2c_board_info __initdata ast_i2c_board_info_2[] = {
++ // Slot#0 IPMB interface
++};
++
++//Under I2C Dev 3
++static struct i2c_board_info __initdata ast_i2c_board_info_3[] = {
++ // Slot#1 NIC sideband
++};
++
++
++//Under I2C Dev 4
++static struct i2c_board_info __initdata ast_i2c_board_info_4[] = {
++ // Slot#1 IPMB interface
++};
++
++//Under I2C Dev 5
++static struct i2c_board_info __initdata ast_i2c_board_info_5[] = {
++ // Slot#2 NIC sideband
++};
++
++//Under I2C Dev 6
++static struct i2c_board_info __initdata ast_i2c_board_info_6[] = {
++ // Slot#2 IPMB interface
++};
++
++//Under I2C Dev 7
++static struct i2c_board_info __initdata ast_i2c_board_info_7[] = {
++ // Slot#3 NIC sideband
++};
++
++//Under I2C Dev 8
++static struct i2c_board_info __initdata ast_i2c_board_info_8[] = {
++ // Slot#3 IPMB interface
++};
++
++//Under I2C Dev 9
++static struct i2c_board_info __initdata ast_i2c_board_info_9[] = {
++ // FRUID
++ {
++ I2C_BOARD_INFO("24c64", 0x51),
++ },
++};
++
++//Under I2C Dev 10
++static struct i2c_board_info __initdata ast_i2c_board_info_10[] = {
++ // Inlet and Outlet temp. sensors
++ {
++ I2C_BOARD_INFO("tmp75", 0x4e),
++ },
++ {
++ I2C_BOARD_INFO("tmp75", 0x4f),
++ },
++};
++
++//Under I2C Dev 11
++static struct i2c_board_info __initdata ast_i2c_board_info_11[] = {
++ // Hotswap Sensor
++ {
++ I2C_BOARD_INFO("adm1278", 0x40),
++ },
++};
++
++//Under I2C Dev 12
++static struct i2c_board_info __initdata ast_i2c_board_info_12[] = {
++ // Mezz Card LAN_SMB bus (PHY, Temp. Sensor)
++};
++
++//Under I2C Dev 13
++static struct i2c_board_info __initdata ast_i2c_board_info_13[] = {
++ // Mezz Card Mezz_SMB bus (FRUID, GPIO expander, QSFP+)
++};
++
++/* end of CONFIG_YOSEMITE */
++
++#else
++
++/* wedge */
++
+ //Under I2C Dev 1
+ static struct i2c_board_info __initdata ast_i2c_board_info_1[] = {
+ {
+- I2C_BOARD_INFO("cat9883", 0x4d),
++ I2C_BOARD_INFO("cat9883", 0x4d),
+ }
+ };
+
+@@ -612,15 +796,6 @@ static struct i2c_board_info __initdata ast_i2c_board_info_2[] = {
+ {
+ I2C_BOARD_INFO("ncp4200", 0x60),
+ },
+- {
+- I2C_BOARD_INFO("ncp4200", 0x61),
+- },
+- {
+- I2C_BOARD_INFO("ncp4200", 0x62),
+- },
+- {
+- I2C_BOARD_INFO("ncp4200", 0x63),
+- },
+ };
+
+
+@@ -632,15 +807,6 @@ static struct i2c_board_info __initdata ast_i2c_board_info_3[] = {
+ {
+ I2C_BOARD_INFO("ncp4200", 0x60),
+ },
+- {
+- I2C_BOARD_INFO("ncp4200", 0x61),
+- },
+- {
+- I2C_BOARD_INFO("ncp4200", 0x62),
+- },
+- {
+- I2C_BOARD_INFO("ncp4200", 0x63),
+- },
+ };
+
+
+@@ -675,7 +841,7 @@ static struct i2c_board_info __initdata ast_i2c_board_info_5[] = {
+ I2C_BOARD_INFO("24c128", 0x51),
+ },
+ };
+-
++
+ //Under I2C Dev 7
+ static struct i2c_board_info __initdata ast_i2c_board_info_7[] = {
+ // Wedge devices
+@@ -688,15 +854,23 @@ static struct i2c_board_info __initdata ast_i2c_board_info_7[] = {
+ },
+ {
+ I2C_BOARD_INFO("24c64", 0x50),
+- }
++ },
+ };
+
+
+ //Under I2C Dev 8
+ static struct i2c_board_info __initdata ast_i2c_board_info_8[] = {
+ {
++ // 6pack power supply
++ I2C_BOARD_INFO("pfe3000", 0x10),
++ },
++ {
+ // Eval board:
+- I2C_BOARD_INFO("lm75b", 0x4a),
++ I2C_BOARD_INFO("lm75b", 0x4a),
++ },
++ {
++ // 6pack power supply EEPROM
++ I2C_BOARD_INFO("24c64", 0x50),
+ },
+ // EEPROMS on the pfe1100 power supplies
+ {
+@@ -722,20 +896,12 @@ static struct i2c_board_info __initdata ast_i2c_board_info_9[] = {
+ {
+ I2C_BOARD_INFO("ncp4200", 0x60),
+ },
+- {
+- I2C_BOARD_INFO("ncp4200", 0x61),
+- },
+- {
+- I2C_BOARD_INFO("ncp4200", 0x62),
+- },
+- {
+- I2C_BOARD_INFO("ncp4200", 0x63),
+- },
+ };
+
+ //Under I2C Dev 12
+ static struct i2c_board_info __initdata ast_i2c_board_info_12[] = {
+ {
++ // Early version of 6pack
+ I2C_BOARD_INFO("pfe3000", 0x10),
+ },
+ };
+@@ -747,6 +913,10 @@ static struct i2c_board_info __initdata ast_i2c_board_info_13[] = {
+ },
+ };
+
++/* end of WEDGE case */
++#endif
++
++/* end of defined(CONFIG_ARCH_AST2300) || defined(CONFIG_ARCH_AST2400) */
+ #endif
+
+ /*-------------------------------------*/
+@@ -755,7 +925,7 @@ void __init ast_add_device_i2c(void)
+ //I2C Multi-Pin
+ ast_scu_multi_func_i2c();
+
+- //SCU I2C Reset
++ //SCU I2C Reset
+ ast_scu_init_i2c();
+
+ ast_i2c_data.reg_gr = ioremap(AST_I2C_BASE, 4*SZ_16);
+@@ -777,8 +947,48 @@ void __init ast_add_device_i2c(void)
+ return;
+ }
+ #endif
+- //TODO
+- pool_buff_page_init(ast_i2c_data.buf_pool);
++
++ pool_buff_page_init(ast_i2c_data.buf_pool);
++
++#if defined(CONFIG_WEDGE100)
++
++ platform_device_register(&ast_i2c_dev1_device);
++ i2c_register_board_info(0, wedge100_i2c_bus1, ARRAY_SIZE(wedge100_i2c_bus1));
++
++ platform_device_register(&ast_i2c_dev2_device);
++ i2c_register_board_info(1, wedge100_i2c_bus2, ARRAY_SIZE(wedge100_i2c_bus2));
++
++ platform_device_register(&ast_i2c_dev3_device);
++ i2c_register_board_info(2, wedge100_i2c_bus3, ARRAY_SIZE(wedge100_i2c_bus3));
++
++ platform_device_register(&ast_i2c_dev4_device);
++ i2c_register_board_info(3, wedge100_i2c_bus4, ARRAY_SIZE(wedge100_i2c_bus4));
++
++ platform_device_register(&ast_i2c_dev5_device);
++ i2c_register_board_info(4, wedge100_i2c_bus5, ARRAY_SIZE(wedge100_i2c_bus5));
++
++ platform_device_register(&ast_i2c_dev6_device);
++ i2c_register_board_info(5, wedge100_i2c_bus6, ARRAY_SIZE(wedge100_i2c_bus6));
++
++ platform_device_register(&ast_i2c_dev7_device);
++ i2c_register_board_info(6, wedge100_i2c_bus7, ARRAY_SIZE(wedge100_i2c_bus7));
++
++ platform_device_register(&ast_i2c_dev8_device);
++ i2c_register_board_info(7, wedge100_i2c_bus8, ARRAY_SIZE(wedge100_i2c_bus8));
++
++ platform_device_register(&ast_i2c_dev9_device);
++ i2c_register_board_info(8, wedge100_i2c_bus9, ARRAY_SIZE(wedge100_i2c_bus9));
++
++ /* i2c bus 10 - 12 are not used as i2c on wedge100 */
++
++ platform_device_register(&ast_i2c_dev13_device);
++ i2c_register_board_info(12, wedge100_i2c_bus13, ARRAY_SIZE(wedge100_i2c_bus13));
++
++ /* i2c bug 14 is not used as i2c on wedge100 */
++
++ /* end of defined(CONFIG_WEDGE100) */
++#else
++
+ platform_device_register(&ast_i2c_dev1_device);
+ i2c_register_board_info(0, ast_i2c_board_info_1, ARRAY_SIZE(ast_i2c_board_info_1));
+ platform_device_register(&ast_i2c_dev2_device);
+@@ -790,17 +1000,27 @@ void __init ast_add_device_i2c(void)
+ platform_device_register(&ast_i2c_dev5_device);
+ i2c_register_board_info(4, ast_i2c_board_info_5, ARRAY_SIZE(ast_i2c_board_info_5));
+ platform_device_register(&ast_i2c_dev6_device);
++#if defined(CONFIG_YOSEMITE)
++ i2c_register_board_info(5, ast_i2c_board_info_6, ARRAY_SIZE(ast_i2c_board_info_6));
++#endif
+ platform_device_register(&ast_i2c_dev7_device);
+ i2c_register_board_info(6, ast_i2c_board_info_7, ARRAY_SIZE(ast_i2c_board_info_7));
+ platform_device_register(&ast_i2c_dev8_device);
+ i2c_register_board_info(7, ast_i2c_board_info_8, ARRAY_SIZE(ast_i2c_board_info_8));
+- platform_device_register(&ast_i2c_dev9_device);
++ platform_device_register(&ast_i2c_dev9_device);
+ i2c_register_board_info(8, ast_i2c_board_info_9, ARRAY_SIZE(ast_i2c_board_info_9));
+
+ #if defined(CONFIG_ARCH_AST2400)
+ platform_device_register(&ast_i2c_dev10_device);
++
++#if defined(CONFIG_YOSEMITE)
++ i2c_register_board_info(9, ast_i2c_board_info_10, ARRAY_SIZE(ast_i2c_board_info_10));
++ platform_device_register(&ast_i2c_dev11_device);
++ i2c_register_board_info(10, ast_i2c_board_info_11, ARRAY_SIZE(ast_i2c_board_info_11));
++#endif
++
+ #if defined(CONFIG_MMC_AST)
+- //Due to share pin with SD
++ //Due to share pin with SD
+ #else
+ /*
+ * On Wedge, bus 13 is used as i2c bus. Bus 12 is used on other
+@@ -812,7 +1032,12 @@ void __init ast_add_device_i2c(void)
+ i2c_register_board_info(11, ast_i2c_board_info_12, ARRAY_SIZE(ast_i2c_board_info_12));
+ platform_device_register(&ast_i2c_dev13_device);
+ i2c_register_board_info(12, ast_i2c_board_info_13, ARRAY_SIZE(ast_i2c_board_info_13));
+-#endif
++#endif
++
++ /* end of defined(CONFIG_ARCH_AST2400) */
++#endif
++
++ /* end of else of defined(CONFIG_WEDGE100) */
+ #endif
+ }
+ #else
+diff --git a/arch/arm/plat-aspeed/dev-spi.c b/arch/arm/plat-aspeed/dev-spi.c
+index e22c49e..0cb0189 100644
+--- a/arch/arm/plat-aspeed/dev-spi.c
++++ b/arch/arm/plat-aspeed/dev-spi.c
+@@ -344,8 +344,8 @@ static struct flash_platform_data wedge_spi_flash_data = {
+
+
+ /* Device info for the flash on ast-spi */
+-#ifdef CONFIG_ARCH_AST2400
+-static struct mtd_partition ast_spi5_flash_partitions[] = {
++#ifdef CONFIG_WEDGE
++static struct mtd_partition wedge_spi5_flash_partitions[] = {
+ {
+ .name = "led-fpga",
+ .offset = 0, /* From 0 */
+@@ -355,8 +355,8 @@ static struct mtd_partition ast_spi5_flash_partitions[] = {
+
+ static struct flash_platform_data wedge_spi5_flash_data = {
+ .type = "at45db011d",
+- .nr_parts = ARRAY_SIZE(ast_spi5_flash_partitions),
+- .parts = ast_spi5_flash_partitions,
++ .nr_parts = ARRAY_SIZE(wedge_spi5_flash_partitions),
++ .parts = wedge_spi5_flash_partitions,
+ };
+ #endif
+
+@@ -372,6 +372,7 @@ static struct spi_board_info ast_spi_devices[] = {
+ },
+ #endif
+ #ifdef CONFIG_ARCH_AST2400
++#ifdef CONFIG_WEDGE
+ {
+ .modalias = "mtd_dataflash",
+ .platform_data = &wedge_spi5_flash_data,
+@@ -380,6 +381,15 @@ static struct spi_board_info ast_spi_devices[] = {
+ .bus_num = 5,
+ .mode = SPI_MODE_0,
+ },
++#elif defined CONFIG_WEDGE100
++ {
++ .modalias = "spidev",
++ .chip_select = 0,
++ .max_speed_hz = 33 * 1000 * 1000,
++ .bus_num = 5,
++ .mode = SPI_MODE_0,
++ },
++#endif
+ {
+ .modalias = "m25p80",
+ .platform_data = &wedge_spi_flash_data,
+@@ -389,13 +399,6 @@ static struct spi_board_info ast_spi_devices[] = {
+ .mode = SPI_MODE_0,
+ },
+ #endif
+- {
+- .modalias = "spidev",
+- .chip_select = 0,
+- .max_speed_hz = 30 * 1000 * 1000,
+- .bus_num = 1,
+- .mode = SPI_MODE_0,
+- },
+ };
+
+ #if defined(AST_SPI1_BASE)
+@@ -490,5 +493,3 @@ void __init ast_add_device_spi(void)
+ #else
+ void __init ast_add_device_spi(void) {}
+ #endif
+-
+-
+diff --git a/arch/arm/plat-aspeed/dev-uart.c b/arch/arm/plat-aspeed/dev-uart.c
+index 0b7b614..e424a5a 100644
+--- a/arch/arm/plat-aspeed/dev-uart.c
++++ b/arch/arm/plat-aspeed/dev-uart.c
+@@ -6,11 +6,11 @@
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+@@ -50,14 +50,14 @@ static struct plat_serial8250_port ast_uart_data[] = {
+ .irq = IRQ_UART0,
+ .uartclk = (24*1000000L),
+ .regshift = 2,
+-#if defined(CONFIG_COLDFIRE)
++#if defined(CONFIG_COLDFIRE)
+ .iotype = UPIO_MEM32,
+ #else
+ .iotype = UPIO_MEM,
+-#endif
++#endif
+ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ },
+-#if defined(CONFIG_ARCH_AST1010)
++#if defined(CONFIG_ARCH_AST1010)
+ {
+ .mapbase = AST_UART1_BASE,
+ .irq = IRQ_UART1,
+@@ -65,7 +65,7 @@ static struct plat_serial8250_port ast_uart_data[] = {
+ .regshift = 2,
+ .iotype = UPIO_MEM32,
+ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+- },
++ },
+ {
+ .mapbase = AST_UART2_BASE,
+ .irq = IRQ_UART2,
+@@ -73,7 +73,7 @@ static struct plat_serial8250_port ast_uart_data[] = {
+ .regshift = 2,
+ .iotype = UPIO_MEM32,
+ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+- },
++ },
+ #else
+ //BMC UART 1 ,2 default to LPC
+ #ifdef CONFIG_ARCH_AST1070
+@@ -85,7 +85,7 @@ static struct plat_serial8250_port ast_uart_data[] = {
+ .regshift = 2,
+ .iotype = UPIO_MEM,
+ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+- },
++ },
+ #endif
+ #ifdef AST_UART2_BASE
+ {
+@@ -95,7 +95,7 @@ static struct plat_serial8250_port ast_uart_data[] = {
+ .regshift = 2,
+ .iotype = UPIO_MEM,
+ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+- },
++ },
+ #endif
+ #endif
+ #ifdef AST_UART1_BASE
+@@ -109,6 +109,19 @@ static struct plat_serial8250_port ast_uart_data[] = {
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ },
+ #endif
++#if defined(CONFIG_YOSEMITE) //Without this, tty offset might change for others
++#ifdef AST_UART2_BASE
++ {
++ .mapbase = AST_UART2_BASE,
++ .membase = (char*)(IO_ADDRESS(AST_UART2_BASE)),
++ .irq = IRQ_UART2,
++ .uartclk = (24*1000000L),
++ .regshift = 2,
++ .iotype = UPIO_MEM,
++ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
++ },
++#endif
++#endif
+ #ifdef AST_UART3_BASE
+ {
+ .mapbase = AST_UART3_BASE,
+@@ -117,7 +130,7 @@ static struct plat_serial8250_port ast_uart_data[] = {
+ .regshift = 2,
+ .iotype = UPIO_MEM,
+ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+- },
++ },
+ #endif
+ #ifdef AST_UART4_BASE
+ {
+@@ -127,9 +140,9 @@ static struct plat_serial8250_port ast_uart_data[] = {
+ .regshift = 2,
+ .iotype = UPIO_MEM,
+ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+- },
++ },
++#endif
+ #endif
+-#endif
+ { },
+ };
+
+@@ -144,11 +157,16 @@ struct platform_device ast_uart_device = {
+ void __init ast_add_device_uart(void)
+ {
+ #if defined(CONFIG_ARCH_AST1010)
++#elif defined(CONFIG_YOSEMITE)
++ ast_scu_multi_func_uart(1);
++ ast_scu_multi_func_uart(2);
++ ast_scu_multi_func_uart(3);
++ ast_scu_multi_func_uart(4);
+ #else
+- ast_scu_multi_func_uart(1);
+- ast_scu_multi_func_uart(3);
+- ast_scu_multi_func_uart(4);
+-#endif
++ ast_scu_multi_func_uart(1);
++ ast_scu_multi_func_uart(3);
++ ast_scu_multi_func_uart(4);
++#endif
+ platform_device_register(&ast_uart_device);
+ }
+ #else
+diff --git a/arch/arm/plat-aspeed/irq.c b/arch/arm/plat-aspeed/irq.c
+index b118359..f6100fa 100644
+--- a/arch/arm/plat-aspeed/irq.c
++++ b/arch/arm/plat-aspeed/irq.c
+@@ -48,13 +48,14 @@ static void ast_mask_irq(unsigned int irq)
+ if((irq >= IRQ_TIMER0) && (irq <= IRQ_TIMER2))
+ timer = 1;
+ #endif
+-
+- if (irq > 32) {
++
++ // for irq0-irq31 use LOW register; for irq32-irq63 use HIGH register set.
++ if (irq >= 32) {
+ i=1;
+ irq = irq - 32;
+ } else
+ i=0;
+-
++
+ regVal = readl(AST_INTR_DIS(i));
+ regVal |= (1 << irq);
+ writel(regVal, AST_INTR_DIS(i));
+@@ -63,8 +64,8 @@ static void ast_mask_irq(unsigned int irq)
+ * clear the interrupt
+ */
+ if(timer)
+- IRQ_EDGE_CLEAR(i,irq);
+-
++ IRQ_EDGE_CLEAR(i,irq);
++
+ }
+
+ static void ast_unmask_irq(unsigned int irq)
+@@ -72,12 +73,13 @@ static void ast_unmask_irq(unsigned int irq)
+ int i;
+ u32 regVal;
+
+- if (irq > 32) {
++ // for irq0-irq31 use LOW register; for irq32-irq63 use HIGH register set.
++ if (irq >= 32) {
+ i=1;
+ irq = irq - 32;
+ } else
+ i=0;
+-
++
+ regVal = readl(AST_INTR_EN(i));
+ regVal |= (1 << irq);
+ writel(regVal, AST_INTR_EN(i));
+@@ -88,8 +90,8 @@ static struct irq_chip ast_irq_chip = {
+ .ack = ast_mask_irq,
+ .mask = ast_mask_irq,
+ .unmask = ast_unmask_irq,
+-};
+-
++};
++
+ void __init ast_init_irq(void)
+ {
+ unsigned int i;
+@@ -107,8 +109,8 @@ void __init ast_init_irq(void)
+ writel(0xFFFFFFFF, AST_INTR_EDGE_CLR(1));
+ #endif
+
+- //TOTAL IRQ NUM =
+- for (i = 0; i < AST_VIC_NUM; i++)
++ //TOTAL IRQ NUM =
++ for (i = 0; i < AST_VIC_NUM; i++)
+ {
+ if(i<32) {
+ if((i >= IRQ_TIMER0) && (i <= IRQ_TIMER2)) //Timer0/1/2
+@@ -125,9 +127,9 @@ void __init ast_init_irq(void)
+ IRQ_SET_HIGH_LEVEL(1,i-32);
+ IRQ_SET_LEVEL_TRIGGER(1,i-32);
+ }
+-#endif
++#endif
+ }
+-
++
+ set_irq_chip(i, &ast_irq_chip);
+ set_irq_handler(i, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+diff --git a/drivers/hwmon/ast_adc.c b/drivers/hwmon/ast_adc.c
+index 3f95dc6..8f5aa54 100644
+--- a/drivers/hwmon/ast_adc.c
++++ b/drivers/hwmon/ast_adc.c
+@@ -13,10 +13,10 @@
+ * 2012.11.26: Initial version [Ryan Chen]
+ */
+
+-/* attr ADC sysfs 0~max adc channel
++/* attr ADC sysfs 0~max adc channel
+ * 0 - show/store enable
+ * 3 - show value
+-* 1 - show/store alarm_en set enable
++* 1 - show/store alarm_en set enable
+ * 2 - show alarm get statuse
+ * 4 - show/store upper
+ * 5 - show/store lower */
+@@ -44,13 +44,33 @@
+
+ #define REST_DESIGN 5
+
++
++#ifdef CONFIG_YOSEMITE
++enum {
++ ADC_P5V = 0,
++ ADC_P12V,
++ ADC_P3V3_STBY,
++ ADC_P12V_SLOT0,
++ ADC_P12V_SLOT1,
++ ADC_P12V_SLOT2,
++ ADC_P12V_SLOT3,
++ ADC_P3V3,
++};
++
++enum {
++ REST_DESIGN_P3V3 = 6,
++ REST_DESIGN_P5V = 7,
++ REST_DESIGN_P12V = 8,
++};
++#endif // CONFIG_YOSEMITE
++
+ struct adc_vcc_ref_data {
+ int v2;
+ int r1;
+- int r2;
++ int r2;
+ };
+
+-static struct adc_vcc_ref_data adc_vcc_ref[6] = {
++static struct adc_vcc_ref_data adc_vcc_ref[9] = {
+ [0] = {
+ .v2 = 0,
+ .r1 = 5600,
+@@ -81,6 +101,24 @@ static struct adc_vcc_ref_data adc_vcc_ref[6] = {
+ .r1 = 1000,
+ .r2 = 1000,
+ },
++ // P3V3
++ [6] = {
++ .v2 = 0,
++ .r1 = 5110,
++ .r2 = 8250,
++ },
++ // P5V
++ [7] = {
++ .v2 = 0,
++ .r1 = 5110,
++ .r2 = 3480,
++ },
++ // P12V
++ [8] = {
++ .v2 = 0,
++ .r1 = 5110,
++ .r2 = 1020,
++ },
+ };
+
+ /* Divisors for voltage sense; right now adc5 & adc6 divide by 2 */
+@@ -93,7 +131,7 @@ static int adc_divisor[] = { 1, 1, 1, 1,
+ struct ast_adc_data {
+ struct device *hwmon_dev;
+ void __iomem *reg_base; /* virtual */
+- int irq; //ADC IRQ number
++ int irq; //ADC IRQ number
+ int compen_value; //Compensating value
+ };
+
+@@ -123,14 +161,14 @@ static void ast_adc_ctrl_init(void)
+ ast_adc_write(ast_adc, AST_ADC_CTRL_COMPEN | AST_ADC_CTRL_NORMAL | AST_ADC_CTRL_EN, AST_ADC_CTRL);
+
+ //Set wait a sensing cycle t (s) = 1000 * 12 * (1/PCLK) * 2 * (ADC0c[31:17] + 1) * (ADC0c[9:0] +1)
+- //ex : pclk = 48Mhz , ADC0c[31:17] = 0, ADC0c[9:0] = 0x40 : 64, ADC0c[31:17] = 0x3e7 : 999
++ //ex : pclk = 48Mhz , ADC0c[31:17] = 0, ADC0c[9:0] = 0x40 : 64, ADC0c[31:17] = 0x3e7 : 999
+ // --> 0.0325s = 12 * 2 * (0x3e7 + 1) *(64+1) / 48000000
+- // --> 0.0005s = 12 * 2 * (0x3e7 + 1) / 48000000
+-
++ // --> 0.0005s = 12 * 2 * (0x3e7 + 1) / 48000000
++
+ pclk = ast_get_pclk();
+
+ #if defined(CONFIG_ARCH_AST2300)
+- ast_adc_write(ast_adc, 0x3e7, AST_ADC_CLK);
++ ast_adc_write(ast_adc, 0x3e7, AST_ADC_CLK);
+
+ ast_adc_write(ast_adc, AST_ADC_CTRL_CH12_EN | AST_ADC_CTRL_COMPEN_CLR| ast_adc_read(ast_adc, AST_ADC_CTRL), AST_ADC_CTRL);
+
+@@ -141,16 +179,16 @@ static void ast_adc_ctrl_init(void)
+ ast_adc->compen_value = 0x200 - (ast_adc_read(ast_adc, AST_ADC_CH12_13) & AST_ADC_L_CH_MASK);
+ else
+ ast_adc->compen_value = 0 - (ast_adc_read(ast_adc, AST_ADC_CH12_13) & AST_ADC_L_CH_MASK);
+-
+- printk("compensating value %d \n",ast_adc->compen_value);
+-
++
++ // printk("compensating value %d \n",ast_adc->compen_value);
++
+ #elif defined(CONFIG_ARCH_AST2400)
+
+ //For AST2400 A0 workaround ... ADC0c = 1 ;
+ // ast_adc_write(ast_adc, 1, AST_ADC_CLK);
+ // ast_adc_write(ast_adc, (0x3e7<< 17) | 0x40, AST_ADC_CLK);
+ ast_adc_write(ast_adc, 0x40, AST_ADC_CLK);
+-
++
+ ast_adc_write(ast_adc, AST_ADC_CTRL_CH0_EN | AST_ADC_CTRL_COMPEN | AST_ADC_CTRL_NORMAL | AST_ADC_CTRL_EN, AST_ADC_CTRL);
+
+ ast_adc_read(ast_adc, AST_ADC_CTRL);
+@@ -159,15 +197,15 @@ static void ast_adc_ctrl_init(void)
+
+ //compensating value = 0x200 - ADC10[9:0]
+ ast_adc->compen_value = 0x200 - (ast_adc_read(ast_adc, AST_ADC_CH0_1) & AST_ADC_L_CH_MASK);
+- printk("compensating value %d \n",ast_adc->compen_value);
++ // printk("compensating value %d \n",ast_adc->compen_value);
+
+ #elif defined(CONFIG_ARCH_AST2500)
+-// TODO ...
+-// scu read trim
++// TODO ...
++// scu read trim
+ // write trim 0xc4 [3:0]
+-
++
+ ast_adc_write(ast_adc, 0x40, AST_ADC_CLK);
+-
++
+ ast_adc_write(ast_adc, AST_ADC_CTRL_NORMAL | AST_ADC_CTRL_EN, AST_ADC_CTRL);
+
+ while(!ast_adc_read(ast_adc, AST_ADC_CTRL) & 0x100);
+@@ -175,17 +213,17 @@ static void ast_adc_ctrl_init(void)
+ ast_adc_write(ast_adc, AST_ADC_CTRL_COMPEN | AST_ADC_CTRL_NORMAL | AST_ADC_CTRL_EN, AST_ADC_CTRL);
+
+ while(ast_adc_read(ast_adc, AST_ADC_CTRL) & AST_ADC_CTRL_COMPEN);
+-
++
+ //compensating value = 0x200 - ADC10[9:0]
+ ast_adc->compen_value = 0x200 - ((ast_adc_read(ast_adc, AST_ADC_TRIM) >> 16) & 0x3ff);
+- printk("compensating value %d \n",ast_adc->compen_value);
+-
++ // printk("compensating value %d \n",ast_adc->compen_value);
++
+ #else
+ #err "No define for ADC "
+ #endif
+
+ ast_adc_write(ast_adc, AST_ADC_CTRL_NORMAL | AST_ADC_CTRL_EN, AST_ADC_CTRL);
+-
++
+ }
+
+ static u16
+@@ -203,9 +241,9 @@ ast_get_adc_hyster_lower(struct ast_adc_data *ast_adc, u8 adc_ch)
+ static void
+ ast_set_adc_hyster_lower(struct ast_adc_data *ast_adc, u8 adc_ch, u16 value)
+ {
+- ast_adc_write(ast_adc,
++ ast_adc_write(ast_adc,
+ (ast_adc_read(ast_adc, AST_ADC_HYSTER0 + (adc_ch *4)) & ~AST_ADC_L_BOUND) |
+- value,
++ value,
+ AST_ADC_HYSTER0 + (adc_ch *4));
+
+ }
+@@ -224,9 +262,9 @@ ast_get_adc_hyster_upper(struct ast_adc_data *ast_adc, u8 adc_ch)
+ static void
+ ast_set_adc_hyster_upper(struct ast_adc_data *ast_adc, u8 adc_ch, u32 value)
+ {
+- ast_adc_write(ast_adc,
++ ast_adc_write(ast_adc,
+ (ast_adc_read(ast_adc, AST_ADC_HYSTER0 + (adc_ch *4)) & ~AST_ADC_H_BOUND) |
+- (value << 16),
++ (value << 16),
+ AST_ADC_HYSTER0 + (adc_ch *4));
+
+ }
+@@ -244,7 +282,7 @@ ast_get_adc_hyster_en(struct ast_adc_data *ast_adc, u8 adc_ch)
+ static void
+ ast_set_adc_hyster_en(struct ast_adc_data *ast_adc, u8 adc_ch, u8 enable)
+ {
+- //tacho source
++ //tacho source
+ if(enable == 1)
+ ast_adc_write(ast_adc,
+ ast_adc_read(ast_adc, AST_ADC_HYSTER0 + (adc_ch *4)) | AST_ADC_HYSTER_EN,
+@@ -270,9 +308,9 @@ ast_get_adc_lower(struct ast_adc_data *ast_adc, u8 adc_ch)
+ static void
+ ast_set_adc_lower(struct ast_adc_data *ast_adc, u8 adc_ch, u16 value)
+ {
+- ast_adc_write(ast_adc,
++ ast_adc_write(ast_adc,
+ (ast_adc_read(ast_adc, AST_ADC_BOUND0 + (adc_ch *4)) & ~AST_ADC_L_BOUND) |
+- value,
++ value,
+ AST_ADC_BOUND0 + (adc_ch *4));
+
+ }
+@@ -293,9 +331,9 @@ ast_get_adc_upper(struct ast_adc_data *ast_adc, u8 adc_ch)
+ static void
+ ast_set_adc_upper(struct ast_adc_data *ast_adc, u8 adc_ch, u32 value)
+ {
+- ast_adc_write(ast_adc,
++ ast_adc_write(ast_adc,
+ (ast_adc_read(ast_adc, AST_ADC_BOUND0 + (adc_ch *4)) & ~AST_ADC_H_BOUND) |
+- (value << 16),
++ (value << 16),
+ AST_ADC_BOUND0 + (adc_ch *4));
+
+ }
+@@ -304,7 +342,7 @@ ast_set_adc_upper(struct ast_adc_data *ast_adc, u8 adc_ch, u32 value)
+ static u8
+ ast_get_adc_alarm(struct ast_adc_data *ast_adc, u8 adc_ch)
+ {
+- //adc ch source
++ //adc ch source
+ if(ast_adc_read(ast_adc, AST_ADC_IER) & (0x1 << adc_ch))
+ return 1;
+ else
+@@ -322,61 +360,61 @@ ast_get_adc_value(struct ast_adc_data *ast_adc, u8 adc_ch)
+ break;
+ case 1:
+ tmp = (ast_adc_read(ast_adc, AST_ADC_CH0_1) & AST_ADC_H_CH_MASK) >> 16;
+- break;
++ break;
+ case 2:
+ tmp = ast_adc_read(ast_adc, AST_ADC_CH2_3) & AST_ADC_L_CH_MASK;
+ break;
+ case 3:
+ tmp = (ast_adc_read(ast_adc, AST_ADC_CH2_3) & AST_ADC_H_CH_MASK) >> 16;
+- break;
++ break;
+ case 4:
+ tmp = ast_adc_read(ast_adc, AST_ADC_CH4_5) & AST_ADC_L_CH_MASK;
+ break;
+ case 5:
+ tmp = (ast_adc_read(ast_adc, AST_ADC_CH4_5) & AST_ADC_H_CH_MASK) >> 16;
+- break;
++ break;
+ case 6:
+ tmp = ast_adc_read(ast_adc, AST_ADC_CH6_7) & AST_ADC_L_CH_MASK;
+ break;
+ case 7:
+ tmp = (ast_adc_read(ast_adc, AST_ADC_CH6_7) & AST_ADC_H_CH_MASK) >> 16;
+- break;
++ break;
+ case 8:
+ tmp = ast_adc_read(ast_adc, AST_ADC_CH8_9) & AST_ADC_L_CH_MASK;
+ break;
+ case 9:
+ tmp = (ast_adc_read(ast_adc, AST_ADC_CH8_9) & AST_ADC_H_CH_MASK) >> 16;
+- break;
++ break;
+ case 10:
+ tmp = ast_adc_read(ast_adc, AST_ADC_CH10_11) & AST_ADC_L_CH_MASK;
+ break;
+ case 11:
+ tmp = (ast_adc_read(ast_adc, AST_ADC_CH10_11) & AST_ADC_H_CH_MASK) >> 16;
+- break;
++ break;
+ case 12:
+ tmp = ast_adc_read(ast_adc, AST_ADC_CH12_13) & AST_ADC_L_CH_MASK;
+ break;
+ case 13:
+ tmp = (ast_adc_read(ast_adc, AST_ADC_CH12_13) & AST_ADC_H_CH_MASK) >> 16;
+- break;
++ break;
+ case 14:
+ tmp = ast_adc_read(ast_adc, AST_ADC_CH14_15) & AST_ADC_L_CH_MASK;
+ break;
+ case 15:
+ tmp = (ast_adc_read(ast_adc, AST_ADC_CH14_15) & AST_ADC_H_CH_MASK) >> 16;
+- break;
++ break;
+
+ }
+
+ tmp += ast_adc->compen_value;
+
+ // printk("voltage = %d \n",tmp);
+-
++
+ return tmp;
+
+ }
+
+-static u8
++static u8
+ ast_get_adc_en(struct ast_adc_data *ast_adc, u8 adc_ch)
+ {
+ u8 tmp=0;
+@@ -390,7 +428,7 @@ ast_get_adc_en(struct ast_adc_data *ast_adc, u8 adc_ch)
+
+ }
+
+-static void
++static void
+ ast_set_adc_en(struct ast_adc_data *ast_adc, u8 adc_ch, u8 enable)
+ {
+ if(enable)
+@@ -401,7 +439,7 @@ ast_set_adc_en(struct ast_adc_data *ast_adc, u8 adc_ch, u8 enable)
+
+
+ /* NAME sysfs */
+-static ssize_t
++static ssize_t
+ show_name(struct device *dev, struct device_attribute *devattr,
+ char *buf)
+ {
+@@ -416,38 +454,63 @@ static const struct attribute_group name_attribute_groups = {
+ .attrs = name_attributes,
+ };
+
+-/* attr ADC sysfs 0~max adc channel
++/* attr ADC sysfs 0~max adc channel
+ * 0 - show/store channel enable
+-* 1 - show value
++* 1 - show value
+ * 2 - show alarm get statuse
+ * 3 - show/store upper
+-* 4 - show/store lower
+-* 5 - show/store hystersis enable
+-* 6 - show/store hystersis upper
+-* 7 - show/store hystersis low
++* 4 - show/store lower
++* 5 - show/store hystersis enable
++* 6 - show/store hystersis upper
++* 7 - show/store hystersis low
+ */
+
+-static u32
++static u32
+ ast_get_voltage(int idx) {
++ u8 rest_design = REST_DESIGN;
+ u16 tmp;
+ u32 voltage, tmp1, tmp2, tmp3;
+ tmp = ast_get_adc_value(ast_adc, idx);
++
++#ifdef CONFIG_YOSEMITE
++ switch (idx) {
++ case ADC_P3V3:
++ case ADC_P3V3_STBY:
++ rest_design = REST_DESIGN_P3V3;
++ break;
++ case ADC_P5V:
++ rest_design = REST_DESIGN_P5V;
++ break;
++ case ADC_P12V:
++ case ADC_P12V_SLOT0:
++ case ADC_P12V_SLOT1:
++ case ADC_P12V_SLOT2:
++ case ADC_P12V_SLOT3:
++ rest_design = REST_DESIGN_P12V;
++ break;
++ default:
++ rest_design = REST_DESIGN;
++ }
++#endif // CONFIG_YOSEMITE
++
+ // Voltage Sense Method
+- tmp1 = (adc_vcc_ref[REST_DESIGN].r1 + adc_vcc_ref[REST_DESIGN].r2) * tmp * 25 * 10;
+- tmp2 = adc_vcc_ref[REST_DESIGN].r2 * 1024 ;
+- tmp3 = (adc_vcc_ref[REST_DESIGN].r1 * adc_vcc_ref[REST_DESIGN].v2) / adc_vcc_ref[REST_DESIGN].r2;
++ tmp1 = (adc_vcc_ref[rest_design].r1 + adc_vcc_ref[rest_design].r2) * tmp * 25 * 10;
++ tmp2 = adc_vcc_ref[rest_design].r2 * 1024 ;
++ tmp3 = (adc_vcc_ref[rest_design].r1 * adc_vcc_ref[rest_design].v2) / adc_vcc_ref[rest_design].r2;
+ // printk("tmp3 = %d \n",tmp3);
+ voltage = (tmp1/tmp2) - tmp3;
+
++#ifndef CONFIG_YOSEMITE
+ // Higher voltage inputs require a divisor
+
+ if (adc_divisor[idx])
+ voltage /= adc_divisor[idx];
++#endif //CONFIG_YOSEMITE
+
+ return voltage;
+ }
+
+-static ssize_t
++static ssize_t
+ ast_show_adc(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
+ {
+ struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
+@@ -455,7 +518,7 @@ ast_show_adc(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
+
+ //sensor_attr->index : pwm_ch#
+ //sensor_attr->nr : attr#
+- switch(sensor_attr->nr)
++ switch(sensor_attr->nr)
+ {
+ case 0: //channel enable, disable
+ return sprintf(sysfsbuf, "%d : %s\n", ast_get_adc_en(ast_adc,sensor_attr->index),ast_get_adc_en(ast_adc,sensor_attr->index) ? "Enable":"Disable");
+@@ -466,23 +529,23 @@ ast_show_adc(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
+ break;
+ case 2: //alarm
+ return sprintf(sysfsbuf, "%d \n", ast_get_adc_alarm(ast_adc,sensor_attr->index));
+- break;
++ break;
+ case 3: //upper
+ return sprintf(sysfsbuf, "%d \n", ast_get_adc_upper(ast_adc,sensor_attr->index));
+- break;
++ break;
+ case 4: //lower
+ return sprintf(sysfsbuf, "%d \n", ast_get_adc_lower(ast_adc,sensor_attr->index));
+- break;
+- case 5: //hystersis enable
++ break;
++ case 5: //hystersis enable
+ return sprintf(sysfsbuf, "%d : %s\n", ast_get_adc_hyster_en(ast_adc,sensor_attr->index),ast_get_adc_hyster_en(ast_adc,sensor_attr->index) ? "Enable":"Disable");
+- break;
++ break;
+ case 6: //hystersis upper
+ return sprintf(sysfsbuf, "%d \n", ast_get_adc_hyster_upper(ast_adc,sensor_attr->index));
+- break;
++ break;
+ case 7: //hystersis lower
+ return sprintf(sysfsbuf, "%d \n", ast_get_adc_hyster_lower(ast_adc,sensor_attr->index));
+- break;
+- case 8:
++ break;
++ case 8:
+ voltage = ast_get_voltage(sensor_attr->index);
+ return sprintf(sysfsbuf, "%d\n",voltage * 10);
+
+@@ -492,7 +555,7 @@ ast_show_adc(struct device *dev, struct device_attribute *attr, char *sysfsbuf)
+ }
+ }
+
+-static ssize_t
++static ssize_t
+ ast_store_adc(struct device *dev, struct device_attribute *attr, const char *sysfsbuf, size_t count)
+ {
+ u32 input_val;
+@@ -503,16 +566,16 @@ ast_store_adc(struct device *dev, struct device_attribute *attr, const char *sys
+
+ //sensor_attr->index : pwm_ch#
+ //sensor_attr->nr : attr#
+- switch(sensor_attr->nr)
++ switch(sensor_attr->nr)
+ {
+ case 0: //enable, disable
+ ast_set_adc_en(ast_adc, sensor_attr->index, input_val);
+ break;
+ case 1: //value
+-
++
+ break;
+ case 2: //alarm
+- break;
++ break;
+ case 3:
+ ast_set_adc_upper(ast_adc, sensor_attr->index, input_val);
+ break;
+@@ -521,14 +584,14 @@ ast_store_adc(struct device *dev, struct device_attribute *attr, const char *sys
+ break;
+ case 5: //hystersis
+ ast_set_adc_hyster_en(ast_adc, sensor_attr->index, input_val);
+- break;
++ break;
+ case 6:
+ ast_set_adc_hyster_upper(ast_adc, sensor_attr->index, input_val);
+ break;
+ case 7:
+ ast_set_adc_hyster_lower(ast_adc, sensor_attr->index, input_val);
+ break;
+-
++
+ default:
+ return -EINVAL;
+ break;
+@@ -537,15 +600,15 @@ ast_store_adc(struct device *dev, struct device_attribute *attr, const char *sys
+ return count;
+ }
+
+-/* attr ADC sysfs 0~max adc channel
++/* attr ADC sysfs 0~max adc channel
+ * 0 - show/store channel enable
+-* 1 - show value
++* 1 - show value
+ * 2 - show alarm get statuse
+ * 3 - show/store upper
+-* 4 - show/store lower
+-* 5 - show/store hystersis enable
+-* 6 - show/store hystersis upper
+-* 7 - show/store hystersis low
++* 4 - show/store lower
++* 5 - show/store hystersis enable
++* 6 - show/store hystersis upper
++* 7 - show/store hystersis low
+ * 8 - show value as 1000s, expected by lm-sensors
+ */
+
+@@ -624,18 +687,18 @@ static const struct attribute_group adc_attribute_groups[] = {
+ { .attrs = adc7_attributes },
+ { .attrs = adc8_attributes },
+ { .attrs = adc9_attributes },
+- { .attrs = adc10_attributes },
++ { .attrs = adc10_attributes },
+ { .attrs = adc11_attributes },
+ #if defined(CONFIG_ARCH_AST2400) || defined(CONFIG_ARCH_AST2500)
+ { .attrs = adc12_attributes },
+ { .attrs = adc13_attributes },
+ { .attrs = adc14_attributes },
+ { .attrs = adc15_attributes },
+-#endif
++#endif
+ };
+
+
+-static int
++static int
+ ast_adc_probe(struct platform_device *pdev)
+ {
+ struct resource *res;
+@@ -695,7 +758,7 @@ ast_adc_probe(struct platform_device *pdev)
+ }
+
+ ast_adc_ctrl_init();
+-
++
+ printk(KERN_INFO "ast_adc: driver successfully loaded.\n");
+
+ return 0;
+@@ -714,7 +777,7 @@ out:
+ return ret;
+ }
+
+-static int
++static int
+ ast_adc_remove(struct platform_device *pdev)
+ {
+ int i=0;
+@@ -739,14 +802,14 @@ ast_adc_remove(struct platform_device *pdev)
+ }
+
+ #ifdef CONFIG_PM
+-static int
++static int
+ ast_adc_suspend(struct platform_device *pdev, pm_message_t state)
+ {
+ printk("ast_adc_suspend : TODO \n");
+ return 0;
+ }
+
+-static int
++static int
+ ast_adc_resume(struct platform_device *pdev)
+ {
+ ast_adc_ctrl_init();
+@@ -769,13 +832,13 @@ static struct platform_driver ast_adc_driver = {
+ },
+ };
+
+-static int __init
++static int __init
+ ast_adc_init(void)
+ {
+ return platform_driver_register(&ast_adc_driver);
+ }
+
+-static void __exit
++static void __exit
+ ast_adc_exit(void)
+ {
+ platform_driver_unregister(&ast_adc_driver);
+diff --git a/drivers/i2c/busses/i2c-ast.c b/drivers/i2c/busses/i2c-ast.c
+index 7a083de..9bb3154 100644
+--- a/drivers/i2c/busses/i2c-ast.c
++++ b/drivers/i2c/busses/i2c-ast.c
+@@ -40,63 +40,68 @@
+ #include <plat/ast_i2c.h>
+ #endif
+
+-//AST2400 buffer mode issue , force I2C slave write use byte mode , read use buffer mode
++//AST2400 buffer mode issue , force I2C slave write use byte mode , read use buffer mode
+ /* Use platform_data instead of module parameters */
+ /* Fast Mode = 400 kHz, Standard = 100 kHz */
+ //static int clock = 100; /* Default: 100 kHz */
+
+
+ /***************************************************************************/
++
++#ifdef CONFIG_AST_I2C_SLAVE_RDWR
++#define I2C_S_BUF_SIZE 64
++#define I2C_S_RX_BUF_NUM 4
++#define BUFF_FULL 0xff00
++#define BUFF_ONGOING 1
++#endif
++
++#define AST_LOCKUP_DETECTED (0x1 << 15)
++
+ struct ast_i2c_dev {
+ struct ast_i2c_driver_data *ast_i2c_data;
+ struct device *dev;
+- void __iomem *reg_base; /* virtual */
+- int irq; //I2C IRQ number
+- u32 bus_id; //for i2c dev# IRQ number check
+- u32 state; //I2C xfer mode state matchine
++ void __iomem *reg_base; /* virtual */
++ int irq; //I2C IRQ number
++ u32 bus_id; //for i2c dev# IRQ number check
++ u32 state; //I2C xfer mode state matchine
+ struct i2c_adapter adap;
+- struct buf_page *req_page;
++ struct buf_page *req_page;
+ //dma or buff mode needed
+ unsigned char *dma_buf;
+ dma_addr_t dma_addr;
+-
+-//master
++
++//master
+ int xfer_last; //cur xfer is last msgs for stop msgs
+ struct i2c_msg *master_msgs; //cur xfer msgs
+- int master_xfer_len; //cur xfer len
++ int master_xfer_len; //cur xfer len
+ int master_xfer_cnt; //total xfer count
+ u32 master_xfer_mode; //cur xfer mode ... 0 : no_op , master: 1 byte , 2 : buffer , 3: dma , slave : xxxx
+ struct completion cmd_complete;
+ int cmd_err;
+ u8 blk_r_flag; //for smbus block read
+- void (*do_master_xfer)(struct ast_i2c_dev *i2c_dev);
+-//Slave structure
++ void (*do_master_xfer)(struct ast_i2c_dev *i2c_dev);
++ spinlock_t master_lock;
++//Slave structure
+ u8 slave_operation;
+ u8 slave_event;
+ struct i2c_msg *slave_msgs; //cur slave xfer msgs
+- int slave_xfer_len;
+- int slave_xfer_cnt;
+- u32 slave_xfer_mode; //cur xfer mode ... 0 : no_op , master: 1 byte , 2 : buffer , 3: dma , slave : xxxx
++ int slave_xfer_len;
++ int slave_xfer_cnt;
++ u32 slave_xfer_mode; //cur xfer mode ... 0 : no_op , master: 1 byte , 2 : buffer , 3: dma , slave : xxxx
+ void (*do_slave_xfer)(struct ast_i2c_dev *i2c_dev);
+-};
+-
+ #ifdef CONFIG_AST_I2C_SLAVE_RDWR
+-#define I2C_S_BUF_SIZE 64
+-#define I2C_S_RX_BUF_NUM 4
+-#define BUFF_FULL 0xff00
+-#define BUFF_ONGOING 1
+-
+-struct i2c_msg slave_rx_msg[I2C_S_RX_BUF_NUM + 1];
+-struct i2c_msg slave_tx_msg;
+-static spinlock_t slave_rx_lock = SPIN_LOCK_UNLOCKED;
++ struct i2c_msg slave_rx_msg[I2C_S_RX_BUF_NUM + 1];
++ struct i2c_msg slave_tx_msg;
++ spinlock_t slave_rx_lock;
+ #endif
++};
++
+
+-static spinlock_t g_master_lock = SPIN_LOCK_UNLOCKED;
+
+ static inline void
+ ast_i2c_write(struct ast_i2c_dev *i2c_dev, u32 val, u32 reg)
+ {
+-// dev_dbg(i2c_dev->dev, "ast_i2c_write : val: %x , reg : %x \n",val,reg);
++// dev_dbg(i2c_dev->dev, "ast_i2c_write : val: %x , reg : %x \n",val,reg);
+ writel(val, i2c_dev->reg_base+ reg);
+ }
+
+@@ -107,7 +112,7 @@ ast_i2c_read(struct ast_i2c_dev *i2c_dev, u32 reg)
+ u32 val = readl(i2c_dev->reg_base + reg);
+ printk("R : reg %x , val: %x \n",reg, val);
+ return val;
+-#else
++#else
+ return readl(i2c_dev->reg_base + reg);
+ #endif
+ }
+@@ -152,7 +157,7 @@ static void ast_slave_issue_alert(struct ast_i2c_dev *i2c_dev, u8 enable)
+ static void ast_slave_mode_enable(struct ast_i2c_dev *i2c_dev, struct i2c_msg *msgs)
+ {
+ if(msgs->buf[0] == 1) {
+- ast_i2c_write(i2c_dev, msgs->addr, I2C_DEV_ADDR_REG);
++ ast_i2c_write(i2c_dev, msgs->addr, I2C_DEV_ADDR_REG);
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_FUN_CTRL_REG) | AST_I2CD_SLAVE_EN, I2C_FUN_CTRL_REG);
+ } else
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_FUN_CTRL_REG) & ~AST_I2CD_SLAVE_EN, I2C_FUN_CTRL_REG);
+@@ -162,12 +167,14 @@ static void ast_slave_mode_enable(struct ast_i2c_dev *i2c_dev, struct i2c_msg *m
+
+ static void ast_i2c_dev_init(struct ast_i2c_dev *i2c_dev)
+ {
+- //I2CG Reset
++ //I2CG Reset
+ ast_i2c_write(i2c_dev, 0, I2C_FUN_CTRL_REG);
+
+-#ifdef CONFIG_AST_I2C_SLAVE_EEPROM
++#ifdef CONFIG_AST_I2C_SLAVE_EEPROM
+ i2c_dev->ast_i2c_data->slave_init(&(i2c_dev->slave_msgs));
+ ast_slave_mode_enable(i2c_dev, i2c_dev->slave_msgs);
++#else
++ i2c_dev->slave_msgs = i2c_dev->slave_rx_msg;
+ #endif
+
+ //Enable Master Mode
+@@ -177,20 +184,20 @@ static void ast_i2c_dev_init(struct ast_i2c_dev *i2c_dev)
+ /* Set AC Timing */
+ #if defined(CONFIG_ARCH_AST2400)
+ if(i2c_dev->ast_i2c_data->bus_clk/1000 > 400) {
+- printk("high speed mode enable clk [%dkhz]\n",i2c_dev->ast_i2c_data->bus_clk/1000);
++ printk("high speed mode enable clk [%dkhz]\n",i2c_dev->ast_i2c_data->bus_clk/1000);
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev, I2C_FUN_CTRL_REG) |
+ AST_I2CD_M_HIGH_SPEED_EN |
+ AST_I2CD_M_SDA_DRIVE_1T_EN |
+- AST_I2CD_SDA_DRIVE_1T_EN
++ AST_I2CD_SDA_DRIVE_1T_EN
+ , I2C_FUN_CTRL_REG);
+-
++
+ /* Set AC Timing */
+ ast_i2c_write(i2c_dev, 0x3, I2C_AC_TIMING_REG2);
+- ast_i2c_write(i2c_dev, select_i2c_clock(i2c_dev), I2C_AC_TIMING_REG1);
++ ast_i2c_write(i2c_dev, select_i2c_clock(i2c_dev), I2C_AC_TIMING_REG1);
+ }else {
+- /* target apeed is xxKhz*/
++ /* target apeed is xxKhz*/
+ ast_i2c_write(i2c_dev, select_i2c_clock(i2c_dev), I2C_AC_TIMING_REG1);
+- ast_i2c_write(i2c_dev, AST_NO_TIMEOUT_CTRL, I2C_AC_TIMING_REG2);
++ ast_i2c_write(i2c_dev, AST_NO_TIMEOUT_CTRL, I2C_AC_TIMING_REG2);
+ }
+ #else
+ /* target apeed is xxKhz*/
+@@ -206,12 +213,12 @@ static void ast_i2c_dev_init(struct ast_i2c_dev *i2c_dev)
+
+ //TODO
+ // ast_i2c_write(i2c_dev, 0xAF, I2C_INTR_CTRL_REG);
+- //Enable Interrupt, STOP Interrupt has bug in AST2000
+-
++ //Enable Interrupt, STOP Interrupt has bug in AST2000
++
+ /* Set interrupt generation of I2C controller */
+ ast_i2c_write(i2c_dev,
+- AST_I2CD_SDA_DL_TO_INTR_EN |
+- AST_I2CD_BUS_RECOVER_INTR_EN |
++ AST_I2CD_SDA_DL_TO_INTR_EN |
++ AST_I2CD_BUS_RECOVER_INTR_EN |
+ AST_I2CD_SMBUS_ALT_INTR_EN |
+ // AST_I2CD_SLAVE_MATCH_INTR_EN |
+ AST_I2CD_SCL_TO_INTR_EN |
+@@ -230,16 +237,16 @@ static void ast_i2c_dev_init(struct ast_i2c_dev *i2c_dev)
+ static void ast_i2c_slave_buff_init(struct ast_i2c_dev *i2c_dev)
+ {
+ int i;
+- //Tx buf 1
+- slave_tx_msg.len = I2C_S_BUF_SIZE;
+- slave_tx_msg.buf = kzalloc(I2C_S_BUF_SIZE, GFP_KERNEL);
++ //Tx buf 1
++ i2c_dev->slave_tx_msg.len = I2C_S_BUF_SIZE;
++ i2c_dev->slave_tx_msg.buf = kzalloc(I2C_S_BUF_SIZE, GFP_KERNEL);
+ //Rx buf 4
+ for(i=0; i<I2C_S_RX_BUF_NUM+1; i++) {
+- slave_rx_msg[i].addr = ~BUFF_ONGOING;
+- slave_rx_msg[i].flags = 0; //mean empty buffer
+- slave_rx_msg[i].len = I2C_S_BUF_SIZE;
+- slave_rx_msg[i].buf = kzalloc(I2C_S_BUF_SIZE, GFP_KERNEL);
+- }
++ i2c_dev->slave_rx_msg[i].addr = ~BUFF_ONGOING;
++ i2c_dev->slave_rx_msg[i].flags = 0; //mean empty buffer
++ i2c_dev->slave_rx_msg[i].len = I2C_S_BUF_SIZE;
++ i2c_dev->slave_rx_msg[i].buf = kzalloc(I2C_S_BUF_SIZE, GFP_KERNEL);
++ }
+ }
+
+ static void ast_i2c_slave_rdwr_xfer(struct ast_i2c_dev *i2c_dev)
+@@ -247,13 +254,13 @@ static void ast_i2c_slave_rdwr_xfer(struct ast_i2c_dev *i2c_dev)
+ int i;
+ unsigned long flags;
+
+- spin_lock_irqsave(&slave_rx_lock, flags);
+-
++ spin_lock_irqsave(&i2c_dev->slave_rx_lock, flags);
++
+ switch(i2c_dev->slave_event) {
+ case I2C_SLAVE_EVENT_START_WRITE:
+ for(i=0; i<I2C_S_RX_BUF_NUM; i++) {
+- if((slave_rx_msg[i].flags == 0) && (slave_rx_msg[i].addr != BUFF_ONGOING)) {
+- slave_rx_msg[i].addr = BUFF_ONGOING;
++ if((i2c_dev->slave_rx_msg[i].flags == 0) && (i2c_dev->slave_rx_msg[i].addr != BUFF_ONGOING)) {
++ i2c_dev->slave_rx_msg[i].addr = BUFF_ONGOING;
+ break;
+ }
+ }
+@@ -261,40 +268,40 @@ static void ast_i2c_slave_rdwr_xfer(struct ast_i2c_dev *i2c_dev)
+ printk("RX buffer full ........use tmp msgs buff \n");
+ //TODO...
+ }
+- printk("I2C_SLAVE_EVENT_START_WRITE ... %d \n", i);
++ //printk("I2C_SLAVE_EVENT_START_WRITE ... %d \n", i);
+
+- i2c_dev->slave_msgs = &slave_rx_msg[i];
++ i2c_dev->slave_msgs = &i2c_dev->slave_rx_msg[i];
+ break;
+ case I2C_SLAVE_EVENT_START_READ:
+- printk("I2C_SLAVE_EVENT_START_READ ERROR .. not imple \n");
+- i2c_dev->slave_msgs = &slave_tx_msg;
++ //printk("I2C_SLAVE_EVENT_START_READ ERROR .. not imple \n");
++ i2c_dev->slave_msgs = &i2c_dev->slave_tx_msg;
+ break;
+ case I2C_SLAVE_EVENT_WRITE:
+- printk("I2C_SLAVE_EVENT_WRITE next write ERROR ...\n");
+- i2c_dev->slave_msgs = &slave_tx_msg;
++ //printk("I2C_SLAVE_EVENT_WRITE next write ERROR ...\n");
++ i2c_dev->slave_msgs = &i2c_dev->slave_tx_msg;
+ break;
+ case I2C_SLAVE_EVENT_READ:
+- printk("I2C_SLAVE_EVENT_READ ERROR ... \n");
+- i2c_dev->slave_msgs = &slave_tx_msg;
++ printk("I2C_SLAVE_EVENT_READ ERROR ... \n");
++ i2c_dev->slave_msgs = &i2c_dev->slave_tx_msg;
+ break;
+ case I2C_SLAVE_EVENT_NACK:
+- printk("I2C_SLAVE_EVENT_NACK ERROR ... \n");
+- i2c_dev->slave_msgs = &slave_tx_msg;
++ //printk("I2C_SLAVE_EVENT_NACK ERROR ... \n");
++ i2c_dev->slave_msgs = &i2c_dev->slave_tx_msg;
+ break;
+ case I2C_SLAVE_EVENT_STOP:
+- printk("I2C_SLAVE_EVENT_STOP \n");
++ //printk("I2C_SLAVE_EVENT_STOP \n");
+ for(i=0; i<I2C_S_RX_BUF_NUM; i++) {
+- if(slave_rx_msg[i].addr == BUFF_ONGOING) {
+- slave_rx_msg[i].flags = BUFF_FULL;
+- slave_rx_msg[i].addr = 0;
++ if(i2c_dev->slave_rx_msg[i].addr == BUFF_ONGOING) {
++ i2c_dev->slave_rx_msg[i].flags = BUFF_FULL;
++ i2c_dev->slave_rx_msg[i].addr = 0;
+ break;
+ }
+ }
+-
+- i2c_dev->slave_msgs = &slave_tx_msg;
++
++ i2c_dev->slave_msgs = &i2c_dev->slave_tx_msg;
+ break;
+ }
+- spin_unlock_irqrestore(&slave_rx_lock, flags);
++ spin_unlock_irqrestore(&i2c_dev->slave_rx_lock, flags);
+
+ }
+
+@@ -308,29 +315,29 @@ static int ast_i2c_slave_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs)
+ case 0:
+ // printk("slave read \n");
+ //cur_msg = get_free_msg;
+- spin_lock_irqsave(&slave_rx_lock, flags);
++ spin_lock_irqsave(&i2c_dev->slave_rx_lock, flags);
+
+ for(i=0; i<I2C_S_RX_BUF_NUM; i++) {
+- if((slave_rx_msg[i].addr == 0) && (slave_rx_msg[i].flags == BUFF_FULL)) {
+- memcpy(msgs->buf, slave_rx_msg[i].buf, slave_rx_msg[i].len);
+- msgs->len = slave_rx_msg[i].len;
+- slave_rx_msg[i].flags = 0;
+- slave_rx_msg[i].len = 0;
++ if((i2c_dev->slave_rx_msg[i].addr == 0) && (i2c_dev->slave_rx_msg[i].flags == BUFF_FULL)) {
++ memcpy(msgs->buf, i2c_dev->slave_rx_msg[i].buf, i2c_dev->slave_rx_msg[i].len);
++ msgs->len = i2c_dev->slave_rx_msg[i].len;
++ i2c_dev->slave_rx_msg[i].flags = 0;
++ i2c_dev->slave_rx_msg[i].len = 0;
+ break;
+ }
+ }
+- spin_unlock_irqrestore(&slave_rx_lock, flags);
+-
++ spin_unlock_irqrestore(&i2c_dev->slave_rx_lock, flags);
++
+ if(i == I2C_S_RX_BUF_NUM) {
+- printk("No buffer ........ \n");
++ //printk("No buffer ........ \n");
+ msgs->len = 0;
+ ret = -1;
+ }
+ break;
+ case I2C_M_RD: //slave write
+ // printk("slave write \n");
+- memcpy(msgs->buf, slave_tx_msg.buf, I2C_S_BUF_SIZE);
+- break;
++ memcpy(msgs->buf, i2c_dev->slave_tx_msg.buf, I2C_S_BUF_SIZE);
++ break;
+ case I2C_S_EN:
+ if((msgs->addr < 0x1) || (msgs->addr > 0xff)) {
+ ret = -1;
+@@ -352,7 +359,7 @@ static int ast_i2c_slave_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs)
+ default:
+ printk("slave xfer error \n");
+ break;
+-
++
+ }
+ return ret;
+ }
+@@ -360,16 +367,16 @@ static int ast_i2c_slave_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs)
+
+ #endif
+
+-static u8
++static u8
+ ast_i2c_bus_error_recover(struct ast_i2c_dev *i2c_dev)
+ {
+ u32 sts;
+- int r;
++ int r;
+ u32 i = 0;
+-
++
+ //Check 0x14's SDA and SCL status
+ sts = ast_i2c_read(i2c_dev,I2C_CMD_REG);
+-
++
+ if ((sts & AST_I2CD_SDA_LINE_STS) && (sts & AST_I2CD_SCL_LINE_STS)) {
+ //Means bus is idle.
+ dev_dbg(i2c_dev->dev, "I2C bus (%d) is idle. I2C slave doesn't exist?!\n", i2c_dev->bus_id);
+@@ -377,11 +384,11 @@ ast_i2c_bus_error_recover(struct ast_i2c_dev *i2c_dev)
+ }
+
+ dev_dbg(i2c_dev->dev, "ERROR!! I2C(%d) bus hanged, try to recovery it!\n", i2c_dev->bus_id);
+-
+-
++
++
+ if ((sts & AST_I2CD_SDA_LINE_STS) && !(sts & AST_I2CD_SCL_LINE_STS)) {
+ //if SDA == 1 and SCL == 0, it means the master is locking the bus.
+- //Send a stop command to unlock the bus.
++ //Send a stop command to unlock the bus.
+ dev_dbg(i2c_dev->dev, "I2C's master is locking the bus, try to stop it.\n");
+ //
+ init_completion(&i2c_dev->cmd_complete);
+@@ -397,12 +404,12 @@ ast_i2c_bus_error_recover(struct ast_i2c_dev *i2c_dev)
+ dev_dbg(i2c_dev->dev, "recovery error \n");
+ return -1;
+ }
+-
++
+ if (r == 0) {
+ dev_dbg(i2c_dev->dev, "recovery timed out\n");
+ return -1;
+ } else {
+- dev_dbg(i2c_dev->dev, "Recovery successfully\n");
++ dev_dbg(i2c_dev->dev, "Recovery successfully\n");
+ return 0;
+ }
+
+@@ -415,11 +422,11 @@ ast_i2c_bus_error_recover(struct ast_i2c_dev *i2c_dev)
+ for (i = 0; i < 10; i++) {
+ ast_i2c_dev_init(i2c_dev);
+ //Do the recovery command BIT11
+- init_completion(&i2c_dev->cmd_complete);
++ init_completion(&i2c_dev->cmd_complete);
+ ast_i2c_write(i2c_dev, AST_I2CD_BUS_RECOVER_CMD_EN, I2C_CMD_REG);
+-
++
+ r = wait_for_completion_interruptible_timeout(&i2c_dev->cmd_complete,
+- i2c_dev->adap.timeout*HZ);
++ i2c_dev->adap.timeout*HZ);
+ if (i2c_dev->cmd_err != 0 &&
+ i2c_dev->cmd_err != AST_I2CD_INTR_STS_NORMAL_STOP) {
+ dev_dbg(i2c_dev->dev, "ERROR!! Failed to do recovery command(0x%08x)\n", i2c_dev->cmd_err);
+@@ -438,31 +445,56 @@ ast_i2c_bus_error_recover(struct ast_i2c_dev *i2c_dev)
+ dev_dbg(i2c_dev->dev, "Don't know how to handle this case?!\n");
+ return -1;
+ }
+- dev_dbg(i2c_dev->dev, "Recovery successfully\n");
++ dev_dbg(i2c_dev->dev, "Recovery successfully\n");
+ return 0;
+ }
+
+-static void ast_master_alert_recv(struct ast_i2c_dev *i2c_dev)
++static void ast_master_alert_recv(struct ast_i2c_dev *i2c_dev)
+ {
+ printk("ast_master_alert_recv bus id %d, Disable Alt, Please Imple \n",i2c_dev->bus_id);
+ }
+
+ static int ast_i2c_wait_bus_not_busy(struct ast_i2c_dev *i2c_dev)
+ {
+- int timeout = 32; //TODO number
++ int timeout = 10; //TODO number
++ volatile u8 mode = 0;
+ // printk("ast_i2c_wait_bus_not_busy \n");
++
++ // Wait for slave transfer to finish
++ mode = i2c_dev->slave_operation;
++ while (mode == 1) {
++ if (timeout <= 0) {
++ break;
++ }
++ mode = i2c_dev->slave_operation;
++ timeout--;
++ msleep(1);
++ }
++
++ if (timeout <= 0) {
++ return -EAGAIN;
++ }
++
++ // Wait for Bus to go IDLE
++ timeout = 10;
+ while (ast_i2c_read(i2c_dev,I2C_CMD_REG) & AST_I2CD_BUS_BUSY_STS) {
+- ast_i2c_bus_error_recover(i2c_dev);
+- if(timeout<=0)
++ if(timeout<=0) {
+ break;
++ }
++
+ timeout--;
+- msleep(2);
++ msleep(1);
+ }
+
+- return timeout <= 0 ? EAGAIN : 0;
++ if (timeout <=0) {
++ ast_i2c_bus_error_recover(i2c_dev);
++ return 0;
++ }
++
++ return 0;
+ }
+
+-static void ast_i2c_do_dma_xfer(struct ast_i2c_dev *i2c_dev)
++static void ast_i2c_do_dma_xfer(struct ast_i2c_dev *i2c_dev)
+ {
+ u32 cmd = 0;
+ int i;
+@@ -470,49 +502,49 @@ static void ast_i2c_do_dma_xfer(struct ast_i2c_dev *i2c_dev)
+ i2c_dev->master_xfer_mode = DMA_XFER;
+ i2c_dev->slave_xfer_mode = DMA_XFER;
+
+- if(i2c_dev->slave_operation == 1) {
++ if(i2c_dev->slave_operation == 1) {
+ if(i2c_dev->slave_msgs->flags & I2C_M_RD) {
+ //DMA tx mode
+ if(i2c_dev->slave_msgs->len > AST_I2C_DMA_SIZE)
+ i2c_dev->slave_xfer_len = AST_I2C_DMA_SIZE;
+- else
++ else
+ i2c_dev->slave_xfer_len = i2c_dev->slave_msgs->len;
+-
++
+ dev_dbg(i2c_dev->dev, "(<--) slave tx DMA \n");
+ for(i=0; i<i2c_dev->slave_xfer_len; i++)
+ i2c_dev->dma_buf[i] = i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt + i];
+-
++
+ ast_i2c_write(i2c_dev, i2c_dev->dma_addr, I2C_DMA_BASE_REG);
+ ast_i2c_write(i2c_dev, (i2c_dev->slave_xfer_len-1), I2C_DMA_LEN_REG);
+- ast_i2c_write(i2c_dev, AST_I2CD_TX_DMA_ENABLE | AST_I2CD_S_TX_CMD,I2C_CMD_REG);
++ ast_i2c_write(i2c_dev, AST_I2CD_TX_DMA_ENABLE | AST_I2CD_S_TX_CMD,I2C_CMD_REG);
+ } else {
+ //DMA prepare rx
+ dev_dbg(i2c_dev->dev, "(-->) slave rx DMA \n");
+ ast_i2c_write(i2c_dev, i2c_dev->dma_addr, I2C_DMA_BASE_REG);
+ ast_i2c_write(i2c_dev, (AST_I2C_DMA_SIZE-1), I2C_DMA_LEN_REG);
+- ast_i2c_write(i2c_dev, AST_I2CD_RX_DMA_ENABLE, I2C_CMD_REG);
++ ast_i2c_write(i2c_dev, AST_I2CD_RX_DMA_ENABLE, I2C_CMD_REG);
+ }
+ } else {
+ dev_dbg(i2c_dev->dev,"M cnt %d, xf len %d \n",i2c_dev->master_xfer_cnt, i2c_dev->master_msgs->len);
+ if(i2c_dev->master_xfer_cnt == -1) {
+- //send start
++ //send start
+ dev_dbg(i2c_dev->dev, " %sing %d byte%s %s 0x%02x\n",
+ i2c_dev->master_msgs->flags & I2C_M_RD ? "read" : "write",
+ i2c_dev->master_msgs->len, i2c_dev->master_msgs->len > 1 ? "s" : "",
+ i2c_dev->master_msgs->flags & I2C_M_RD ? "from" : "to", i2c_dev->master_msgs->addr);
+
+ if(i2c_dev->master_msgs->flags & I2C_M_RD) {
+- //workaround .. HW can;t send start read addr with buff mode
++ //workaround .. HW can;t send start read addr with buff mode
+ cmd = AST_I2CD_M_START_CMD | AST_I2CD_M_TX_CMD;
+ ast_i2c_write(i2c_dev, (i2c_dev->master_msgs->addr <<1) |0x1, I2C_BYTE_BUF_REG);
+
+ // tx_buf[0] = (i2c_dev->master_msgs->addr <<1); //+1
+ i2c_dev->master_xfer_len = 1;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+ } else {
+ //tx
+- cmd = AST_I2CD_M_START_CMD | AST_I2CD_M_TX_CMD | AST_I2CD_TX_DMA_ENABLE;
++ cmd = AST_I2CD_M_START_CMD | AST_I2CD_M_TX_CMD | AST_I2CD_TX_DMA_ENABLE;
+
+ i2c_dev->dma_buf[0] = (i2c_dev->master_msgs->addr <<1); //+1
+ //next data write
+@@ -520,44 +552,44 @@ static void ast_i2c_do_dma_xfer(struct ast_i2c_dev *i2c_dev)
+ i2c_dev->master_xfer_len = AST_I2C_DMA_SIZE;
+ else
+ i2c_dev->master_xfer_len = i2c_dev->master_msgs->len + 1;
+-
++
+ for(i = 1; i < i2c_dev->master_xfer_len; i++)
+ i2c_dev->dma_buf[i] = i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt+i];
+-
++
+ if (i2c_dev->xfer_last == 1) {
+ dev_dbg(i2c_dev->dev, "last stop \n");
+ cmd |= AST_I2CD_M_STOP_CMD;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
+- ~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+-
++ ~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++
+ } else {
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+ }
+ ast_i2c_write(i2c_dev, i2c_dev->dma_addr, I2C_DMA_BASE_REG);
+ ast_i2c_write(i2c_dev, (i2c_dev->master_xfer_len-1), I2C_DMA_LEN_REG);
+-
++
+ }
+- ast_i2c_write(i2c_dev, cmd, I2C_CMD_REG);
++ ast_i2c_write(i2c_dev, cmd, I2C_CMD_REG);
+ dev_dbg(i2c_dev->dev, "txfer size %d , cmd = %x \n",i2c_dev->master_xfer_len, cmd);
+
+ } else if (i2c_dev->master_xfer_cnt < i2c_dev->master_msgs->len){
+- //Next send
++ //Next send
+ if(i2c_dev->master_msgs->flags & I2C_M_RD) {
+ //Rx data
+ cmd = AST_I2CD_M_RX_CMD | AST_I2CD_RX_DMA_ENABLE;
+-
++
+ if((i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt) > AST_I2C_DMA_SIZE) {
+ i2c_dev->master_xfer_len = AST_I2C_DMA_SIZE;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+ AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+-
++
+ } else {
+ i2c_dev->master_xfer_len = i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt;
+ if((i2c_dev->master_msgs->flags & I2C_M_RECV_LEN) && (i2c_dev->blk_r_flag == 0)) {
+ dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN \n");
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
++ AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+ } else {
+ #ifdef CONFIG_AST1010
+ //Workaround for ast1010 can't send NACK
+@@ -568,7 +600,7 @@ static void ast_i2c_do_dma_xfer(struct ast_i2c_dev *i2c_dev)
+ i2c_dev->master_xfer_mode = BYTE_XFER;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
+ ~AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+-
++
+ } else if (i2c_dev->master_xfer_len > 1) {
+ i2c_dev->master_xfer_len -=1;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+@@ -578,8 +610,8 @@ static void ast_i2c_do_dma_xfer(struct ast_i2c_dev *i2c_dev)
+ }
+ #else
+ if(i2c_dev->xfer_last == 1) {
+- dev_dbg(i2c_dev->dev, "last stop \n");
+- cmd |= AST_I2CD_M_STOP_CMD;
++ dev_dbg(i2c_dev->dev, "last stop \n");
++ cmd |= AST_I2CD_M_STOP_CMD;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
+ ~AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+ } else {
+@@ -588,9 +620,9 @@ static void ast_i2c_do_dma_xfer(struct ast_i2c_dev *i2c_dev)
+ }
+ //TODO check....
+ cmd |= AST_I2CD_M_S_RX_CMD_LAST;
+-#endif
++#endif
+ }
+-
++
+ }
+ ast_i2c_write(i2c_dev, i2c_dev->dma_addr, I2C_DMA_BASE_REG);
+ ast_i2c_write(i2c_dev, i2c_dev->master_xfer_len-1, I2C_DMA_LEN_REG);
+@@ -603,23 +635,23 @@ static void ast_i2c_do_dma_xfer(struct ast_i2c_dev *i2c_dev)
+ if((i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt) > AST_I2C_DMA_SIZE) {
+ i2c_dev->master_xfer_len = AST_I2C_DMA_SIZE;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+-
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++
+ } else {
+ i2c_dev->master_xfer_len = i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt;
+ if(i2c_dev->xfer_last == 1) {
+ dev_dbg(i2c_dev->dev, "last stop \n");
+ cmd |= AST_I2CD_M_STOP_CMD;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
+- ~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+-
++ ~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++
+ } else {
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+ }
+ }
+
+- for(i = 0; i < i2c_dev->master_xfer_len; i++)
++ for(i = 0; i < i2c_dev->master_xfer_len; i++)
+ i2c_dev->dma_buf[i] = i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt + i];
+
+ ast_i2c_write(i2c_dev, i2c_dev->dma_addr, I2C_DMA_BASE_REG);
+@@ -627,33 +659,33 @@ static void ast_i2c_do_dma_xfer(struct ast_i2c_dev *i2c_dev)
+ ast_i2c_write(i2c_dev, cmd , I2C_CMD_REG);
+ dev_dbg(i2c_dev->dev, "txfer size %d , cmd = %x \n",i2c_dev->master_xfer_len, cmd);
+
+- }
++ }
+ }else {
+- //should send next msg
++ //should send next msg
+ if(i2c_dev->master_xfer_cnt != i2c_dev->master_msgs->len)
+ printk("complete rx ... bus=%d addr=0x%x (%d vs. %d) ERROR\n",
+ i2c_dev->bus_id, i2c_dev->master_msgs->addr,
+ i2c_dev->master_xfer_cnt, i2c_dev->master_msgs->len);
+-
++
+ dev_dbg(i2c_dev->dev, "ast_i2c_do_byte_xfer complete \n");
+ i2c_dev->cmd_err = 0;
+- complete(&i2c_dev->cmd_complete);
++ complete(&i2c_dev->cmd_complete);
+ }
+-
++
+ }
+
+-
++
+ }
+
+-static void ast_i2c_do_pool_xfer(struct ast_i2c_dev *i2c_dev)
++static void ast_i2c_do_pool_xfer(struct ast_i2c_dev *i2c_dev)
+ {
+ u32 cmd = 0;
+ int i;
+ u32 *tx_buf;
+
+ i2c_dev->master_xfer_mode = BUFF_XFER;
+- i2c_dev->slave_xfer_mode = BUFF_XFER;
+-
++ i2c_dev->slave_xfer_mode = BUFF_XFER;
++
+ #if defined(CONFIG_ARCH_AST2400)
+ ast_i2c_write(i2c_dev,
+ (ast_i2c_read(i2c_dev, I2C_FUN_CTRL_REG) &
+@@ -665,15 +697,15 @@ static void ast_i2c_do_pool_xfer(struct ast_i2c_dev *i2c_dev)
+ tx_buf = (u32 *) i2c_dev->req_page->page_addr;
+
+
+- if(i2c_dev->slave_operation == 1) {
++ if(i2c_dev->slave_operation == 1) {
+ if(i2c_dev->slave_msgs->flags & I2C_M_RD) {
+ dev_dbg(i2c_dev->dev, "(<--) slave tx buf \n");
+-
++
+ if(i2c_dev->slave_msgs->len > i2c_dev->req_page->page_size)
+ i2c_dev->slave_xfer_len = i2c_dev->req_page->page_size;
+ else
+ i2c_dev->slave_xfer_len = i2c_dev->slave_msgs->len;
+-
++
+ for(i = 0; i< i2c_dev->slave_xfer_len; i++) {
+ if(i%4 == 0)
+ tx_buf[i/4] = 0;
+@@ -681,80 +713,80 @@ static void ast_i2c_do_pool_xfer(struct ast_i2c_dev *i2c_dev)
+ dev_dbg(i2c_dev->dev, "[%x] ",tx_buf[i/4]);
+ }
+ dev_dbg(i2c_dev->dev, "\n");
+-
+- ast_i2c_write(i2c_dev, AST_I2CD_TX_DATA_BUF_END_SET((i2c_dev->slave_xfer_len-1)) |
+- AST_I2CD_BUF_BASE_ADDR_SET((i2c_dev->req_page->page_addr_point)),
++
++ ast_i2c_write(i2c_dev, AST_I2CD_TX_DATA_BUF_END_SET((i2c_dev->slave_xfer_len-1)) |
++ AST_I2CD_BUF_BASE_ADDR_SET((i2c_dev->req_page->page_addr_point)),
+ I2C_BUF_CTRL_REG);
+-
++
+ ast_i2c_write(i2c_dev, AST_I2CD_TX_BUFF_ENABLE | AST_I2CD_S_TX_CMD, I2C_CMD_REG);
+ } else {
+ //prepare for new rx
+ dev_dbg(i2c_dev->dev, "(-->) slave prepare rx buf \n");
+- ast_i2c_write(i2c_dev,
++ ast_i2c_write(i2c_dev,
+ AST_I2CD_RX_BUF_END_ADDR_SET((i2c_dev->req_page->page_size-1)) |
+ AST_I2CD_BUF_BASE_ADDR_SET((i2c_dev->req_page->page_addr_point)),
+ I2C_BUF_CTRL_REG);
+
+- ast_i2c_write(i2c_dev, AST_I2CD_RX_BUFF_ENABLE, I2C_CMD_REG);
+-
++ ast_i2c_write(i2c_dev, AST_I2CD_RX_BUFF_ENABLE, I2C_CMD_REG);
++
+ }
+ } else {
+ dev_dbg(i2c_dev->dev,"M cnt %d, xf len %d \n",i2c_dev->master_xfer_cnt, i2c_dev->master_msgs->len);
+ if(i2c_dev->master_xfer_cnt == -1) {
+- //send start
++ //send start
+ dev_dbg(i2c_dev->dev, " %sing %d byte%s %s 0x%02x\n",
+ i2c_dev->master_msgs->flags & I2C_M_RD ? "read" : "write",
+ i2c_dev->master_msgs->len, i2c_dev->master_msgs->len > 1 ? "s" : "",
+ i2c_dev->master_msgs->flags & I2C_M_RD ? "from" : "to", i2c_dev->master_msgs->addr);
+
+ if(i2c_dev->master_msgs->flags & I2C_M_RD) {
+-//workaround .. HW can;t send start read addr with buff mode
++//workaround .. HW can;t send start read addr with buff mode
+ cmd = AST_I2CD_M_START_CMD | AST_I2CD_M_TX_CMD;
+ ast_i2c_write(i2c_dev, (i2c_dev->master_msgs->addr <<1) |0x1, I2C_BYTE_BUF_REG);
+
+ // tx_buf[0] = (i2c_dev->master_msgs->addr <<1); //+1
+ i2c_dev->master_xfer_len = 1;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+ } else {
+- cmd = AST_I2CD_M_START_CMD | AST_I2CD_M_TX_CMD | AST_I2CD_TX_BUFF_ENABLE;
++ cmd = AST_I2CD_M_START_CMD | AST_I2CD_M_TX_CMD | AST_I2CD_TX_BUFF_ENABLE;
+ tx_buf[0] = (i2c_dev->master_msgs->addr <<1); //+1
+ //next data write
+ if((i2c_dev->master_msgs->len + 1) > i2c_dev->req_page->page_size)
+ i2c_dev->master_xfer_len = i2c_dev->req_page->page_size;
+ else
+ i2c_dev->master_xfer_len = i2c_dev->master_msgs->len + 1;
+-
++
+ for(i = 1; i < i2c_dev->master_xfer_len; i++) {
+ if(i%4 == 0)
+ tx_buf[i/4] = 0;
+ tx_buf[i/4] |= (i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt + i] << ((i%4)*8)) ;
+ }
+-
++
+ if (i2c_dev->xfer_last == 1) {
+ dev_dbg(i2c_dev->dev, "last stop \n");
+ cmd |= AST_I2CD_M_STOP_CMD;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
+- ~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+-
++ ~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++
+ } else {
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+ }
+- ast_i2c_write(i2c_dev,
++ ast_i2c_write(i2c_dev,
+ AST_I2CD_TX_DATA_BUF_END_SET((i2c_dev->master_xfer_len - 1)) |
+ AST_I2CD_BUF_BASE_ADDR_SET(i2c_dev->req_page->page_addr_point),
+ I2C_BUF_CTRL_REG);
+ }
+- ast_i2c_write(i2c_dev, cmd, I2C_CMD_REG);
++ ast_i2c_write(i2c_dev, cmd, I2C_CMD_REG);
+ dev_dbg(i2c_dev->dev, "txfer size %d , cmd = %x \n",i2c_dev->master_xfer_len, cmd);
+
+ } else if (i2c_dev->master_xfer_cnt < i2c_dev->master_msgs->len){
+- //Next send
++ //Next send
+ if(i2c_dev->master_msgs->flags & I2C_M_RD) {
+ //Rx data
+ cmd = AST_I2CD_M_RX_CMD | AST_I2CD_RX_BUFF_ENABLE;
+-
++
+ if((i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt) > i2c_dev->req_page->page_size) {
+ i2c_dev->master_xfer_len = i2c_dev->req_page->page_size;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+@@ -764,11 +796,11 @@ static void ast_i2c_do_pool_xfer(struct ast_i2c_dev *i2c_dev)
+ if((i2c_dev->master_msgs->flags & I2C_M_RECV_LEN) && (i2c_dev->blk_r_flag == 0)) {
+ dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN \n");
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
++ AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+ } else {
+ if(i2c_dev->xfer_last == 1) {
+- dev_dbg(i2c_dev->dev, "last stop \n");
+- cmd |= AST_I2CD_M_STOP_CMD;
++ dev_dbg(i2c_dev->dev, "last stop \n");
++ cmd |= AST_I2CD_M_STOP_CMD;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
+ ~AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+ } else {
+@@ -791,46 +823,46 @@ static void ast_i2c_do_pool_xfer(struct ast_i2c_dev *i2c_dev)
+ if((i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt) > i2c_dev->req_page->page_size) {
+ i2c_dev->master_xfer_len = i2c_dev->req_page->page_size;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+-
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++
+ } else {
+ i2c_dev->master_xfer_len = i2c_dev->master_msgs->len - i2c_dev->master_xfer_cnt;
+ if(i2c_dev->xfer_last == 1) {
+ dev_dbg(i2c_dev->dev, "last stop \n");
+ cmd |= AST_I2CD_M_STOP_CMD;
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
+- ~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+-
++ ~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++
+ } else {
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+ }
+ }
+-
++
+ for(i = 0; i < i2c_dev->master_xfer_len; i++) {
+ if(i%4 == 0)
+ tx_buf[i/4] = 0;
+ tx_buf[i/4] |= (i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt + i] << ((i%4)*8)) ;
+ }
+-// printk("count %x \n",ast_i2c_read(i2c_dev,I2C_CMD_REG));
+- ast_i2c_write(i2c_dev,
++// printk("count %x \n",ast_i2c_read(i2c_dev,I2C_CMD_REG));
++ ast_i2c_write(i2c_dev,
+ AST_I2CD_TX_DATA_BUF_END_SET((i2c_dev->master_xfer_len - 1)) |
+ AST_I2CD_BUF_BASE_ADDR_SET(i2c_dev->req_page->page_addr_point),
+ I2C_BUF_CTRL_REG);
+-
++
+ ast_i2c_write(i2c_dev, cmd , I2C_CMD_REG);
+ dev_dbg(i2c_dev->dev, "txfer size %d , cmd = %x \n",i2c_dev->master_xfer_len, cmd);
+ }
+ } else {
+- //should send next msg
++ //should send next msg
+ if(i2c_dev->master_xfer_cnt != i2c_dev->master_msgs->len)
+ printk("complete rx ... bus=%d addr=0x%x (%d vs. %d) ERROR\n",
+ i2c_dev->bus_id, i2c_dev->master_msgs->addr,
+ i2c_dev->master_xfer_cnt, i2c_dev->master_msgs->len);
+-
++
+ dev_dbg(i2c_dev->dev, "ast_i2c_do_byte_xfer complete \n");
+ i2c_dev->cmd_err = 0;
+- complete(&i2c_dev->cmd_complete);
++ complete(&i2c_dev->cmd_complete);
+ }
+
+ }
+@@ -843,16 +875,16 @@ static void ast_i2c_do_byte_xfer(struct ast_i2c_dev *i2c_dev)
+ i2c_dev->master_xfer_mode = BYTE_XFER;
+ i2c_dev->master_xfer_len = 1;
+
+- i2c_dev->slave_xfer_mode = BYTE_XFER;
++ i2c_dev->slave_xfer_mode = BYTE_XFER;
+ i2c_dev->slave_xfer_len = 1;
+-
+- if(i2c_dev->slave_operation == 1) {
++
++ if(i2c_dev->slave_operation == 1) {
+ dev_dbg(i2c_dev->dev,"S cnt %d, xf len %d \n",i2c_dev->slave_xfer_cnt, i2c_dev->slave_msgs->len);
+ if(i2c_dev->slave_msgs->flags & I2C_M_RD) {
+ //READ <-- TX
+ dev_dbg(i2c_dev->dev, "(<--) slave(tx) buf %d [%x]\n", i2c_dev->slave_xfer_cnt, i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt]);
+ ast_i2c_write(i2c_dev, i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt], I2C_BYTE_BUF_REG);
+- ast_i2c_write(i2c_dev, AST_I2CD_S_TX_CMD, I2C_CMD_REG);
++ ast_i2c_write(i2c_dev, AST_I2CD_S_TX_CMD, I2C_CMD_REG);
+ } else {
+ // Write -->Rx
+ //no need to handle in byte mode
+@@ -862,21 +894,21 @@ static void ast_i2c_do_byte_xfer(struct ast_i2c_dev *i2c_dev)
+ } else {
+ dev_dbg(i2c_dev->dev,"M cnt %d, xf len %d \n",i2c_dev->master_xfer_cnt, i2c_dev->master_msgs->len);
+ if(i2c_dev->master_xfer_cnt == -1) {
+- //first start
++ //first start
+ dev_dbg(i2c_dev->dev, " %sing %d byte%s %s 0x%02x\n",
+ i2c_dev->master_msgs->flags & I2C_M_RD ? "read" : "write",
+ i2c_dev->master_msgs->len, i2c_dev->master_msgs->len > 1 ? "s" : "",
+ i2c_dev->master_msgs->flags & I2C_M_RD ? "from" : "to", i2c_dev->master_msgs->addr);
+-
+-
+- if(i2c_dev->master_msgs->flags & I2C_M_RD)
++
++
++ if(i2c_dev->master_msgs->flags & I2C_M_RD)
+ ast_i2c_write(i2c_dev, (i2c_dev->master_msgs->addr <<1) |0x1, I2C_BYTE_BUF_REG);
+ else
+ ast_i2c_write(i2c_dev, (i2c_dev->master_msgs->addr <<1), I2C_BYTE_BUF_REG);
+
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+-
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++
+ ast_i2c_write(i2c_dev, AST_I2CD_M_TX_CMD | AST_I2CD_M_START_CMD, I2C_CMD_REG);
+
+
+@@ -888,7 +920,7 @@ static void ast_i2c_do_byte_xfer(struct ast_i2c_dev *i2c_dev)
+ if((i2c_dev->master_msgs->flags & I2C_M_RECV_LEN) && (i2c_dev->master_xfer_cnt == 0)) {
+ dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN \n");
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
++ AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+
+ } else if((i2c_dev->xfer_last == 1) && (i2c_dev->master_xfer_cnt + 1 == i2c_dev->master_msgs->len)) {
+ cmd |= AST_I2CD_M_S_RX_CMD_LAST | AST_I2CD_M_STOP_CMD;
+@@ -897,11 +929,11 @@ static void ast_i2c_do_byte_xfer(struct ast_i2c_dev *i2c_dev)
+ ~AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+ } else {
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
++ AST_I2CD_RX_DOWN_INTR_EN, I2C_INTR_CTRL_REG);
+ }
+
+ dev_dbg(i2c_dev->dev, "(<--) rx byte, cmd = %x \n",cmd);
+-
++
+ ast_i2c_write(i2c_dev, cmd, I2C_CMD_REG);
+
+
+@@ -911,29 +943,29 @@ static void ast_i2c_do_byte_xfer(struct ast_i2c_dev *i2c_dev)
+ ast_i2c_write(i2c_dev, *(xfer_buf + i2c_dev->master_xfer_cnt), I2C_BYTE_BUF_REG);
+ if((i2c_dev->xfer_last == 1) && (i2c_dev->master_xfer_cnt + 1 == i2c_dev->master_msgs->len)) {
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) &
+- ~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++ ~AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+ ast_i2c_write(i2c_dev, AST_I2CD_M_TX_CMD | AST_I2CD_M_STOP_CMD, I2C_CMD_REG);
+ } else {
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+- AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
++ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+ ast_i2c_write(i2c_dev, AST_I2CD_M_TX_CMD, I2C_CMD_REG);
+ }
+ }
+-
++
+ } else {
+- //should send next msg
++ //should send next msg
+ if(i2c_dev->master_xfer_cnt != i2c_dev->master_msgs->len)
+ printk("CNT ERROR bus=%d addr=0x%x (%d vs. %d)\n",
+ i2c_dev->bus_id, i2c_dev->master_msgs->addr,
+ i2c_dev->master_xfer_cnt, i2c_dev->master_msgs->len);
+-
++
+ dev_dbg(i2c_dev->dev, "ast_i2c_do_byte_xfer complete \n");
+ i2c_dev->cmd_err = 0;
+- complete(&i2c_dev->cmd_complete);
+-
++ complete(&i2c_dev->cmd_complete);
++
+ }
+ }
+-
++
+ }
+
+ static void ast_i2c_slave_xfer_done(struct ast_i2c_dev *i2c_dev)
+@@ -941,8 +973,8 @@ static void ast_i2c_slave_xfer_done(struct ast_i2c_dev *i2c_dev)
+ u32 xfer_len;
+ int i;
+ u8 *rx_buf;
+-
+- dev_dbg(i2c_dev->dev, "ast_i2c_slave_xfer_done [%d]\n",i2c_dev->slave_xfer_mode);
++
++ dev_dbg(i2c_dev->dev, "ast_i2c_slave_xfer_done [%d]\n",i2c_dev->slave_xfer_mode);
+
+ if (i2c_dev->slave_msgs->flags & I2C_M_RD) {
+ //tx done , only check tx count ...
+@@ -979,16 +1011,16 @@ static void ast_i2c_slave_xfer_done(struct ast_i2c_dev *i2c_dev)
+ xfer_len = AST_I2CD_RX_BUF_ADDR_GET(ast_i2c_read(i2c_dev, I2C_BUF_CTRL_REG));
+ if(xfer_len == 0)
+ xfer_len = AST_I2C_PAGE_SIZE;
+-
++
+ dev_dbg(i2c_dev->dev,"rx buff done len %d \n",xfer_len);
+-
++
+ rx_buf = (u8 *)i2c_dev->req_page->page_addr;
+-
++
+ for(i=0;i<xfer_len;i++) {
+ i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt+i] = rx_buf[i];
+ dev_dbg(i2c_dev->dev,"%d, [%x] \n",i2c_dev->slave_xfer_cnt+i ,i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt+i]);
+ }
+-
++
+ } else {
+ //RX DMA DOWN
+ xfer_len = ast_i2c_read(i2c_dev, I2C_DMA_LEN_REG);
+@@ -996,15 +1028,15 @@ static void ast_i2c_slave_xfer_done(struct ast_i2c_dev *i2c_dev)
+ xfer_len = i2c_dev->slave_xfer_len;
+ else
+ xfer_len = i2c_dev->slave_xfer_len - xfer_len - 1;
+-
++
+ dev_dbg(i2c_dev->dev, " rx dma done len %d \n", xfer_len);
+-
++
+ for(i=0;i<xfer_len;i++) {
+ i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt+i] = i2c_dev->dma_buf[i];
+ dev_dbg(i2c_dev->dev,"%d, [%x] \n",i2c_dev->slave_xfer_cnt+i ,i2c_dev->slave_msgs->buf[i2c_dev->slave_xfer_cnt+i]);
+ }
+ }
+-
++
+ }
+
+ if(xfer_len !=i2c_dev->slave_xfer_len) {
+@@ -1012,7 +1044,7 @@ static void ast_i2c_slave_xfer_done(struct ast_i2c_dev *i2c_dev)
+ printk(" **slave xfer error ====\n");
+ //should goto stop....
+ } else
+- i2c_dev->slave_xfer_cnt += i2c_dev->slave_xfer_len;
++ i2c_dev->slave_xfer_cnt += i2c_dev->slave_xfer_len;
+
+
+ if((i2c_dev->slave_event == I2C_SLAVE_EVENT_NACK) || (i2c_dev->slave_event == I2C_SLAVE_EVENT_STOP)) {
+@@ -1020,33 +1052,33 @@ static void ast_i2c_slave_xfer_done(struct ast_i2c_dev *i2c_dev)
+ ast_i2c_slave_rdwr_xfer(i2c_dev);
+ #else
+ i2c_dev->ast_i2c_data->slave_xfer(i2c_dev->slave_event, &(i2c_dev->slave_msgs));
+-#endif
++#endif
+ i2c_dev->slave_xfer_cnt = 0;
+ } else {
+ if(i2c_dev->slave_xfer_cnt == i2c_dev->slave_msgs->len) {
+- dev_dbg(i2c_dev->dev,"slave next msgs \n");
++ dev_dbg(i2c_dev->dev,"slave next msgs \n");
+ #ifdef CONFIG_AST_I2C_SLAVE_RDWR
+ ast_i2c_slave_rdwr_xfer(i2c_dev);
+ #else
+ i2c_dev->ast_i2c_data->slave_xfer(i2c_dev->slave_event, &(i2c_dev->slave_msgs));
+-#endif
++#endif
+
+ i2c_dev->slave_xfer_cnt = 0;
+- }
++ }
+ i2c_dev->do_slave_xfer(i2c_dev);
+ }
+
+
+ if(AST_I2CD_IDLE == i2c_dev->state) {
+- dev_dbg(i2c_dev->dev,"** Slave go IDLE **\n");
++ dev_dbg(i2c_dev->dev,"** Slave go IDLE **\n");
+ i2c_dev->slave_operation = 0;
+-
++
+ if(i2c_dev->slave_xfer_mode == BUFF_XFER) {
+ i2c_dev->ast_i2c_data->free_pool_buff_page(i2c_dev->req_page);
+- }
+-
+- }
+-
++ }
++
++ }
++
+ }
+
+ //TX/Rx Done
+@@ -1057,7 +1089,7 @@ static void ast_i2c_master_xfer_done(struct ast_i2c_dev *i2c_dev)
+ u8 *pool_buf;
+ unsigned long flags;
+
+- spin_lock_irqsave(&g_master_lock, flags);
++ spin_lock_irqsave(&i2c_dev->master_lock, flags);
+
+ /*
+ * This function shall be involked during interrupt handling.
+@@ -1068,8 +1100,8 @@ static void ast_i2c_master_xfer_done(struct ast_i2c_dev *i2c_dev)
+ goto unlock_out;
+ }
+
+- dev_dbg(i2c_dev->dev, "ast_i2c_master_xfer_done mode[%d]\n",i2c_dev->master_xfer_mode);
+-
++ dev_dbg(i2c_dev->dev, "ast_i2c_master_xfer_done mode[%d]\n",i2c_dev->master_xfer_mode);
++
+ if (i2c_dev->master_msgs->flags & I2C_M_RD) {
+ if(i2c_dev->master_xfer_cnt == -1) {
+ xfer_len = 1;
+@@ -1077,16 +1109,16 @@ static void ast_i2c_master_xfer_done(struct ast_i2c_dev *i2c_dev)
+ }
+ if(i2c_dev->master_xfer_mode == BYTE_XFER) {
+ if ((i2c_dev->master_msgs->flags & I2C_M_RECV_LEN) && (i2c_dev->blk_r_flag == 0)) {
+- i2c_dev->master_msgs->len += (ast_i2c_read(i2c_dev,I2C_BYTE_BUF_REG) & AST_I2CD_RX_BYTE_BUFFER) >> 8;
++ i2c_dev->master_msgs->len += (ast_i2c_read(i2c_dev,I2C_BYTE_BUF_REG) & AST_I2CD_RX_BYTE_BUFFER) >> 8;
+ i2c_dev->blk_r_flag = 1;
+- dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN %d \n", i2c_dev->master_msgs->len -1);
++ dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN %d \n", i2c_dev->master_msgs->len -1);
+ }
+ xfer_len = 1;
+ i2c_dev->master_msgs->buf[i2c_dev->master_xfer_cnt] = (ast_i2c_read(i2c_dev,I2C_BYTE_BUF_REG) & AST_I2CD_RX_BYTE_BUFFER) >> 8;
+ } else if (i2c_dev->master_xfer_mode == BUFF_XFER) {
+ pool_buf = (u8 *)i2c_dev->req_page->page_addr;
+ xfer_len = AST_I2CD_RX_BUF_ADDR_GET(ast_i2c_read(i2c_dev, I2C_BUF_CTRL_REG));
+-
++
+ if(xfer_len == 0)
+ xfer_len = AST_I2C_PAGE_SIZE;
+
+@@ -1098,7 +1130,7 @@ static void ast_i2c_master_xfer_done(struct ast_i2c_dev *i2c_dev)
+ if ((i2c_dev->master_msgs->flags & I2C_M_RECV_LEN) && (i2c_dev->blk_r_flag == 0)) {
+ i2c_dev->master_msgs->len += pool_buf[0];
+ i2c_dev->blk_r_flag = 1;
+- dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN %d \n", i2c_dev->master_msgs->len -1);
++ dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN %d \n", i2c_dev->master_msgs->len -1);
+ }
+ } else {
+ //DMA Mode
+@@ -1114,13 +1146,13 @@ static void ast_i2c_master_xfer_done(struct ast_i2c_dev *i2c_dev)
+ dev_dbg(i2c_dev->dev, "buf[%x] \n", i2c_dev->dma_buf[i]);
+ dev_dbg(i2c_dev->dev, "buf[%x] \n", i2c_dev->dma_buf[i+1]);
+ }
+-
++
+ if ((i2c_dev->master_msgs->flags & I2C_M_RECV_LEN) && (i2c_dev->blk_r_flag == 0)) {
+ i2c_dev->master_msgs->len += i2c_dev->dma_buf[0];
+ i2c_dev->blk_r_flag = 1;
+- dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN %d \n", i2c_dev->master_msgs->len -1);
++ dev_dbg(i2c_dev->dev, "I2C_M_RECV_LEN %d \n", i2c_dev->master_msgs->len -1);
+ }
+-
++
+ }
+
+ }else {
+@@ -1153,28 +1185,28 @@ next_xfer:
+ i2c_dev->cmd_err = 1;
+ goto done_out;
+ } else
+- i2c_dev->master_xfer_cnt += i2c_dev->master_xfer_len;
++ i2c_dev->master_xfer_cnt += i2c_dev->master_xfer_len;
+
+ if(i2c_dev->master_xfer_cnt != i2c_dev->master_msgs->len) {
+ dev_dbg(i2c_dev->dev,"do next cnt \n");
+ i2c_dev->do_master_xfer(i2c_dev);
+ } else {
+-#if 0
+- int i;
++#if 0
++ int i;
+ printk(" ===== \n");
+ for(i=0;i<i2c_dev->master_msgs->len;i++)
+ printk("rx buf i,[%x]\n",i,i2c_dev->master_msgs->buf[i]);
+- printk(" ===== \n");
+-#endif
++ printk(" ===== \n");
++#endif
+ i2c_dev->cmd_err = 0;
+
+ done_out:
+ dev_dbg(i2c_dev->dev,"msgs complete \n");
+- complete(&i2c_dev->cmd_complete);
++ complete(&i2c_dev->cmd_complete);
+ }
+
+ unlock_out:
+- spin_unlock_irqrestore(&g_master_lock, flags);
++ spin_unlock_irqrestore(&i2c_dev->master_lock, flags);
+ }
+
+ static void ast_i2c_slave_addr_match(struct ast_i2c_dev *i2c_dev)
+@@ -1187,7 +1219,7 @@ static void ast_i2c_slave_addr_match(struct ast_i2c_dev *i2c_dev)
+ i2c_dev->slave_msgs->buf[0] = match;
+ dev_dbg(i2c_dev->dev, "S Start Addr match [%x] \n",match);
+
+-
++
+ if(match & 1) {
+ i2c_dev->slave_event = I2C_SLAVE_EVENT_START_READ;
+ } else {
+@@ -1201,7 +1233,7 @@ static void ast_i2c_slave_addr_match(struct ast_i2c_dev *i2c_dev)
+ #else
+ i2c_dev->ast_i2c_data->slave_xfer(i2c_dev->slave_event, &(i2c_dev->slave_msgs));
+ i2c_dev->slave_xfer_cnt = 0;
+-#endif
++#endif
+
+ //request
+ if(i2c_dev->ast_i2c_data->slave_dma == BYTE_MODE)
+@@ -1211,7 +1243,7 @@ static void ast_i2c_slave_addr_match(struct ast_i2c_dev *i2c_dev)
+ else {
+ if(i2c_dev->ast_i2c_data->request_pool_buff_page(&(i2c_dev->req_page)) == 0)
+ i2c_dev->do_slave_xfer = ast_i2c_do_pool_xfer;
+- else
++ else
+ i2c_dev->do_slave_xfer = ast_i2c_do_byte_xfer;
+ }
+
+@@ -1221,7 +1253,7 @@ static void ast_i2c_slave_addr_match(struct ast_i2c_dev *i2c_dev)
+
+ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+ {
+- u32 sts;
++ u32 sts;
+
+ struct ast_i2c_dev *i2c_dev = dev_id;
+ u32 isr_sts = readl(i2c_dev->ast_i2c_data->reg_gr);
+@@ -1231,7 +1263,7 @@ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+
+ i2c_dev->state = (ast_i2c_read(i2c_dev,I2C_CMD_REG) >> 19) & 0xf;
+ sts = ast_i2c_read(i2c_dev,I2C_INTR_STS_REG);
+-// printk("ISR : %x , sts [%x]\n",sts , xfer_sts);
++// printk("ISR : %x , sts [%x]\n",sts , xfer_sts);
+ // dev_dbg(i2c_dev->dev,"ISR : %x , sts [%x]\n",sts , xfer_sts);
+
+ // dev_dbg(i2c_dev->dev,"sts machine %x, slave_op %d \n", xfer_sts,i2c_dev->slave_operation);
+@@ -1244,9 +1276,9 @@ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+ I2C_INTR_CTRL_REG);
+ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_SMBUS_ALT, I2C_INTR_STS_REG);
+ ast_master_alert_recv(i2c_dev);
+- sts &= ~AST_I2CD_SMBUS_ALT_INTR_EN;
++ sts &= ~AST_I2CD_SMBUS_ALT_INTR_EN;
+ }
+-
++
+ if(AST_I2CD_INTR_STS_ABNORMAL & sts) {
+ i2c_dev->cmd_err |= AST_I2CD_INTR_STS_ABNORMAL;
+ // Turn off interrupts for further abnormal
+@@ -1257,6 +1289,8 @@ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+ I2C_INTR_CTRL_REG);
+ complete(&i2c_dev->cmd_complete);
+ sts &= ~AST_I2CD_INTR_STS_ABNORMAL;
++ // Need to clear the interrupt
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_ABNORMAL, I2C_INTR_STS_REG);
+ }
+
+ switch(sts) {
+@@ -1265,7 +1299,7 @@ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+ i2c_dev->slave_event = I2C_SLAVE_EVENT_READ;
+ ast_i2c_slave_xfer_done(i2c_dev);
+ dev_dbg(i2c_dev->dev, "S clear isr: AST_I2CD_INTR_STS_TX_ACK = %x\n",sts);
+- ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_ACK, I2C_INTR_STS_REG);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_ACK, I2C_INTR_STS_REG);
+ } else {
+ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_TX_ACK = %x\n",sts);
+ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_ACK, I2C_INTR_STS_REG);
+@@ -1280,9 +1314,17 @@ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+ ast_i2c_write(i2c_dev, ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
+ AST_I2CD_TX_ACK_INTR_EN, I2C_INTR_CTRL_REG);
+ ast_i2c_master_xfer_done(i2c_dev);
+-
++
+ } else {
+- printk("TODO ...\n");
++ printk("ast_i2c: TX_ACK | NORMAL_STOP; xfer_last %d\n", i2c_dev->xfer_last);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_ACK | AST_I2CD_INTR_STS_NORMAL_STOP, I2C_INTR_STS_REG);
++ uint32_t new_val = ast_i2c_read(i2c_dev,I2C_INTR_CTRL_REG) |
++ AST_I2CD_NORMAL_STOP_INTR_EN |
++ AST_I2CD_TX_ACK_INTR_EN;
++ ast_i2c_write(i2c_dev, new_val, I2C_INTR_CTRL_REG);
++ //take care
++ i2c_dev->cmd_err |= AST_LOCKUP_DETECTED;
++ complete(&i2c_dev->cmd_complete);
+ }
+ break;
+
+@@ -1291,8 +1333,8 @@ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+ i2c_dev->slave_event = I2C_SLAVE_EVENT_NACK;
+ ast_i2c_slave_xfer_done(i2c_dev);
+ dev_dbg(i2c_dev->dev, "S clear isr: AST_I2CD_INTR_STS_TX_NAK = %x\n",sts);
+- ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_NAK, I2C_INTR_STS_REG);
+-
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_NAK, I2C_INTR_STS_REG);
++
+ } else {
+ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_TX_NAK = %x\n",sts);
+ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_NAK, I2C_INTR_STS_REG);
+@@ -1310,7 +1352,7 @@ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+ case AST_I2CD_INTR_STS_TX_NAK | AST_I2CD_INTR_STS_NORMAL_STOP:
+ if(i2c_dev->slave_operation == 1) {
+ printk("SLAVE TODO .... \n");
+-
++
+ } else {
+ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_TX_NAK| AST_I2CD_INTR_STS_NORMAL_STOP = %x\n",sts);
+ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_NAK | AST_I2CD_INTR_STS_NORMAL_STOP, I2C_INTR_STS_REG);
+@@ -1320,47 +1362,47 @@ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+ }
+ break;
+
+- //Issue : Workaround for I2C slave mode
++ //Issue : Workaround for I2C slave mode
+ case AST_I2CD_INTR_STS_TX_NAK | AST_I2CD_INTR_STS_SLAVE_MATCH:
+ if(i2c_dev->slave_operation == 1) {
+ i2c_dev->slave_event = I2C_SLAVE_EVENT_NACK;
+ ast_i2c_slave_xfer_done(i2c_dev);
+ ast_i2c_slave_addr_match(i2c_dev);
+- ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_NAK | AST_I2CD_INTR_STS_SLAVE_MATCH , I2C_INTR_STS_REG);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_TX_NAK | AST_I2CD_INTR_STS_SLAVE_MATCH , I2C_INTR_STS_REG);
+ } else {
+ printk("ERROR !!!!\n");
+ }
+ break;
+ case AST_I2CD_INTR_STS_RX_DOWN | AST_I2CD_INTR_STS_SLAVE_MATCH:
+ ast_i2c_slave_addr_match(i2c_dev);
+- dev_dbg(i2c_dev->dev, "S clear isr: AST_I2CD_INTR_STS_RX_DOWN | AST_I2CD_INTR_STS_SLAVE_MATCH = %x\n",sts);
++ dev_dbg(i2c_dev->dev, "S clear isr: AST_I2CD_INTR_STS_RX_DOWN | AST_I2CD_INTR_STS_SLAVE_MATCH = %x\n",sts);
+ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_RX_DOWN | AST_I2CD_INTR_STS_SLAVE_MATCH, I2C_INTR_STS_REG);
+ break;
+-
++
+ case AST_I2CD_INTR_STS_RX_DOWN:
+ if(i2c_dev->slave_operation == 1) {
+ i2c_dev->slave_event = I2C_SLAVE_EVENT_WRITE;
+ ast_i2c_slave_xfer_done(i2c_dev);
+ dev_dbg(i2c_dev->dev, "S clear isr: AST_I2CD_INTR_STS_RX_DOWN = %x\n",sts);
+- ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_RX_DOWN, I2C_INTR_STS_REG);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_RX_DOWN, I2C_INTR_STS_REG);
+ } else {
+ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_RX_DOWN = %x\n",sts);
+ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_RX_DOWN, I2C_INTR_STS_REG);
+ ast_i2c_master_xfer_done(i2c_dev);
+-
++
+ }
+ break;
+-
++
+ case AST_I2CD_INTR_STS_NORMAL_STOP:
+ if(i2c_dev->slave_operation == 1) {
+ i2c_dev->slave_event = I2C_SLAVE_EVENT_STOP;
+ ast_i2c_slave_xfer_done(i2c_dev);
+ dev_dbg(i2c_dev->dev, "S clear isr: AST_I2CD_INTR_STS_NORMAL_STOP = %x\n",sts);
+- ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_NORMAL_STOP, I2C_INTR_STS_REG);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_NORMAL_STOP, I2C_INTR_STS_REG);
+ dev_dbg(i2c_dev->dev, "state [%x] \n",i2c_dev->state);
+- } else {
++ } else {
+ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_NORMAL_STOP = %x\n",sts);
+- ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_NORMAL_STOP, I2C_INTR_STS_REG);
++ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_NORMAL_STOP, I2C_INTR_STS_REG);
+ i2c_dev->cmd_err |= AST_I2CD_INTR_STS_NORMAL_STOP;
+ complete(&i2c_dev->cmd_complete);
+ }
+@@ -1380,24 +1422,24 @@ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_ARBIT_LOSS = %x\n",sts);
+ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_ARBIT_LOSS, I2C_INTR_STS_REG);
+ i2c_dev->cmd_err |= AST_I2CD_INTR_STS_ARBIT_LOSS;
+- complete(&i2c_dev->cmd_complete);
++ complete(&i2c_dev->cmd_complete);
+ break;
+ case AST_I2CD_INTR_STS_SCL_TO:
+ i2c_dev->cmd_err |= AST_I2CD_INTR_STS_SCL_TO;
+- complete(&i2c_dev->cmd_complete);
+-
++ complete(&i2c_dev->cmd_complete);
++
+ break;
+ case AST_I2CD_INTR_STS_GCALL_ADDR:
+ i2c_dev->cmd_err |= AST_I2CD_INTR_STS_GCALL_ADDR;
+- complete(&i2c_dev->cmd_complete);
++ complete(&i2c_dev->cmd_complete);
+
+ break;
+ case AST_I2CD_INTR_STS_SMBUS_DEF_ADDR:
+ break;
+ case AST_I2CD_INTR_STS_SMBUS_DEV_ALT:
+-
++
+ break;
+-
++
+ case AST_I2CD_INTR_STS_SMBUS_ARP_ADDR:
+ break;
+ case AST_I2CD_INTR_STS_SDA_DL_TO:
+@@ -1405,25 +1447,50 @@ static irqreturn_t i2c_ast_handler(int this_irq, void *dev_id)
+ case AST_I2CD_INTR_STS_BUS_RECOVER:
+ dev_dbg(i2c_dev->dev, "M clear isr: AST_I2CD_INTR_STS_BUS_RECOVER= %x\n",sts);
+ ast_i2c_write(i2c_dev, AST_I2CD_INTR_STS_BUS_RECOVER, I2C_INTR_STS_REG);
+- complete(&i2c_dev->cmd_complete);
++ complete(&i2c_dev->cmd_complete);
+ break;
+ default:
+- if(sts)
+- printk("GR %x : No one care : %x, bus_id %d\n",i2c_dev->ast_i2c_data->reg_gr, sts, i2c_dev->bus_id);
+- return IRQ_NONE;
++ //TODO: Clearing this interrupt for now, but needs to cleanup this ISR function
++ ast_i2c_write(i2c_dev, sts, I2C_INTR_STS_REG);
++
++ // Handle Arbitration Loss
++ if (sts & AST_I2CD_INTR_STS_ARBIT_LOSS) {
++ i2c_dev->cmd_err |= AST_I2CD_INTR_STS_ARBIT_LOSS;
++ complete(&i2c_dev->cmd_complete);
++ sts &= (~AST_I2CD_INTR_STS_ARBIT_LOSS);
++ }
++
++ // Handle the write transaction ACK
++ if (sts & AST_I2CD_INTR_STS_TX_ACK) {
++ ast_i2c_master_xfer_done(i2c_dev);
++ complete(&i2c_dev->cmd_complete);
++ sts &= (~AST_I2CD_INTR_STS_TX_ACK);
++ }
++
++ // Handle the Slave address match
++ if (sts & AST_I2CD_INTR_STS_SLAVE_MATCH) {
++ ast_i2c_slave_addr_match(i2c_dev);
++ sts &= (~AST_I2CD_INTR_STS_SLAVE_MATCH);
++ }
++
++ // TODO: Debug print for any unhandled condition
++ if(sts) {
++ printk("GR %x : Status : %x, bus_id %d\n",i2c_dev->ast_i2c_data->reg_gr, sts, i2c_dev->bus_id);
++ }
++
++ return IRQ_HANDLED;
+ }
+
+ return IRQ_HANDLED;
+-
+ }
+
+ static int ast_i2c_do_msgs_xfer(struct ast_i2c_dev *i2c_dev, struct i2c_msg *msgs, int num)
+ {
+ int i;
+- int ret = 1;
++ int ret = 1;
+ unsigned long flags;
+
+- spin_lock_irqsave(&g_master_lock, flags);
++ spin_lock_irqsave(&i2c_dev->master_lock, flags);
+
+ //request
+ if(i2c_dev->ast_i2c_data->master_dma == BYTE_MODE)
+@@ -1433,7 +1500,7 @@ static int ast_i2c_do_msgs_xfer(struct ast_i2c_dev *i2c_dev, struct i2c_msg *msg
+ else {
+ if(i2c_dev->ast_i2c_data->request_pool_buff_page(&(i2c_dev->req_page)) == 0)
+ i2c_dev->do_master_xfer = ast_i2c_do_pool_xfer;
+- else
++ else
+ i2c_dev->do_master_xfer = ast_i2c_do_byte_xfer;
+ }
+
+@@ -1458,12 +1525,12 @@ static int ast_i2c_do_msgs_xfer(struct ast_i2c_dev *i2c_dev, struct i2c_msg *msg
+
+ i2c_dev->do_master_xfer(i2c_dev);
+
+- spin_unlock_irqrestore(&g_master_lock, flags);
++ spin_unlock_irqrestore(&i2c_dev->master_lock, flags);
+
+ ret = wait_for_completion_interruptible_timeout(&i2c_dev->cmd_complete,
+ i2c_dev->adap.timeout*HZ);
+-
+- spin_lock_irqsave(&g_master_lock, flags);
++
++ spin_lock_irqsave(&i2c_dev->master_lock, flags);
+ i2c_dev->master_msgs = NULL;
+
+ if (ret == 0) {
+@@ -1471,25 +1538,30 @@ static int ast_i2c_do_msgs_xfer(struct ast_i2c_dev *i2c_dev, struct i2c_msg *msg
+ i2c_dev->state = (ast_i2c_read(i2c_dev,I2C_CMD_REG) >> 19) & 0xf;
+ // printk("sts [%x], isr sts [%x] \n",i2c_dev->state, ast_i2c_read(i2c_dev,I2C_INTR_STS_REG));
+ ret = -ETIMEDOUT;
+- spin_unlock_irqrestore(&g_master_lock, flags);
++ spin_unlock_irqrestore(&i2c_dev->master_lock, flags);
+ goto stop;
+ }
+-
++
+ if(i2c_dev->cmd_err != 0 &&
+ i2c_dev->cmd_err != AST_I2CD_INTR_STS_NORMAL_STOP) {
++ if (i2c_dev->cmd_err & AST_LOCKUP_DETECTED) {
++ printk("ast-i2c: error got unexpected STOP\n");
++ // reset the bus
++ ast_i2c_bus_error_recover(i2c_dev);
++ }
+ ret = -EAGAIN;
+- spin_unlock_irqrestore(&g_master_lock, flags);
++ spin_unlock_irqrestore(&i2c_dev->master_lock, flags);
+ goto stop;
+ }
+ }
+
+- spin_unlock_irqrestore(&g_master_lock, flags);
++ spin_unlock_irqrestore(&i2c_dev->master_lock, flags);
+
+ if(i2c_dev->cmd_err == 0 ||
+ i2c_dev->cmd_err == AST_I2CD_INTR_STS_NORMAL_STOP) {
+ ret = num;
+ goto out;
+-
++
+ }
+ stop:
+ init_completion(&i2c_dev->cmd_complete);
+@@ -1503,8 +1575,8 @@ out:
+ //Free ..
+ if(i2c_dev->master_xfer_mode == BUFF_XFER) {
+ i2c_dev->ast_i2c_data->free_pool_buff_page(i2c_dev->req_page);
+-
+- }
++
++ }
+ dev_dbg(i2c_dev->dev, "end xfer ret = %d, xfer mode[%d]\n",ret, i2c_dev->master_xfer_mode);
+ return ret;
+
+@@ -1521,7 +1593,7 @@ static int ast_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+ /*
+ * Wait for the bus to become free.
+ */
+-
++
+ ret = ast_i2c_wait_bus_not_busy(i2c_dev);
+ if (ret) {
+ dev_err(&i2c_dev->adap.dev, "i2c_ast: timeout waiting for bus free\n");
+@@ -1536,7 +1608,7 @@ static int ast_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+ dev_dbg(&adap->dev, "Retrying transmission [%d]\n",i);
+ udelay(100);
+ }
+-
++
+ ret = -EREMOTEIO;
+ out:
+
+@@ -1550,9 +1622,9 @@ static u32 ast_i2c_functionality(struct i2c_adapter *adap)
+
+ static const struct i2c_algorithm i2c_ast_algorithm = {
+ .master_xfer = ast_i2c_xfer,
+-#ifdef CONFIG_AST_I2C_SLAVE_RDWR
++#ifdef CONFIG_AST_I2C_SLAVE_RDWR
+ .slave_xfer = ast_i2c_slave_xfer,
+-#endif
++#endif
+ .functionality = ast_i2c_functionality,
+ };
+
+@@ -1572,23 +1644,23 @@ static int ast_i2c_probe(struct platform_device *pdev)
+
+ i2c_dev->ast_i2c_data = pdev->dev.platform_data;
+ if(i2c_dev->ast_i2c_data->master_dma == BUFF_MODE) {
+- dev_dbg(&pdev->dev, "use buffer pool mode 256\n");
+-
++ dev_dbg(&pdev->dev, "use buffer pool mode 256\n");
++
+ } else if ((i2c_dev->ast_i2c_data->master_dma == DMA_MODE) || (i2c_dev->ast_i2c_data->slave_dma == DMA_MODE)) {
+- dev_dbg(&pdev->dev, "use dma mode \n");
++ dev_dbg(&pdev->dev, "use dma mode \n");
+ if (!i2c_dev->dma_buf) {
+ i2c_dev->dma_buf = dma_alloc_coherent(NULL, AST_I2C_DMA_SIZE, &i2c_dev->dma_addr, GFP_KERNEL);
+ if (!i2c_dev->dma_buf) {
+ printk("unable to allocate tx Buffer memory\n");
+ ret = -ENOMEM;
+- goto err_no_dma;
++ goto err_no_dma;
+ }
+ if(i2c_dev->dma_addr%4 !=0) {
+ printk("not 4 byte boundary \n");
+ ret = -ENOMEM;
+- goto err_no_dma;
+- }
+-// printk("dma_buf = [0x%x] dma_addr = [0x%x], please check 4byte boundary \n",i2c_dev->dma_buf,i2c_dev->dma_addr);
++ goto err_no_dma;
++ }
++// printk("dma_buf = [0x%x] dma_addr = [0x%x], please check 4byte boundary \n",i2c_dev->dma_buf,i2c_dev->dma_addr);
+ memset (i2c_dev->dma_buf, 0, AST_I2C_DMA_SIZE);
+ }
+
+@@ -1596,7 +1668,7 @@ static int ast_i2c_probe(struct platform_device *pdev)
+ //master_mode 0: use byte mode
+ dev_dbg(&pdev->dev, "use default byte mode \n");
+ }
+-
++
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (NULL == res) {
+ dev_err(&pdev->dev, "cannot get IORESOURCE_MEM\n");
+@@ -1628,11 +1700,11 @@ static int ast_i2c_probe(struct platform_device *pdev)
+ if(i2c_dev->irq == IRQ_C0_I2C) {
+ i2c_dev->bus_id = pdev->id - NUM_BUS;
+ dev_dbg(&pdev->dev, "C0 :: pdev->id %d , i2c_dev->bus_id = %d, i2c_dev->irq =%d\n",pdev->id, i2c_dev->bus_id,i2c_dev->irq);
+-#if (CONFIG_AST1070_NR >= 2)
++#if (CONFIG_AST1070_NR >= 2)
+ } else if(i2c_dev->irq == IRQ_C1_I2C) {
+ i2c_dev->bus_id = pdev->id - (NUM_BUS + 8);
+- dev_dbg(&pdev->dev, "C1 :: pdev->id %d , i2c_dev->bus_id = %d, i2c_dev->irq =%d\n",pdev->id, i2c_dev->bus_id,i2c_dev->irq);
+-#endif
++ dev_dbg(&pdev->dev, "C1 :: pdev->id %d , i2c_dev->bus_id = %d, i2c_dev->irq =%d\n",pdev->id, i2c_dev->bus_id,i2c_dev->irq);
++#endif
+ } else {
+ i2c_dev->bus_id = pdev->id;
+ dev_dbg(&pdev->dev, "AST pdev->id %d , i2c_dev->bus_id = %d, i2c_dev->irq =%d\n",pdev->id, i2c_dev->bus_id,i2c_dev->irq);
+@@ -1644,13 +1716,13 @@ static int ast_i2c_probe(struct platform_device *pdev)
+ /* Initialize the I2C adapter */
+ i2c_dev->adap.owner = THIS_MODULE;
+ //TODO
+- i2c_dev->adap.retries = 0;
++ i2c_dev->adap.retries = 0;
+
+-// i2c_dev->adap.retries = 3;
++// i2c_dev->adap.retries = 3;
+
+- i2c_dev->adap.timeout = 5;
++ i2c_dev->adap.timeout = 5;
+
+- i2c_dev->master_xfer_mode = BYTE_XFER;
++ i2c_dev->master_xfer_mode = BYTE_XFER;
+
+ /*
+ * If "pdev->id" is negative we consider it as zero.
+@@ -1662,7 +1734,7 @@ static int ast_i2c_probe(struct platform_device *pdev)
+ i2c_dev->adap.nr);
+
+ i2c_dev->slave_operation = 0;
+- i2c_dev->blk_r_flag = 0;
++ i2c_dev->blk_r_flag = 0;
+ i2c_dev->adap.algo = &i2c_ast_algorithm;
+
+ ast_i2c_dev_init(i2c_dev);
+@@ -1674,8 +1746,11 @@ static int ast_i2c_probe(struct platform_device *pdev)
+ goto ereqirq;
+ }
+
++ spin_lock_init(&i2c_dev->master_lock);
++
+ #ifdef CONFIG_AST_I2C_SLAVE_RDWR
+ ast_i2c_slave_buff_init(i2c_dev);
++ spin_lock_init(&i2c_dev->slave_rx_lock);
+ #endif
+
+ i2c_dev->adap.algo_data = i2c_dev;
+@@ -1718,7 +1793,7 @@ static int ast_i2c_remove(struct platform_device *pdev)
+
+ platform_set_drvdata(pdev, NULL);
+ i2c_del_adapter(&i2c_dev->adap);
+-
++
+ free_irq(i2c_dev->irq, i2c_dev);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+@@ -1742,7 +1817,7 @@ static int ast_i2c_resume(struct platform_device *pdev)
+ {
+ //TODO
+ // struct ast_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
+- //Should reset i2c ???
++ //Should reset i2c ???
+ return 0;
+ }
+ #else
+diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
+index c8e3cf6..06d9042 100644
+--- a/drivers/i2c/i2c-core.c
++++ b/drivers/i2c/i2c-core.c
+@@ -1064,7 +1064,7 @@ int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)
+ EXPORT_SYMBOL(i2c_transfer);
+
+ #ifdef CONFIG_AST_I2C_SLAVE_RDWR
+-int i2c_slave_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs)
++int i2c_slave_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+ {
+ unsigned long orig_jiffies;
+ int ret, try;
+@@ -1075,9 +1075,18 @@ int i2c_slave_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs)
+ "len=%d\n", (msgs->flags & I2C_S_RD)
+ ? 'R' : 'W', msgs->addr, msgs->len);
+ #endif
+- i2c_lock_adapter(adap);
++ if (in_atomic() || irqs_disabled()) {
++ ret = mutex_trylock(&adap->bus_lock);
++ if (!ret)
++ /* I2C activity is ongoing. */
++ return -EAGAIN;
++ } else {
++ mutex_lock_nested(&adap->bus_lock, adap->level);
++ }
++
+ ret = adap->algo->slave_xfer(adap, msgs);
+- i2c_unlock_adapter(adap);
++
++ mutex_unlock(&adap->bus_lock);
+
+ return ret;
+ } else {
+diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
+index 07f393d..82f2c7c 100644
+--- a/drivers/i2c/i2c-dev.c
++++ b/drivers/i2c/i2c-dev.c
+@@ -38,7 +38,7 @@
+ #include <asm/uaccess.h>
+
+ #ifdef CONFIG_AST_I2C_SLAVE_RDWR
+-#include <asm/arch/ast_i2c.h>
++#include <plat/ast_i2c.h>
+ #endif
+
+ static struct i2c_driver i2cdev_driver;
+@@ -310,6 +310,113 @@ static noinline int i2cdev_ioctl_rdrw(struct i2c_client *client,
+ return res;
+ }
+
++static noinline int i2cdev_ioctl_slave_rdrw(struct i2c_client *client,
++ unsigned long arg)
++{
++ struct i2c_rdwr_ioctl_data rdwr_arg;
++ struct i2c_msg *rdwr_pa;
++ u8 __user **data_ptrs;
++ int i, res;
++
++ if (copy_from_user(&rdwr_arg,
++ (struct i2c_rdwr_ioctl_data __user *)arg,
++ sizeof(rdwr_arg)))
++ return -EFAULT;
++
++ /* Put an arbitrary limit on the number of messages that can
++ * be sent at once */
++ if (rdwr_arg.nmsgs > I2C_RDRW_IOCTL_MAX_MSGS)
++ return -EINVAL;
++
++ rdwr_pa = (struct i2c_msg *)
++ kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg),
++ GFP_KERNEL);
++ if (!rdwr_pa)
++ return -ENOMEM;
++
++ if (copy_from_user(rdwr_pa, rdwr_arg.msgs,
++ rdwr_arg.nmsgs * sizeof(struct i2c_msg))) {
++ kfree(rdwr_pa);
++ return -EFAULT;
++ }
++
++ data_ptrs = kmalloc(rdwr_arg.nmsgs * sizeof(u8 __user *), GFP_KERNEL);
++ if (data_ptrs == NULL) {
++ kfree(rdwr_pa);
++ return -ENOMEM;
++ }
++
++ res = 0;
++ for (i = 0; i < rdwr_arg.nmsgs; i++) {
++ /* Limit the size of the message to a sane amount;
++ * and don't let length change either. */
++ if (rdwr_pa[i].len > 8192) {
++ res = -EINVAL;
++ break;
++ }
++ data_ptrs[i] = (u8 __user *)rdwr_pa[i].buf;
++ rdwr_pa[i].buf = kmalloc(rdwr_pa[i].len, GFP_KERNEL);
++ if (rdwr_pa[i].buf == NULL) {
++ res = -ENOMEM;
++ break;
++ }
++ if (copy_from_user(rdwr_pa[i].buf, data_ptrs[i],
++ rdwr_pa[i].len)) {
++ ++i; /* Needs to be kfreed too */
++ res = -EFAULT;
++ break;
++ }
++
++ /* From Linux 3.5: */
++ /*
++ * If the message length is received from the slave (similar
++ * to SMBus block read), we must ensure that the buffer will
++ * be large enough to cope with a message length of
++ * I2C_SMBUS_BLOCK_MAX as this is the maximum underlying bus
++ * drivers allow. The first byte in the buffer must be
++ * pre-filled with the number of extra bytes, which must be
++ * at least one to hold the message length, but can be
++ * greater (for example to account for a checksum byte at
++ * the end of the message.)
++ */
++ if (rdwr_pa[i].flags & I2C_M_RECV_LEN) {
++ if (!(rdwr_pa[i].flags & I2C_M_RD) ||
++ rdwr_pa[i].buf[0] < 1 ||
++ rdwr_pa[i].len < rdwr_pa[i].buf[0] +
++ I2C_SMBUS_BLOCK_MAX) {
++ res = -EINVAL;
++ break;
++ }
++
++ rdwr_pa[i].len = rdwr_pa[i].buf[0];
++ }
++
++ }
++ if (res < 0) {
++ int j;
++ for (j = 0; j < i; ++j)
++ kfree(rdwr_pa[j].buf);
++ kfree(data_ptrs);
++ kfree(rdwr_pa);
++ return res;
++ }
++
++ res = i2c_slave_transfer(client->adapter, rdwr_pa, rdwr_arg.nmsgs);
++ while (i-- > 0) {
++ if (res >= 0 ) {
++ if (copy_to_user(data_ptrs[i], rdwr_pa[i].buf,
++ rdwr_pa[i].len))
++ res = -EFAULT;
++
++ rdwr_arg.msgs[i].len = rdwr_pa[i].len;
++ }
++ kfree(rdwr_pa[i].buf);
++ }
++ kfree(data_ptrs);
++ kfree(rdwr_pa);
++ return res;
++}
++
+ static noinline int i2cdev_ioctl_smbus(struct i2c_client *client,
+ unsigned long arg)
+ {
+@@ -448,8 +555,8 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+
+ #ifdef CONFIG_AST_I2C_SLAVE_RDWR
+ case I2C_SLAVE_RDWR:
+- return i2cdev_ioctl_slave_rdrw(client->adapter, (struct i2c_msg __user *)arg);
+-#endif
++ return i2cdev_ioctl_slave_rdrw(client, arg);
++#endif
+
+ case I2C_SMBUS:
+ return i2cdev_ioctl_smbus(client, arg);
+diff --git a/drivers/net/ftgmac100_26.c b/drivers/net/ftgmac100_26.c
+index fdc77fc..3a5d796 100644
+--- a/drivers/net/ftgmac100_26.c
++++ b/drivers/net/ftgmac100_26.c
+@@ -1,16 +1,16 @@
+ /********************************************************************************
+ * File Name : ftgmac100_26.c
+-*
++*
+ * Copyright (C) 2012-2020 ASPEED Technology Inc.
+-* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ ********************************************************************************/
+ //-----------------------------------------------------------------------------
+ // "ASPEED MAC Driver, (Linux Kernel 2.6.15.7) 10/02/07 - by ASPEED\n"
+@@ -76,7 +76,7 @@
+ //AST2300 SDK 0.14
+ //19.09/13/2010 - by river@aspeed
+ // Support Realtek RTL8201EL 10/100M PHY
+-//AST2400
++//AST2400
+ //20.06/25/2013 - by CC@aspeed
+ // Support BCM54612E 10/100/1000M PHY
+ //-----------------------------------------------------------------------------
+@@ -120,7 +120,12 @@
+ #err "Not define include for GMAC"
+ #endif
+
++#ifdef CONFIG_WEDGE100
++#define PHY_DEFAULT_ADDR 0x18
++#else
++/* wedge */
+ #define PHY_DEFAULT_ADDR 0x1F
++#endif
+
+ /*------------------------------------------------------------------------
+ .
+@@ -172,7 +177,6 @@ static int ftgmac100_wait_to_send_packet(struct sk_buff * skb, struct net_device
+
+ static volatile int trans_busy = 0;
+
+-
+ void ftgmac100_phy_rw_waiting(unsigned int ioaddr)
+ {
+ unsigned int tmp;
+@@ -255,6 +259,7 @@ static void getMacHwConfig( struct net_device* dev, struct AstMacHwConfig* out )
+
+ // out->macId = dev->dev_id;
+ //.. getMacAndPhy(dev, out);
++ out->phyAddr = PHY_DEFAULT_ADDR;
+ out->miiPhyId = 0;
+
+ // We assume the Clock Stop register does not disable the MAC1 or MAC2 clock
+@@ -272,7 +277,7 @@ no_phy_access:
+ out->phyAddr = 1;
+ }
+ #if 0
+- if (out->miiPhyId == 0x0362) {
++ if (out->miiPhyId == 0x0362) {
+ out->phyAddr = 1;
+ }
+ #endif
+@@ -297,6 +302,902 @@ no_phy_access:
+ return;
+ }
+
++// --------------------------------------------------------------------
++// NCSI function
++// --------------------------------------------------------------------
++void NCSI_Struct_Initialize(struct net_device *dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long i;
++
++ for (i = 0; i < 6; i++) {
++ lp->NCSI_Request.DA[i] = 0xFF;
++ lp->NCSI_Respond.DA[i] = 0xFF;
++ lp->NCSI_Respond.SA[i] = 0xFF;
++ lp->NCSI_Request.SA[i] = dev->dev_addr[i];
++ }
++ lp->NCSI_Request.EtherType = 0xF888;
++ lp->NCSI_Request.MC_ID = 0;
++ lp->NCSI_Request.Header_Revision = 0x01;
++ lp->NCSI_Request.Reserved_1 = 0;
++ lp->NCSI_Request.Reserved_2 = 0;
++ lp->NCSI_Request.Reserved_3 = 0;
++ lp->NCSI_Respond.EtherType = 0xF888;
++ lp->NCSI_Respond.MC_ID = 0;
++ lp->NCSI_Respond.Header_Revision = 0x01;
++ lp->NCSI_Respond.Reserved_1 = 0;
++ lp->NCSI_Respond.Reserved_2 = 0;
++ lp->NCSI_Respond.Reserved_3 = 0;
++
++ lp->InstanceID = 0;
++ lp->Payload_Checksum = 0;
++ for (i = 0; i < 4; i++) {
++ lp->Payload_Pad[i] = 0;
++ }
++ for (i = 0; i < 64; i++) {
++ lp->Payload_Data[i] = 0;
++ }
++}
++
++void Calculate_Checksum(struct net_device * dev, unsigned char *buffer_base, int Length)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned int i, CheckSum = 0;
++ unsigned int Data, Data1;
++
++ for (i = 0; i < ((Length - 14) / 2); i++) {
++ Data = buffer_base[i * 2];
++ Data1 = buffer_base[i * 2 + 1];
++ CheckSum += ((Data << 8) + Data1);
++ }
++ lp->Payload_Checksum = (~(CheckSum) + 1); //2's complement
++//Inverse for insert into buffer
++ Data = (lp->Payload_Checksum & 0xFF000000) >> 24;
++ Data1 = (lp->Payload_Checksum & 0x000000FF) << 24;
++ lp->Payload_Checksum = (lp->Payload_Checksum & 0x00FFFF00) + Data + Data1;
++ Data = (lp->Payload_Checksum & 0x00FF0000) >> 8;
++ Data1 = (lp->Payload_Checksum & 0x0000FF00) << 8;
++ lp->Payload_Checksum = (lp->Payload_Checksum & 0xFF0000FF) + Data + Data1;
++}
++
++void copy_data (struct net_device * dev, struct sk_buff * skb, int Length)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++
++ memcpy ((unsigned char *)(skb->data + 30), &lp->Payload_Data, Length);
++ Calculate_Checksum(dev, skb->data + 14, 30 + Length);
++ memcpy ((unsigned char *)(skb->data + 30 + Length), &lp->Payload_Checksum, 4);
++}
++
++void NCSI_Rx (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long status, length, i = 0;
++ volatile RX_DESC *cur_desc;
++
++ncsi_rx:
++ i = 0;
++ cur_desc = &lp->rx_descs[lp->rx_idx];
++ do {
++ status = cur_desc->RXPKT_RDY;
++ i++;
++ } while (!(((status & RX_OWNBY_SOFTWARE) != 0) || (i >= NCSI_LOOP)));
++
++ if (i < NCSI_LOOP) {
++ if (cur_desc->LRS) {
++ length = cur_desc->VDBC;
++ unsigned char *tbuf = (unsigned char *)phys_to_virt(cur_desc->RXBUF_BADR);
++ if (length <= 128 && tbuf[12] == 0x88 && tbuf[13] == 0xF8) {
++ memcpy (&lp->NCSI_Respond, (unsigned char *)phys_to_virt(cur_desc->RXBUF_BADR), length);
++ } else {
++ printk("NCSI_RX: Skip len: %d, proto: %x:%x\n", length, tbuf[12], tbuf[13]);
++ lp->rx_descs[lp->rx_idx].RXPKT_RDY = RX_OWNBY_FTGMAC100;
++ lp->rx_idx = (lp->rx_idx+1)%RXDES_NUM;
++ goto ncsi_rx;
++ }
++
++ }
++ lp->rx_descs[lp->rx_idx].RXPKT_RDY = RX_OWNBY_FTGMAC100;
++ lp->rx_idx = (lp->rx_idx+1)%RXDES_NUM;
++ } else {
++ printk("NCSI_Rx: Failed\n");
++ }
++}
++
++void DeSelect_Package (struct net_device * dev, int Package_ID)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = DESELECT_PACKAGE;
++ Combined_Channel_ID = (Package_ID << 5) + 0x1F; //Internal Channel ID = 0x1F, 0x1F means all channel
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (DESELECT_PACKAGE | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++int Select_Package (struct net_device * dev, int Package_ID)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID, Found = 0;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = SELECT_PACKAGE;
++ Combined_Channel_ID = (Package_ID << 5) + 0x1F; //Internal Channel ID = 0x1F
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = (4 << 8);
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ lp->NCSI_Request.Payload_Length = 4;
++ memset ((void *)lp->Payload_Data, 0, 4);
++ lp->Payload_Data[3] = 1; //Arbitration Disable
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (SELECT_PACKAGE | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ Found = 0;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ Found = 1;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++
++ return Found;
++}
++
++
++void DeSelect_Active_Package (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = DESELECT_PACKAGE;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + 0x1F; //Internal Channel ID = 0x1F, 0x1F means all channel
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (DESELECT_PACKAGE | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++
++int Select_Active_Package (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID, Found = 0;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = SELECT_PACKAGE;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + 0x1F; //Internal Channel ID = 0x1F
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = (4 << 8);
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ lp->NCSI_Request.Payload_Length = 4;
++ memset ((void *)lp->Payload_Data, 0, 4);
++ lp->Payload_Data[3] = 1; //Arbitration Disable
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (SELECT_PACKAGE | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ Found = 0;
++ }
++ else {
++ lp->Retry = 0;
++ Found = 1;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++
++ return Found;
++}
++
++int Clear_Initial_State (struct net_device * dev, int Channel_ID)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID, Found = 0;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = CLEAR_INITIAL_STATE;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + Channel_ID; //Internal Channel ID = 0
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (CLEAR_INITIAL_STATE | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ Found = 0;
++ }
++ else {
++ lp->Retry = 0;
++ Found = 1;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++
++ return Found;
++}
++
++void Get_Version_ID (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = GET_VERSION_ID;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (GET_VERSION_ID | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++void Get_Capabilities (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = GET_CAPABILITIES;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (GET_CAPABILITIES | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ lp->NCSI_Cap.Capabilities_Flags = lp->NCSI_Respond.Payload_Data[0];
++ lp->NCSI_Cap.Broadcast_Packet_Filter_Capabilities = lp->NCSI_Respond.Payload_Data[1];
++ lp->NCSI_Cap.Multicast_Packet_Filter_Capabilities = lp->NCSI_Respond.Payload_Data[2];
++ lp->NCSI_Cap.Buffering_Capabilities = lp->NCSI_Respond.Payload_Data[3];
++ lp->NCSI_Cap.AEN_Control_Support = lp->NCSI_Respond.Payload_Data[4];
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++void Enable_AEN (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = AEN_ENABLE;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = (8 << 8);
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ lp->NCSI_Request.Payload_Length = 8;
++ lp->Payload_Data[3] = 0; //MC ID
++ lp->Payload_Data[7] = 1; //Link Status Change AEN
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (AEN_ENABLE | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++void Get_MAC_Address (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID, i;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = 0x50;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = (8 << 8);
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ lp->NCSI_Request.Payload_Length = 8;
++ lp->Payload_Data[0] = 0x00;
++ lp->Payload_Data[1] = 0x00;
++ lp->Payload_Data[2] = 0x81;
++ lp->Payload_Data[3] = 0x19;
++
++ lp->Payload_Data[4] = 0x00;
++ lp->Payload_Data[5] = 0x00;
++ lp->Payload_Data[6] = 0x1B;
++ lp->Payload_Data[7] = 0x00;
++
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (0x50 | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++
++ // Update MAC Address
++printk("NCSI: MAC ");
++for (i = 0; i < 6; i++)
++ printk("%02X:", lp->NCSI_Respond.Payload_Data[12+i]);
++printk("\n");
++ memcpy(lp->NCSI_Request.SA, &lp->NCSI_Respond.Payload_Data[12], 6);
++ memcpy(dev->dev_addr, &lp->NCSI_Respond.Payload_Data[12], 6);
++
++ /* Update the MAC address */
++ ast_gmac_set_mac(lp, dev->dev_addr);
++}
++
++void Set_MAC_Affinity (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID, i;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = 0x50;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = (60 << 8);
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++
++ lp->NCSI_Request.Payload_Length = 60;
++ memset(lp->Payload_Data, 0x00, 60);
++ lp->Payload_Data[0] = 0x00;
++ lp->Payload_Data[1] = 0x00;
++ lp->Payload_Data[2] = 0x81;
++ lp->Payload_Data[3] = 0x19;
++
++ lp->Payload_Data[4] = 0x00;
++ lp->Payload_Data[5] = 0x01;
++ lp->Payload_Data[6] = 0x07;
++ lp->Payload_Data[7] = 0x00;
++
++ for (i = 0; i < 6; i++) {
++ lp->Payload_Data[8+i] = lp->NCSI_Request.SA[i];
++ }
++
++ lp->Payload_Data[14] = 0x09;
++
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (0x50 | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++void Enable_Set_MAC_Address (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID, i;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = SET_MAC_ADDRESS;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = (8 << 8);
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ lp->NCSI_Request.Payload_Length = 8;
++ for (i = 0; i < 6; i++) {
++ lp->Payload_Data[i] = lp->NCSI_Request.SA[i];
++ }
++ lp->Payload_Data[6] = 1; //MAC Address Num = 1 --> address filter 1, fixed in sample code
++ lp->Payload_Data[7] = UNICAST + 0 + ENABLE_MAC_ADDRESS_FILTER; //AT + Reserved + E
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (SET_MAC_ADDRESS | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++void Enable_Broadcast_Filter (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = ENABLE_BROADCAST_FILTERING;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = (4 << 8);
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ lp->NCSI_Request.Payload_Length = 4;
++ memset ((void *)lp->Payload_Data, 0, 4);
++ lp->Payload_Data[3] = 0x1; //ARP, DHCP, NetBIOS
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (ENABLE_BROADCAST_FILTERING | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++void Disable_VLAN (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = DISABLE_VLAN;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (DISABLE_VLAN | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++void Get_Parameters (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = GET_PARAMETERS;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (GET_PARAMETERS | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++// printk ("Retry: Command = %x, Response_Code = %x, Resonpd.Command = %x, IID = %x, lp->InstanceID = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code, lp->NCSI_Respond.Command, lp->NCSI_Respond.IID, lp->InstanceID);
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ lp->NCSI_Cap.Capabilities_Flags = lp->NCSI_Respond.Payload_Data[0];
++ lp->NCSI_Cap.Broadcast_Packet_Filter_Capabilities = lp->NCSI_Respond.Payload_Data[1];
++ lp->NCSI_Cap.Multicast_Packet_Filter_Capabilities = lp->NCSI_Respond.Payload_Data[2];
++ lp->NCSI_Cap.Buffering_Capabilities = lp->NCSI_Respond.Payload_Data[3];
++ lp->NCSI_Cap.AEN_Control_Support = lp->NCSI_Respond.Payload_Data[4];
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++void Enable_Network_TX (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = ENABLE_CHANNEL_NETWORK_TX;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (ENABLE_CHANNEL_NETWORK_TX | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++void Disable_Network_TX (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = DISABLE_CHANNEL_NETWORK_TX;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + (lp->NCSI_Request.Payload_Length % 4) + 8;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (DISABLE_CHANNEL_NETWORK_TX | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ } else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++void Enable_Channel (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = ENABLE_CHANNEL;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (ENABLE_CHANNEL | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++void Disable_Channel (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = DISABLE_CHANNEL;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = (4 << 8);
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ lp->NCSI_Request.Payload_Length = 4;
++ memset ((void *)lp->Payload_Data, 0, 4);
++ lp->Payload_Data[3] = 0x1; //ALD
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (DISABLE_CHANNEL | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
++
++int Get_Link_Status (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = GET_LINK_STATUS;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = 0;
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (GET_LINK_STATUS | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++ if (lp->NCSI_Respond.Payload_Data[3] & 0x40) {
++ return (lp->NCSI_Respond.Payload_Data[3] & 0x01); //Link Up or Not
++ }
++ else {
++ return 0; //Auto Negotiate did not finish
++ }
++}
++
++void Set_Link (struct net_device * dev)
++{
++ struct ftgmac100_priv *lp = (struct ftgmac100_priv *)dev->priv;
++ unsigned long Combined_Channel_ID;
++ struct sk_buff * skb;
++
++ do {
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ memset(skb->data, 0, TX_BUF_SIZE + 16);
++//TX
++ lp->InstanceID++;
++ lp->NCSI_Request.IID = lp->InstanceID;
++ lp->NCSI_Request.Command = SET_LINK;
++ Combined_Channel_ID = (lp->NCSI_Cap.Package_ID << 5) + lp->NCSI_Cap.Channel_ID;
++ lp->NCSI_Request.Channel_ID = Combined_Channel_ID;
++ lp->NCSI_Request.Payload_Length = (8 << 8);
++ memcpy ((unsigned char *)skb->data, &lp->NCSI_Request, 30);
++ lp->NCSI_Request.Payload_Length = 8;
++ memset ((void *)lp->Payload_Data, 0, 8);
++ lp->Payload_Data[2] = 0x02; //full duplex
++ lp->Payload_Data[3] = 0x04; //100M, auto-disable
++ copy_data (dev, skb, lp->NCSI_Request.Payload_Length);
++ skb->len = 30 + lp->NCSI_Request.Payload_Length + 4;
++ ftgmac100_wait_to_send_packet (skb, dev);
++//RX
++ NCSI_Rx(dev);
++ if (((lp->NCSI_Respond.IID != lp->InstanceID) || (lp->NCSI_Respond.Command != (SET_LINK | 0x80)) || (lp->NCSI_Respond.Response_Code != COMMAND_COMPLETED)) && (lp->Retry != RETRY_COUNT)) {
++ printk ("Retry: Command = %x, Response_Code = %x\n", lp->NCSI_Request.Command, lp->NCSI_Respond.Response_Code);
++ printk ("IID: %x:%x, Command: %x:%x\n", lp->InstanceID, lp->NCSI_Respond.IID, lp->NCSI_Request.Command, lp->NCSI_Respond.Command);
++ lp->Retry++;
++ lp->InstanceID--;
++ }
++ else {
++ lp->Retry = 0;
++ }
++ } while ((lp->Retry != 0) && (lp->Retry <= RETRY_COUNT));
++ lp->Retry = 0;
++}
+
+ static void ftgmac100_reset( struct net_device* dev )
+ {
+@@ -308,64 +1209,71 @@ static void ftgmac100_reset( struct net_device* dev )
+ PRINTK("%s:ftgmac100_reset, phyAddr=0x%x, miiPhyId=0x%04x_%04x\n",
+ dev->name, ids->phyAddr, (ids->miiPhyId >> 16), (ids->miiPhyId & 0xffff));
+
+- if (ids->miiPhyId < 1)
+- return; // Cannot access MAC registers
+-
+- // Check the link speed and duplex.
+- // They are not valid until auto-neg is resolved, which is reg.1 bit[5],
+- // or the link is up, which is reg.1 bit[2].
+-
+- if (ids->phyAddr < 0xff)
+- tmp = ftgmac100_read_phy_register(dev->base_addr, ids->phyAddr, 0x1);
+- else tmp = 0;
+-
+- if (0==(tmp & (1u<<5 | 1u<<2)) || ids->phyAddr >= 0xff) {
+- // No PHY chip, or link has not negotiated.
+- speed = PHY_SPEED_100M;
+- duplex = 1;
+- netif_carrier_off(dev);
+- }
+- else if (((ids->miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8201EL)) {
+- tmp = ftgmac100_read_phy_register(dev->base_addr, priv->ids.phyAddr, 0x00);
+- duplex = (tmp & 0x0100) ? 1 : 0;
+- speed = (tmp & 0x2000) ? PHY_SPEED_100M : PHY_SPEED_10M;
+- }
+- else if (((ids->miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_MARVELL) ||
+- ((ids->miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8211)) {
+- // Use reg.17_0.bit[15:13] for {speed[1:0], duplex}.
+- tmp = ftgmac100_read_phy_register(dev->base_addr, ids->phyAddr, 0x11);
+- duplex = (tmp & PHY_DUPLEX_mask)>>13;
+- speed = (tmp & PHY_SPEED_mask)>>14;
+- netif_carrier_on(dev);
+- }
+- else if (priv->ids.miiPhyId == PHYID_BCM54612E
+- || priv->ids.miiPhyId == PHYID_BCM54616S) {
+- // Get link status
+- // First Switch shadow register selector
+- ftgmac100_write_phy_register(dev->base_addr, priv->ids.phyAddr, 0x1C, 0x2000);
+- tmp = ftgmac100_read_phy_register(dev->base_addr, priv->ids.phyAddr, 0x1C);
+- if ( (tmp & 0x0080) == 0x0080 )
+- duplex = 0;
+- else
+- duplex = 1;
+-
+- switch(tmp & 0x0018) {
+- case 0x0000:
+- speed = PHY_SPEED_1G; break;
+- case 0x0008:
+- speed = PHY_SPEED_100M; break;
+- case 0x0010:
+- speed = PHY_SPEED_10M; break;
+- default:
+- speed = PHY_SPEED_100M;
+- }
++ if ((priv->NCSI_support == 1) || (priv->INTEL_NCSI_EVA_support == 1)) {
++ ids->miiPhyId = 0xFFFF;
++ // NCSI mode always is 100M and full duplex
++ duplex = 1;
++ speed = PHY_SPEED_100M;
++ } else {
++ if (ids->miiPhyId < 1)
++ return; // Cannot access MAC registers
++
++ // Check the link speed and duplex.
++ // They are not valid until auto-neg is resolved, which is reg.1 bit[5],
++ // or the link is up, which is reg.1 bit[2].
++
++ if (ids->phyAddr < 0xff)
++ tmp = ftgmac100_read_phy_register(dev->base_addr, ids->phyAddr, 0x1);
++ else tmp = 0;
++
++ if (0==(tmp & (1u<<5 | 1u<<2)) || ids->phyAddr >= 0xff) {
++ // No PHY chip, or link has not negotiated.
++ speed = PHY_SPEED_100M;
++ duplex = 1;
++ netif_carrier_off(dev);
+ }
+- else {
+- // Assume Broadcom BCM5221. Use reg.18 bits [1:0] for {100Mb/s, fdx}.
+- tmp = ftgmac100_read_phy_register(dev->base_addr, ids->phyAddr, 0x18);
+- duplex = (tmp & 0x0001);
+- speed = (tmp & 0x0002) ? PHY_SPEED_100M : PHY_SPEED_10M;
+- }
++ else if (((ids->miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8201EL)) {
++ tmp = ftgmac100_read_phy_register(dev->base_addr, priv->ids.phyAddr, 0x00);
++ duplex = (tmp & 0x0100) ? 1 : 0;
++ speed = (tmp & 0x2000) ? PHY_SPEED_100M : PHY_SPEED_10M;
++ }
++ else if (((ids->miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_MARVELL) ||
++ ((ids->miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8211)) {
++ // Use reg.17_0.bit[15:13] for {speed[1:0], duplex}.
++ tmp = ftgmac100_read_phy_register(dev->base_addr, ids->phyAddr, 0x11);
++ duplex = (tmp & PHY_DUPLEX_mask)>>13;
++ speed = (tmp & PHY_SPEED_mask)>>14;
++ netif_carrier_on(dev);
++ }
++ else if (priv->ids.miiPhyId == PHYID_BCM54612E
++ || priv->ids.miiPhyId == PHYID_BCM54616S) {
++ // Get link status
++ // First Switch shadow register selector
++ ftgmac100_write_phy_register(dev->base_addr, priv->ids.phyAddr, 0x1C, 0x2000);
++ tmp = ftgmac100_read_phy_register(dev->base_addr, priv->ids.phyAddr, 0x1C);
++ if ( (tmp & 0x0080) == 0x0080 )
++ duplex = 0;
++ else
++ duplex = 1;
++
++ switch(tmp & 0x0018) {
++ case 0x0000:
++ speed = PHY_SPEED_1G; break;
++ case 0x0008:
++ speed = PHY_SPEED_100M; break;
++ case 0x0010:
++ speed = PHY_SPEED_10M; break;
++ default:
++ speed = PHY_SPEED_100M;
++ }
++ }
++ else {
++ // Assume Broadcom BCM5221. Use reg.18 bits [1:0] for {100Mb/s, fdx}.
++ tmp = ftgmac100_read_phy_register(dev->base_addr, ids->phyAddr, 0x18);
++ duplex = (tmp & 0x0001);
++ speed = (tmp & 0x0002) ? PHY_SPEED_100M : PHY_SPEED_10M;
++ }
++ }// NCSI_Check
+
+ if (speed == PHY_SPEED_1G) {
+ // Set SPEED_100_bit too, for consistency.
+@@ -385,9 +1293,9 @@ static void ftgmac100_reset( struct net_device* dev )
+ }
+ if (duplex)
+ priv->maccr_val |= FULLDUP_bit;
+- else
++ else
+ priv->maccr_val &= ~FULLDUP_bit;
+-
++
+ outl( SW_RST_bit, dev->base_addr + MACCR_REG );
+
+ #ifdef not_complete_yet
+@@ -419,6 +1327,7 @@ static void ftgmac100_enable( struct net_device *dev )
+ unsigned int rfifo_rsize; //Richard
+ unsigned int tfifo_rsize; //Richard
+ unsigned int rxbuf_size;
++ unsigned long Package_Found = 0, Channel_Found = 0, Re_Send = 0, Link_Status;
+
+ rxbuf_size = RX_BUF_SIZE & 0x3fff;
+ outl( rxbuf_size , dev->base_addr + RBSR_REG); //for NC Body
+@@ -475,7 +1384,7 @@ static void ftgmac100_enable( struct net_device *dev )
+
+ /// enable trans/recv,...
+ outl(priv->maccr_val, dev->base_addr + MACCR_REG );
+-#if 0
++
+ //NCSI Start
+ //DeSelect Package/ Select Package
+ if ((priv->NCSI_support == 1) || (priv->INTEL_NCSI_EVA_support == 1)) {
+@@ -491,16 +1400,18 @@ static void ftgmac100_enable( struct net_device *dev )
+ }
+ if (Package_Found != 0) {
+ //Initiali State
+- for (i = 0; i < 2; i++) { //Suppose 2 channels in current version, You could modify it to 0x1F to support 31 channels
+- Channel_Found = Clear_Initial_State(dev, i);
++ for (i = 0; i < 1; i++) { //Suppose 2 channels in current version, You could modify it to 0x1F to support 31 channels
++ //Channel_Found = Clear_Initial_State(dev, i);
++ Channel_Found = 1;
+ if (Channel_Found == 1) {
+ priv->NCSI_Cap.Channel_ID = i;
+ printk ("Found NCSI Network Controller at (%d, %d)\n", priv->NCSI_Cap.Package_ID, priv->NCSI_Cap.Channel_ID);
++ Get_MAC_Address(dev);
++ Set_MAC_Affinity(dev);
++ Clear_Initial_State(dev, i);
+ //Get Version and Capabilities
+ Get_Version_ID(dev);
+ Get_Capabilities(dev);
+-//Configuration
+- Select_Active_Package(dev);
+ //Set MAC Address
+ Enable_Set_MAC_Address(dev);
+ //Enable Broadcast Filter
+@@ -508,16 +1419,18 @@ static void ftgmac100_enable( struct net_device *dev )
+ //Disable VLAN
+ Disable_VLAN(dev);
+ //Enable AEN
+- Enable_AEN(dev);
++ //Enable_AEN(dev);
+ //Get Parameters
+ Get_Parameters(dev);
+-//Enable TX
++//Enable TX
+ Enable_Network_TX(dev);
+ //Enable Channel
+ Enable_Channel(dev);
+ //Get Link Status
+ Re_Get_Link_Status:
+- Link_Status = Get_Link_Status(dev);
++ //TODO: Workaround for CX4 Link status issue
++ //Link_Status = Get_Link_Status(dev);
++ Link_Status = LINK_UP;
+ if (Link_Status == LINK_UP) {
+ printk ("Using NCSI Network Controller (%d, %d)\n", priv->NCSI_Cap.Package_ID, priv->NCSI_Cap.Channel_ID);
+ netif_carrier_on(dev);
+@@ -528,7 +1441,7 @@ Re_Get_Link_Status:
+ netif_carrier_off(dev);
+ goto Re_Get_Link_Status;
+ }
+-//Disable TX
++//Disable TX
+ Disable_Network_TX(dev);
+ //Disable Channel
+ // Disable_Channel(dev);
+@@ -537,9 +1450,19 @@ Re_Get_Link_Status:
+ }
+ }
+ }
++ // Enable Interrupts
++ outl(
++ AHB_ERR_bit |
++ TPKT_LOST_bit |
++ TPKT2E_bit |
++ RXBUF_UNAVA_bit |
++ RPKT2B_bit
++ ,dev->base_addr + IER_REG
++ );
++
++ return;
+ }
+ /* now, enable interrupts */
+-#endif
+ if (((priv->ids.miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_MARVELL) ||
+ ((priv->ids.miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8211)) {
+ outl(
+@@ -564,7 +1487,7 @@ Re_Get_Link_Status:
+ );
+ }
+ else if (priv->ids.miiPhyId == PHYID_BCM54612E
+- || priv->ids.miiPhyId == PHYID_BCM54616S) {
++ || priv->ids.miiPhyId == PHYID_BCM54616S) {
+ outl(
+ // no link PHY link status pin PHYSTS_CHG_bit |
+ AHB_ERR_bit |
+@@ -583,7 +1506,7 @@ Re_Get_Link_Status:
+ RXBUF_UNAVA_bit |
+ RPKT2B_bit
+ ,dev->base_addr + IER_REG
+- );
++ );
+ }
+ }
+
+@@ -619,7 +1542,7 @@ static void aspeed_mac_timer(unsigned long data)
+ speed = (tmp & PHY_SPEED_mask)>>14;
+ }
+ else if (priv->ids.miiPhyId == PHYID_BCM54612E
+- || priv->ids.miiPhyId == PHYID_BCM54616S) {
++ || priv->ids.miiPhyId == PHYID_BCM54616S) {
+ // Get link status
+ // First Switch shadow register selector
+ ftgmac100_write_phy_register(dev->base_addr, priv->ids.phyAddr, 0x1C, 0x2000);
+@@ -628,23 +1551,23 @@ static void aspeed_mac_timer(unsigned long data)
+ duplex = 0;
+ else
+ duplex = 1;
+-
++
+ switch(tmp & 0x0018) {
+ case 0x0000:
+- speed = PHY_SPEED_1G;
+-
++ speed = PHY_SPEED_1G;
++
+ break;
+- case 0x0008:
+- speed = PHY_SPEED_100M;
+-
++ case 0x0008:
++ speed = PHY_SPEED_100M;
++
+ break;
+- case 0x0010:
+- speed = PHY_SPEED_10M;
+-
++ case 0x0010:
++ speed = PHY_SPEED_10M;
++
+ break;
+ default:
+ speed = PHY_SPEED_100M;
+- }
++ }
+ }
+ else {
+ duplex = 1; speed = PHY_SPEED_100M;
+@@ -730,27 +1653,26 @@ static int ftgmac100_wait_to_send_packet( struct sk_buff * skb, struct net_devic
+ PRINTK3("%s:ftgmac100_wait_to_send_packet, skb=%x\n", dev->name, skb);
+ cur_desc = &priv->tx_descs[priv->tx_idx];
+
+-#ifdef not_complete_yet
+- if (cur_desc->TXDMA_OWN != TX_OWNBY_SOFTWARE) /// no empty transmit descriptor
++#ifdef not_complete_yet
++ if (cur_desc->TXDMA_OWN != TX_OWNBY_SOFTWARE) /// no empty transmit descriptor
+ {
+ DO_PRINT("no empty transmit descriptor\n");
+ DO_PRINT("jiffies = %d\n", jiffies);
+ priv->stats.tx_dropped++;
+- netif_stop_queue(dev); /// waiting to do:
++ netif_stop_queue(dev); /// waiting to do:
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+
+ return 1;
+ }
+ #endif /* end_of_not */
+
+- if (cur_desc->TXDMA_OWN != TX_OWNBY_SOFTWARE) /// no empty transmit descriptor
++ if (cur_desc->TXDMA_OWN != TX_OWNBY_SOFTWARE) /// no empty transmit descriptor
+ {
+ DO_PRINT("no empty TX descriptor:0x%x:0x%x\n",
+ (unsigned int)cur_desc,((unsigned int *)cur_desc)[0]);
+ priv->stats.tx_dropped++;
+- netif_stop_queue(dev); /// waiting to do:
++ netif_stop_queue(dev); /// waiting to do:
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+-
+ return 1;
+ }
+ priv->tx_skbuff[priv->tx_idx] = skb;
+@@ -803,18 +1725,18 @@ static int ftgmac100_ringbuf_alloc(struct ftgmac100_priv *priv)
+ int i;
+ struct sk_buff *skb;
+
+- priv->rx_descs = dma_alloc_coherent(priv->dev,
+- sizeof(RX_DESC)*RXDES_NUM,
++ priv->rx_descs = dma_alloc_coherent(priv->dev,
++ sizeof(RX_DESC)*RXDES_NUM,
+ &priv->rx_descs_dma, GFP_KERNEL);
+
+ if(!priv->rx_descs)
+ return -ENOMEM;
+-
++
+ memset(priv->rx_descs, 0, sizeof(RX_DESC)*RXDES_NUM);
+ priv->rx_descs[RXDES_NUM-1].EDORR = 1;
+
+ for (i=0; i<RXDES_NUM; i++) {
+- dma_addr_t mapping;
++ dma_addr_t mapping;
+ skb = dev_alloc_skb(RX_BUF_SIZE + NET_IP_ALIGN);
+ skb_reserve(skb, NET_IP_ALIGN);
+
+@@ -829,8 +1751,8 @@ static int ftgmac100_ringbuf_alloc(struct ftgmac100_priv *priv)
+ priv->rx_descs[i].VIR_RXBUF_BADR = skb->data;
+ }
+
+- priv->tx_descs = dma_alloc_coherent(priv->dev,
+- sizeof(TX_DESC)*TXDES_NUM,
++ priv->tx_descs = dma_alloc_coherent(priv->dev,
++ sizeof(TX_DESC)*TXDES_NUM,
+ &priv->tx_descs_dma ,GFP_KERNEL);
+
+ if(!priv->tx_descs)
+@@ -838,7 +1760,7 @@ static int ftgmac100_ringbuf_alloc(struct ftgmac100_priv *priv)
+
+ memset((void*)priv->tx_descs, 0, sizeof(TX_DESC)*TXDES_NUM);
+ priv->tx_descs[TXDES_NUM-1].EDOTR = 1; // is last descriptor
+-
++
+ }
+
+ #if FTMAC100_DEBUG > 2
+@@ -918,20 +1840,14 @@ static void ftgmac100_phy_configure(struct net_device* dev)
+ }
+ break;
+ case PHYID_VENDOR_BROADCOM:
+- switch (priv->ids.miiPhyId) {
+- case PHYID_BCM54612E:
+- case PHYID_BCM54616S:
+- ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x1C, 0x8C00); // Disable GTXCLK Clock Delay Enable
+- ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x18, 0xF0E7); // Disable RGMII RXD to RXC Skew
+- break;
+- case PHYID_BCM5221A4:
+- default:
+- tmp = ftgmac100_read_phy_register(ioaddr, priv->ids.phyAddr, 0x1b);
+- tmp |= 0x0004;
+- ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x1b, (u16) tmp);
+- break;
+- }
+- break;
++ tmp = ftgmac100_read_phy_register(ioaddr, priv->ids.phyAddr, 0x1b);
++ tmp |= 0x0004;
++ ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x1b, (u16) tmp);
++ break;
++ case PHYID_VENDOR_BCM5461X:
++ ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x1C, 0x8C00); // Disable GTXCLK Clock Delay Enable
++ ftgmac100_write_phy_register(ioaddr, priv->ids.phyAddr, 0x18, 0xF0E7); // Disable RGMII RXD to RXC Skew
++ break;
+ }
+ }
+
+@@ -960,26 +1876,26 @@ static void ftgmac100_timeout (struct net_device *dev)
+ }
+
+
+-static void ftgmac100_free_tx (struct net_device *dev)
++static void ftgmac100_free_tx (struct net_device *dev)
+ {
+ struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
+- int entry = priv->old_tx % TXDES_NUM;
++ int entry = priv->old_tx % TXDES_NUM;
+ unsigned long flags = 0;
+-
++
+ spin_lock_irqsave(&priv->tx_lock,flags);
+-
++
+ /* Free used tx skbuffs */
+
+ while ((priv->tx_descs[entry].TXDMA_OWN == TX_OWNBY_SOFTWARE) && (priv->tx_skbuff[entry] != NULL)) {
+ struct sk_buff *skb;
+-
++
+ skb = priv->tx_skbuff[entry];
+ dev_kfree_skb_any (skb);
+ priv->tx_skbuff[entry] = 0;
+ entry = (entry + 1) % TXDES_NUM;
+ priv->tx_free++;
+ }
+-
++
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+ priv->old_tx = entry;
+ if ((netif_queue_stopped(dev)) && (priv->tx_free > 0)) {
+@@ -1295,7 +2211,7 @@ static irqreturn_t ftgmac100_interrupt(int irq, void * dev_id, struct pt_regs *
+ DO_PRINT("PHYSTS_CHG \n");
+ // Is this interrupt for changes of the PHYLINK pin?
+ // Note: PHYLINK is optional; not all boards connect it.
+- if (((priv->ids.miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_MARVELL) ||
++ if (((priv->ids.miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_MARVELL) ||
+ ((priv->ids.miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8211))
+ {
+ tmp = ftgmac100_read_phy_register(ioaddr, priv->ids.phyAddr, 0x13);
+@@ -1312,7 +2228,7 @@ static irqreturn_t ftgmac100_interrupt(int irq, void * dev_id, struct pt_regs *
+ tmp &= 0x000e;
+ }
+ else if (priv->ids.miiPhyId == PHYID_BCM54612E
+- || priv->ids.miiPhyId == PHYID_BCM54616S) {
++ || priv->ids.miiPhyId == PHYID_BCM54616S) {
+ tmp = ftgmac100_read_phy_register(ioaddr, priv->ids.phyAddr, 0x1A);
+ PRINTK("%s: PHY interrupt status, read_phy_reg(0x1A) = 0x%04x\n",
+ dev->name, tmp);
+@@ -1403,10 +2319,10 @@ static irqreturn_t ftgmac100_interrupt(int irq, void * dev_id, struct pt_regs *
+ . Get the current statistics.
+ . This may be called with the card open or closed.
+ .-------------------------------------------------------------*/
+-static struct net_device_stats* ftgmac100_query_statistics(struct net_device *dev)
++static struct net_device_stats* ftgmac100_query_statistics(struct net_device *dev)
+ {
+ struct ftgmac100_priv *priv = (struct ftgmac100_priv *)dev->priv;
+-
++
+ return &priv->stats;
+ }
+
+@@ -1416,7 +2332,7 @@ static struct net_device_stats* ftgmac100_query_statistics(struct net_device *de
+ // Finds the CRC32 of a set of bytes.
+ // Again, from Peter Cammaert's code.
+ // --------------------------------------------------------------------
+-static int crc32( char * s, int length )
++static int crc32( char * s, int length )
+ {
+ /* indices */
+ int perByte;
+@@ -1446,7 +2362,7 @@ static int crc32( char * s, int length )
+ . packets before they take up memory.
+ */
+
+-static void ftgmac100_setmulticast( struct net_device *dev, int count, struct dev_mc_list * addrs )
++static void ftgmac100_setmulticast( struct net_device *dev, int count, struct dev_mc_list * addrs )
+ {
+ struct dev_mc_list * cur_addr;
+ int crc_val;
+@@ -1455,12 +2371,12 @@ static void ftgmac100_setmulticast( struct net_device *dev, int count, struct de
+ struct AstMacHwConfig* ids = &priv->ids;
+ unsigned long Combined_Channel_ID, i;
+ struct sk_buff * skb;
+- cur_addr = addrs;
++ cur_addr = addrs;
+
+ //TX
+-#if 0
++#if 1
+ if (priv->NCSI_support == 1) {
+- skb = dev_alloc_skb (TX_BUF_SIZE + 16);
++ skb = dev_alloc_skb (TX_BUF_SIZE + 16);
+ priv->InstanceID++;
+ priv->NCSI_Request.IID = priv->InstanceID;
+ priv->NCSI_Request.Command = SET_MAC_ADDRESS;
+@@ -1597,7 +2513,7 @@ static int ast_gmac_stop(struct net_device *dev)
+ priv->rx_descs = NULL; priv->rx_descs_dma = 0;
+ priv->tx_descs = NULL; priv->tx_descs_dma = 0;
+ priv->tx_buf = NULL; priv->tx_buf_dma = 0;
+-
++
+
+ return 0;
+ }
+@@ -1651,10 +2567,10 @@ static int ftgmac100_open(struct net_device *netdev)
+ ftgmac100_reset(netdev);
+ ftgmac100_enable(netdev);
+
+- if (((priv->ids.miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_BROADCOM) ||
++ if (((priv->ids.miiPhyId & PHYID_VENDOR_MASK) == PHYID_VENDOR_BROADCOM) ||
+ ((priv->ids.miiPhyId & PHYID_VENDOR_MODEL_MASK) == PHYID_RTL8201EL) ||
+ (priv->ids.miiPhyId == PHYID_BCM54612E) ||
+- (priv->ids.miiPhyId == PHYID_BCM54616S)) {
++ (priv->ids.miiPhyId == PHYID_BCM54616S)) {
+
+ init_timer(&priv->timer);
+ priv->timer.data = (unsigned long)netdev;
+@@ -1702,7 +2618,7 @@ static int __init ast_gmac_probe(struct platform_device *pdev)
+
+
+ // SET_ETHTOOL_OPS(netdev, &ftgmac100_ethtool_ops);
+-
++
+ #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30))
+ netdev->netdev_ops = &ftgmac100_netdev_ops;
+ #else
+@@ -1715,13 +2631,12 @@ static int __init ast_gmac_probe(struct platform_device *pdev)
+ netdev->hard_start_xmit = ftgmac100_wait_to_send_packet;
+ netdev->tx_timeout = ftgmac100_timeout;
+ netdev->get_stats = ftgmac100_query_statistics;
+-//#ifdef HAVE_MULTICAST
+-#if 0
++#ifdef HAVE_MULTICAST
+ netdev->set_multicast_list = &ftgmac100_set_multicast_list;
+ #endif
+
+ #endif
+-
++
+
+ #ifdef CONFIG_AST_NPAI
+ // netdev->features = NETIF_F_GRO;
+@@ -1734,12 +2649,12 @@ static int __init ast_gmac_probe(struct platform_device *pdev)
+ priv = netdev_priv(netdev);
+ priv->netdev = netdev;
+ priv->dev = &pdev->dev;
+-
++
+
+ priv->ids.macId = pdev->id;
+-
++
+ priv->NCSI_support = ast_eth_data->NCSI_support;
+- priv->INTEL_NCSI_EVA_support= ast_eth_data->INTEL_NCSI_EVA_support;
++ priv->INTEL_NCSI_EVA_support= ast_eth_data->INTEL_NCSI_EVA_support;
+ spin_lock_init(&priv->tx_lock);
+
+ #if 0
+@@ -1833,7 +2748,7 @@ err_ioremap:
+ err_req_mem:
+ // netif_napi_del(&priv->napi);
+ platform_set_drvdata(pdev, NULL);
+-err_netdev:
++err_netdev:
+ free_netdev(netdev);
+ err_alloc_etherdev:
+ return err;
+diff --git a/drivers/net/ftgmac100_26.h b/drivers/net/ftgmac100_26.h
+index 0d47024..2493111 100644
+--- a/drivers/net/ftgmac100_26.h
++++ b/drivers/net/ftgmac100_26.h
+@@ -1,16 +1,16 @@
+ /********************************************************************************
+ * File Name : ftgmac100_26.h
+-*
++*
+ * Copyright (C) 2012-2020 ASPEED Technology Inc.
+-* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ ********************************************************************************/
+ // --------------------------------------------------------------------
+
+@@ -78,7 +78,7 @@
+
+
+ // --------------------------------------------------------------------
+-// APTC_REG
++// APTC_REG
+ // --------------------------------------------------------------------
+
+
+@@ -99,18 +99,18 @@ typedef struct
+ #define PHY_READ_bit (1UL<<26)
+ #define PHY_WRITE_bit (1UL<<27)
+ // --------------------------------------------------------------------
+-// PHYCR_REG
++// PHYCR_REG
+ // --------------------------------------------------------------------
+ #define PHY_AUTO_OK_bit (1UL<<5)
+ // --------------------------------------------------------------------
+-// PHY INT_STAT_REG
++// PHY INT_STAT_REG
+ // --------------------------------------------------------------------
+ #define PHY_SPEED_CHG_bit (1UL<<14)
+ #define PHY_DUPLEX_CHG_bit (1UL<<13)
+ #define PHY_LINK_CHG_bit (1UL<<10)
+ #define PHY_AUTO_COMP_bit (1UL<<11)
+ // --------------------------------------------------------------------
+-// PHY SPE_STAT_REG
++// PHY SPE_STAT_REG
+ // --------------------------------------------------------------------
+ #define PHY_RESOLVED_bit (1UL<<11)
+ #define PHY_SPEED_mask 0xC000
+@@ -269,7 +269,7 @@ typedef struct {
+ unsigned short Reserved_5;
+ unsigned short Response_Code;
+ unsigned short Reason_Code;
+- unsigned char Payload_Data[64];
++ unsigned char Payload_Data[128];
+ } NCSI_Response_Packet;
+
+ //Standard Response Code
+@@ -365,30 +365,30 @@ typedef struct
+ u32 FRS:1;
+ u32 EDORR:1;
+ u32 RXPKT_RDY:1; // 1 ==> owned by FTMAC100, 0 ==> owned by software
+-
++
+ // RXDES1
+ u32 VLAN_TAGC:16;
+ u32 Reserved4:4;
+ u32 PROTL_TYPE:2;
+ u32 LLC_PKT:1;
+ u32 DF:1;
+- u32 VLAN_AVA:1;
++ u32 VLAN_AVA:1;
+ u32 TCPCS_FAIL:1;
+ u32 UDPCS_FAIL:1;
+ u32 IPCS_FAIL:1;
+ u32 Reserved5:4;
+-
++
+ // RXDES2
+ u32 Reserved6:32;
+-
++
+ // RXDES3
+ u32 RXBUF_BADR;
+-
++
+ u32 VIR_RXBUF_BADR; // not defined, the virtual address of receive buffer is placed here
+-
+- u32 RESERVED;
+- u32 RESERVED1;
+- u32 RESERVED2;
++
++ u32 RESERVED;
++ u32 RESERVED1;
++ u32 RESERVED2;
+ }RX_DESC;
+
+
+@@ -405,7 +405,7 @@ typedef struct
+ u32 FTS:1;
+ u32 EDOTR:1;
+ u32 TXDMA_OWN:1;
+-
++
+ // TXDES1
+ u32 VLAN_TAGC:16;
+ u32 INS_VLAN:1;
+@@ -416,8 +416,8 @@ typedef struct
+ u32 LLC_PKT:1;
+ u32 Reserved6:7;
+ u32 TX2FIC:1;
+- u32 TXIC:1;
+-
++ u32 TXIC:1;
++
+ // TXDES2
+ u32 Reserved7:32;
+
+@@ -427,8 +427,8 @@ typedef struct
+ u32 VIR_TXBUF_BADR; // Reserve, the virtual address of transmit buffer is placed here
+
+ u32 RESERVED;
+- u32 RESERVED1;
+- u32 RESERVED2;
++ u32 RESERVED1;
++ u32 RESERVED2;
+
+ }TX_DESC;
+
+@@ -450,7 +450,7 @@ typedef struct
+ // --------------------------------------------------------------------
+
+
+-//#define RXDES_NUM 64//64 // we defined 32 descriptor for OTG issue
++//#define RXDES_NUM 64//64 // we defined 32 descriptor for OTG issue
+ #define RXDES_NUM 32
+
+ #define RX_BUF_SIZE 1536
+@@ -464,6 +464,7 @@ typedef struct
+ #define PHYID_REVISION_MASK 0x0000000f
+ #define PHYID_VENDOR_MARVELL 0x01410c00
+ #define PHYID_VENDOR_BROADCOM 0x00406000
++#define PHYID_VENDOR_BCM5461X 0x03625c00
+ #define PHYID_VENDOR_REALTEK 0x001cc800
+
+ #define PHYID_BCM5221A4 0x004061e4
+@@ -521,7 +522,7 @@ struct ftgmac100_priv {
+ int tx_idx;
+ int old_tx;
+ struct sk_buff *tx_skbuff[TXDES_NUM];
+-
++
+ int maccr_val;
+ struct timer_list timer;
+ u32 GigaBit_MAHT0;
+@@ -533,7 +534,7 @@ struct ftgmac100_priv {
+ NCSI_Capability NCSI_Cap;
+ unsigned int InstanceID;
+ unsigned int Retry;
+- unsigned char Payload_Data[16];
++ unsigned char Payload_Data[64];
+ unsigned char Payload_Pad[4];
+ unsigned long Payload_Checksum;
+ int tx_free;
+@@ -575,7 +576,7 @@ struct ftgmac100_priv {
+ #define STOP_DONE (1 << 4)
+
+
+-
++
+ #endif /* _SMC_91111_H_ */
+
+
+diff --git a/drivers/rtc/rtc-aspeed.c b/drivers/rtc/rtc-aspeed.c
+index 477032e..de9e995 100644
+--- a/drivers/rtc/rtc-aspeed.c
++++ b/drivers/rtc/rtc-aspeed.c
+@@ -7,11 +7,11 @@
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+@@ -67,8 +67,16 @@ ast_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+ {
+ struct ast_rtc *ast_rtc = dev_get_drvdata(dev);
+ pr_debug("cmd = 0x%08x, arg = 0x%08lx\n", cmd, arg);
+-
++
+ switch (cmd) {
++ case RTC_SET_TIME:
++ case RTC_RD_TIME:
++ case RTC_ALM_READ:
++ case RTC_ALM_SET:
++ {
++ // use rtc-dev.c fallback
++ return -ENOIOCTLCMD;
++ }
+ case RTC_AIE_ON: /* alarm on */
+ {
+ rtc_write(ast_rtc->base, rtc_read(ast_rtc->base, RTC_CONTROL) | ENABLE_ALL_ALARM, RTC_CONTROL);
+@@ -105,7 +113,7 @@ ast_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+ default:
+ return -ENOTTY;
+ }
+-
++
+ return 0;
+ }
+
+@@ -122,7 +130,7 @@ ast_rtc_get_time(struct device *dev, struct rtc_time *rtc_tm)
+
+ reg_time = rtc_read(ast_rtc->base, RTC_CNTR_STS_1);
+ reg_date = rtc_read(ast_rtc->base, RTC_CNTR_STS_2);
+-
++
+ spin_unlock_irqrestore(&ast_rtc->lock, flags);
+
+ rtc_tm->tm_year = GET_CENT_VAL(reg_date)*1000 | GET_YEAR_VAL(reg_date);
+@@ -132,7 +140,7 @@ ast_rtc_get_time(struct device *dev, struct rtc_time *rtc_tm)
+ rtc_tm->tm_hour = GET_HOUR_VAL(reg_time);
+ rtc_tm->tm_min = GET_MIN_VAL(reg_time);
+ rtc_tm->tm_sec = GET_SEC_VAL(reg_time);
+-
++
+ pr_debug("read time %02x.%02x.%02x %02x/%02x/%02x\n",
+ rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday,
+ rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec);
+@@ -155,7 +163,7 @@ ast_rtc_set_time(struct device *dev, struct rtc_time *tm)
+
+ /* set hours */
+ reg_time = SET_DAY_VAL(tm->tm_mday) | SET_HOUR_VAL(tm->tm_hour) | SET_MIN_VAL(tm->tm_min) | SET_SEC_VAL(tm->tm_sec);
+-
++
+ /* set century */
+ /* set mon */
+ reg_date = SET_CENT_VAL(tm->tm_year / 1000) | SET_YEAR_VAL(tm->tm_year % 1000) | SET_MON_VAL(tm->tm_mon);
+@@ -166,10 +174,10 @@ ast_rtc_set_time(struct device *dev, struct rtc_time *tm)
+ rtc_write(ast_rtc->base, reg_date, RTC_CNTR_STS_2);
+
+ rtc_write(ast_rtc->base, rtc_read(ast_rtc->base, RTC_CONTROL) &~RTC_LOCK , RTC_CONTROL);
+-
++
+ spin_unlock_irqrestore(&ast_rtc->lock, flags);
+
+- return 0;
++ return 0;
+ }
+ static int
+ ast_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+@@ -183,7 +191,7 @@ ast_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+ alarm_reg = rtc_read(ast_rtc->base, RTC_ALARM);
+ spin_unlock_irqrestore(&ast_rtc->lock, flags);
+
+-//DAY
++//DAY
+ alm_tm->tm_mday = GET_DAY_VAL(alarm_reg);
+
+ //HR
+@@ -221,7 +229,7 @@ ast_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+ if (tm->tm_mday <= 31 && tm->tm_mday >= 1) {
+ reg_alarm |= SET_DAY_VAL(tm->tm_mday);
+ }
+-
++
+ //HR
+ /* set ten hours */
+ if (tm->tm_hour <= 23 && tm->tm_hour >= 0) {
+@@ -245,8 +253,8 @@ ast_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+ spin_lock_irqsave(&ast_rtc->lock, flags);
+
+ rtc_write(ast_rtc->base, reg_alarm, RTC_ALARM);
+-
+- if(alarm->enabled)
++
++ if(alarm->enabled)
+ rtc_write(ast_rtc->base, reg_alarm, RTC_CONTROL);
+ else
+ rtc_write(ast_rtc->base, reg_alarm, RTC_CONTROL);
+@@ -366,14 +374,14 @@ static int __init ast_rtc_probe(struct platform_device *pdev)
+ ret = -EBUSY;
+ goto free_rtc;
+ }
+-
++
+ ast_rtc->base = ioremap(res->start, resource_size(res));
+ if (!ast_rtc->base) {
+ dev_err(&pdev->dev, "cannot map SocleDev registers\n");
+ ret = -ENOMEM;
+ goto release_mem;
+ }
+-
++
+ pr_debug("base = 0x%p, irq = %d\n", ast_rtc->base, ast_rtc->irq);
+
+ rtc_dev = rtc_device_register(pdev->name, &pdev->dev, &ast_rtcops, THIS_MODULE);
+@@ -381,7 +389,7 @@ static int __init ast_rtc_probe(struct platform_device *pdev)
+ ret = PTR_ERR(rtc_dev);
+ goto unmap;
+ }
+-
++
+ ast_rtc->res = res;
+ ast_rtc->rtc_dev = rtc_dev;
+ spin_lock_init(&ast_rtc->lock);
+@@ -406,7 +414,7 @@ static int __init ast_rtc_probe(struct platform_device *pdev)
+ printk("no need to enable RTC \n");
+
+ spin_unlock_irq(&ast_rtc->lock);
+-
++
+ /* register ISR */
+ ret = request_irq(ast_rtc->irq, ast_rtc_interrupt, IRQF_DISABLED, dev_name(&rtc_dev->dev), ast_rtc);
+ if (ret) {
+diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
+index a181ccf..f16da59 100644
+--- a/drivers/serial/8250.c
++++ b/drivers/serial/8250.c
+@@ -38,6 +38,7 @@
+ #include <linux/serial_8250.h>
+ #include <linux/nmi.h>
+ #include <linux/mutex.h>
++#include <linux/gpio.h>
+
+ #include <asm/io.h>
+ #include <asm/irq.h>
+@@ -59,6 +60,8 @@ static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
+
+ static struct uart_driver serial8250_reg;
+
++DECLARE_WAIT_QUEUE_HEAD(thre_wait);
++
+ static int serial_index(struct uart_port *port)
+ {
+ return (serial8250_reg.minor - 64) + port->line;
+@@ -1225,7 +1228,10 @@ static void autoconfig_irq(struct uart_8250_port *up)
+
+ static inline void __stop_tx(struct uart_8250_port *p)
+ {
+- if (p->ier & UART_IER_THRI) {
++ int status = serial_in(p, UART_LSR);
++ // only turn off THRE interrupt if THRE is *currently* asserted
++ // (we still want to catch it a final time after the FIFO empties)
++ if ((p->ier & UART_IER_THRI) && (status & UART_LSR_THRE)) {
+ p->ier &= ~UART_IER_THRI;
+ serial_out(p, UART_IER, p->ier);
+ }
+@@ -1527,6 +1533,7 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
+
+ DEBUG_INTR("end.\n");
+
++ wake_up(&thre_wait);
+ return IRQ_RETVAL(handled);
+ }
+
+@@ -2526,6 +2533,35 @@ serial8250_type(struct uart_port *port)
+ return uart_config[type].name;
+ }
+
++static int serial8250_ioctl(struct uart_port *port, unsigned int cmd, unsigned long arg) {
++ struct uart_8250_port *up = (struct uart_8250_port *)port;
++ unsigned long flags;
++ int ret = -ENOIOCTLCMD;
++ // kernel-space RS485 drain-and-switch hack
++ if (cmd == TIOCSERWAITTEMT) {
++ // wait for kernel buffers and UART FIFO to both empty
++ struct circ_buf *xmit = &up->port.info->xmit;
++ wait_event_interruptible(
++ thre_wait,
++ uart_circ_empty(xmit) &&
++ (serial_in(up, UART_LSR) & UART_LSR_THRE));
++ // spin until TEMT (transmit shift register empty)
++ spin_lock_irqsave(&up->port.lock, flags);
++ wait_for_xmitr(up, BOTH_EMPTY);
++ if (arg != 0) {
++ // turn off RS485 DE pin
++ gpio_set_value(arg, 0);
++ }
++ // grab any phantom char seen on RX when transceiver switches
++ (void) serial_inp(up, UART_RX);
++ // enable read
++ up->port.ignore_status_mask &= ~UART_LSR_DR;
++ spin_unlock_irqrestore(&up->port.lock, flags);
++ return 0;
++ }
++ return ret;
++}
++
+ static struct uart_ops serial8250_pops = {
+ .tx_empty = serial8250_tx_empty,
+ .set_mctrl = serial8250_set_mctrl,
+@@ -2544,6 +2580,7 @@ static struct uart_ops serial8250_pops = {
+ .request_port = serial8250_request_port,
+ .config_port = serial8250_config_port,
+ .verify_port = serial8250_verify_port,
++ .ioctl = serial8250_ioctl,
+ #ifdef CONFIG_CONSOLE_POLL
+ .poll_get_char = serial8250_get_poll_char,
+ .poll_put_char = serial8250_put_poll_char,
+diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
+index 5702145..0b01ba8 100644
+--- a/drivers/watchdog/Kconfig
++++ b/drivers/watchdog/Kconfig
+@@ -235,10 +235,17 @@ config ORION5X_WATCHDOG
+
+ config AST_WATCHDOG
+ tristate "ASPEED GUC watchdog"
+- depends on WATCHDOG
++ depends on WATCHDOG
+ help
+ Watchdog timer for ASPEED chips.
+
++config AST_WATCHDOG_REARM_DUAL_BOOT
++ bool "Rearm dual boot watchdog"
++ default n
++ depends on AST_WATCHDOG
++ help
++ Rearm dual boot watchdog or not during boot
++
+ # ARM26 Architecture
+
+ # AVR32 Architecture
+diff --git a/drivers/watchdog/ast_wdt.c b/drivers/watchdog/ast_wdt.c
+index 9e7e84f..e599a55 100644
+--- a/drivers/watchdog/ast_wdt.c
++++ b/drivers/watchdog/ast_wdt.c
+@@ -68,6 +68,7 @@ typedef unsigned char bool_T;
+
+ #else
+ #define WDT_BASE_VA (IO_ADDRESS(AST_WDT_BASE))
++#define WDT2_BASE_VA (IO_ADDRESS(AST_WDT_BASE + 20))
+ #endif
+
+ #define WDT_CntSts (WDT_BASE_VA+0x00)
+@@ -78,6 +79,14 @@ typedef unsigned char bool_T;
+ #define WDT_Clr (WDT_BASE_VA+0x14)
+ #define WDT_RstWd (WDT_BASE_VA+0x18)
+
++#define WDT2_CntSts (WDT2_BASE_VA+0x00)
++#define WDT2_Reload (WDT2_BASE_VA+0x04)
++#define WDT2_Restart (WDT2_BASE_VA+0x08)
++#define WDT2_Ctrl (WDT2_BASE_VA+0x0C)
++#define WDT2_TimeOut (WDT2_BASE_VA+0x10)
++#define WDT2_Clr (WDT2_BASE_VA+0x14)
++#define WDT2_RstWd (WDT2_BASE_VA+0x18)
++
+ #define WDT_CTRL_B_SECOND_BOOT (0x1 << 7)
+ #define WDT_CTRL_B_RESET_SOC (0x00 << 5) /* yes, 0x00 */
+ #define WDT_CTRL_B_RESET_FULL (0x01 << 5)
+@@ -101,6 +110,11 @@ typedef unsigned char bool_T;
+ #define WDT_TIMO 30 /* Default heartbeat = 30 seconds */
+
+ #define WDT_INITIAL_TIMO (8*60) /* Initial timeout, 8m */
++/*
++ * Dual boot watchdog is 5s shorter so that dual boot watchdog
++ * will kick in first.
++ */
++#define WDT_DUAL_BOOT_TIMO (WDT_INITIAL_TIMO - 5)
+ #define WDT_TIMO2TICKS(t) (TICKS_PER_uSEC * 1000000 * (t))
+
+ static int heartbeat = WDT_TIMO;
+@@ -233,6 +247,14 @@ bool_T wdt_is_enabled(void)
+ return reg & WDT_CTRL_B_ENABLE;
+ }
+
++#ifdef CONFIG_AST_WATCHDOG_REARM_DUAL_BOOT
++void wdt_dual_boot_restart(unsigned int timeo)
++{
++ AST_WRITE_REG(WDT2_Reload, WDT_TIMO2TICKS(timeo));
++ AST_WRITE_REG(WDT2_Restart, 0x4755); /* reload! */
++ printk(KERN_INFO "Re-arm the dual boot watchdog for %u seconds\n", timeo);
++}
++#endif
+
+ void wdt_restart_new(unsigned int nPeriod, int sourceClk, bool_T bResetOut,
+ bool_T bIntrSys, bool_T bClrAfter, bool_T bResetARMOnly)
+@@ -542,6 +564,11 @@ static int ast_wdt_probe(struct platform_device *pdev)
+ return ret;
+ }
+
++#ifdef CONFIG_AST_WATCHDOG_REARM_DUAL_BOOT
++ /* re-arm dual boot watchdog */
++ wdt_dual_boot_restart(WDT_DUAL_BOOT_TIMO);
++#endif
++
+ /* interrupt the system while WDT timeout */
+ wdt_restart_new(WDT_TIMO2TICKS(WDT_INITIAL_TIMO), WDT_CLK_SRC_EXT,
+ /* No Ext, No intr, Self clear, Full chip reset */
+diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
+index 61cb48f..5dc69ab 100644
+--- a/fs/compat_ioctl.c
++++ b/fs/compat_ioctl.c
+@@ -3,7 +3,7 @@
+ *
+ * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com)
+ * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
+- * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs
++ * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs
+ * Copyright (C) 2003 Pavel Machek (pavel@suse.cz)
+ *
+ * These routines maintain argument size conversion between 32bit and 64bit
+@@ -125,7 +125,7 @@ static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
+ mm_segment_t old_fs = get_fs();
+ int err;
+ unsigned long val;
+-
++
+ set_fs (KERNEL_DS);
+ err = sys_ioctl(fd, cmd, (unsigned long)&val);
+ set_fs (old_fs);
+@@ -133,14 +133,14 @@ static int w_long(unsigned int fd, unsigned int cmd, unsigned long arg)
+ return -EFAULT;
+ return err;
+ }
+-
++
+ static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg)
+ {
+ mm_segment_t old_fs = get_fs();
+ u32 __user *argptr = compat_ptr(arg);
+ int err;
+ unsigned long val;
+-
++
+ if(get_user(val, argptr))
+ return -EFAULT;
+ set_fs (KERNEL_DS);
+@@ -365,17 +365,17 @@ static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
+ if (copy_in_user(ifr, ifr32, sizeof(struct ifreq32)))
+ return -EFAULT;
+ ifr++;
+- ifr32++;
++ ifr32++;
+ }
+ }
+ if (copy_to_user(uifc, &ifc, sizeof(struct ifconf)))
+ return -EFAULT;
+
+- err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)uifc);
++ err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)uifc);
+ if (err)
+ return err;
+
+- if (copy_from_user(&ifc, uifc, sizeof(struct ifconf)))
++ if (copy_from_user(&ifc, uifc, sizeof(struct ifconf)))
+ return -EFAULT;
+
+ ifr = ifc.ifc_req;
+@@ -411,7 +411,7 @@ static int ethtool_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+ struct ifreq32 __user *ifr32;
+ u32 data;
+ void __user *datap;
+-
++
+ ifr = compat_alloc_user_space(sizeof(*ifr));
+ ifr32 = compat_ptr(arg);
+
+@@ -507,7 +507,7 @@ static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
+ struct ifmap32 __user *uifmap32;
+ mm_segment_t old_fs;
+ int err;
+-
++
+ uifr32 = compat_ptr(arg);
+ uifmap32 = &uifr32->ifr_ifru.ifru_map;
+ switch (cmd) {
+@@ -610,7 +610,7 @@ static int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+ char devname[16];
+ u32 rtdev;
+ mm_segment_t old_fs = get_fs();
+-
++
+ struct socket *mysock = sockfd_lookup(fd, &ret);
+
+ if (mysock && mysock->sk && mysock->sk->sk_family == AF_INET6) { /* ipv6 */
+@@ -624,7 +624,7 @@ static int routing_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+ ret |= __get_user (r6.rtmsg_info, &(ur6->rtmsg_info));
+ ret |= __get_user (r6.rtmsg_flags, &(ur6->rtmsg_flags));
+ ret |= __get_user (r6.rtmsg_ifindex, &(ur6->rtmsg_ifindex));
+-
++
+ r = (void *) &r6;
+ } else { /* ipv4 */
+ struct rtentry32 __user *ur4 = compat_ptr(arg);
+@@ -1046,14 +1046,14 @@ static int vt_check(struct file *file)
+ struct tty_struct *tty;
+ struct inode *inode = file->f_path.dentry->d_inode;
+ struct vc_data *vc;
+-
++
+ if (file->f_op->unlocked_ioctl != tty_ioctl)
+ return -EINVAL;
+-
++
+ tty = (struct tty_struct *)file->private_data;
+ if (tty_paranoia_check(tty, inode, "tty_ioctl"))
+ return -EINVAL;
+-
++
+ if (tty->ops->ioctl != vt_ioctl)
+ return -EINVAL;
+
+@@ -1067,7 +1067,7 @@ static int vt_check(struct file *file)
+ */
+ if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
+ return 1;
+- return 0;
++ return 0;
+ }
+
+ struct consolefontdesc32 {
+@@ -1085,7 +1085,7 @@ static int do_fontx_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg,
+
+ perm = vt_check(file);
+ if (perm < 0) return perm;
+-
++
+ switch (cmd) {
+ case PIO_FONTX:
+ if (!perm)
+@@ -1130,16 +1130,16 @@ struct console_font_op32 {
+ compat_uint_t charcount;
+ compat_caddr_t data; /* font data with height fixed to 32 */
+ };
+-
++
+ static int do_kdfontop_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file)
+ {
+ struct console_font_op op;
+ struct console_font_op32 __user *fontop = compat_ptr(arg);
+ int perm = vt_check(file), i;
+ struct vc_data *vc;
+-
++
+ if (perm < 0) return perm;
+-
++
+ if (copy_from_user(&op, fontop, sizeof(struct console_font_op32)))
+ return -EFAULT;
+ if (!perm && op.op != KD_FONT_OP_GET)
+@@ -1303,7 +1303,7 @@ static int do_atmif_sioc(unsigned int fd, unsigned int cmd, unsigned long arg)
+ u32 data;
+ void __user *datap;
+ int err;
+-
++
+ sioc = compat_alloc_user_space(sizeof(*sioc));
+ sioc32 = compat_ptr(arg);
+
+@@ -1328,7 +1328,7 @@ static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg)
+ {
+ int i;
+ unsigned int cmd = 0;
+-
++
+ switch (cmd32) {
+ case SONET_GETSTAT:
+ case SONET_GETSTATZ:
+@@ -1349,11 +1349,11 @@ static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg)
+ }
+ if (i == NR_ATM_IOCTL)
+ return -EINVAL;
+-
++
+ switch (cmd) {
+ case ATM_GETNAMES:
+ return do_atm_iobuf(fd, cmd, arg);
+-
++
+ case ATM_GETLINKRATE:
+ case ATM_GETTYPE:
+ case ATM_GETESI:
+@@ -1444,7 +1444,7 @@ static int mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg)
+ }
+
+ return err;
+-}
++}
+
+ #ifdef CONFIG_BLOCK
+ struct raw32_config_request
+@@ -1798,7 +1798,7 @@ static int rtc_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
+ val32 = kval;
+ return put_user(val32, (unsigned int __user *)arg);
+ case RTC_IRQP_SET32:
+- return sys_ioctl(fd, RTC_IRQP_SET, arg);
++ return sys_ioctl(fd, RTC_IRQP_SET, arg);
+ case RTC_EPOCH_SET32:
+ return sys_ioctl(fd, RTC_EPOCH_SET, arg);
+ default:
+@@ -2678,6 +2678,7 @@ COMPATIBLE_IOCTL(USBDEVFS_IOCTL32)
+ /* i2c */
+ HANDLE_IOCTL(I2C_FUNCS, w_long)
+ HANDLE_IOCTL(I2C_RDWR, do_i2c_rdwr_ioctl)
++HANDLE_IOCTL(I2C_SLAVE_RDWR, do_i2c_rdwr_ioctl)
+ HANDLE_IOCTL(I2C_SMBUS, do_i2c_smbus_ioctl)
+ /* bridge */
+ HANDLE_IOCTL(SIOCSIFBR, old_bridge_ioctl)
+diff --git a/include/linux/i2c-dev.h b/include/linux/i2c-dev.h
+index 311315b..ed9b48d 100644
+--- a/include/linux/i2c-dev.h
++++ b/include/linux/i2c-dev.h
+@@ -46,6 +46,7 @@
+ #define I2C_FUNCS 0x0705 /* Get the adapter functionality mask */
+
+ #define I2C_RDWR 0x0707 /* Combined R/W transfer (one STOP only) */
++#define I2C_SLAVE_RDWR 0x0709 /* Slave Read Write */
+
+ #define I2C_PEC 0x0708 /* != 0 to use PEC with SMBus */
+ #define I2C_SMBUS 0x0720 /* SMBus transfer */
+diff --git a/include/linux/i2c.h b/include/linux/i2c.h
+index 59167e2..f037cde 100644
+--- a/include/linux/i2c.h
++++ b/include/linux/i2c.h
+@@ -62,6 +62,9 @@ extern int i2c_master_recv(struct i2c_client *client, char *buf, int count);
+ extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+ int num);
+
++extern int i2c_slave_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
++ int num);
++
+ /* This is the very generalized SMBus access routine. You probably do not
+ want to use this, though; one of the functions below may be much easier,
+ and probably just as fast.
+@@ -333,6 +336,7 @@ struct i2c_algorithm {
+ processed, or a negative value on error */
+ int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,
+ int num);
++ int (*slave_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs);
+ int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,
+ unsigned short flags, char read_write,
+ u8 command, int size, union i2c_smbus_data *data);
+@@ -516,6 +520,8 @@ struct i2c_msg {
+ __u16 flags;
+ #define I2C_M_TEN 0x0010 /* this is a ten bit chip address */
+ #define I2C_M_RD 0x0001 /* read data, from slave to master */
++#define I2C_S_EN 0x0002 /* Slave Enable */
++#define I2C_S_ALT 0x0004 /* Slave Alert */
+ #define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */
+ #define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */
+ #define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
+diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0029-mtd-m25p80-Add-support-for-the-Winbond-W25Q64.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0029-mtd-m25p80-Add-support-for-the-Winbond-W25Q64.patch
+new file mode 100644
+index 0000000..52aef04
+--- /dev/null
++++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0029-mtd-m25p80-Add-support-for-the-Winbond-W25Q64.patch
+@@ -0,0 +1,29 @@
++From d2ac467a108400ff1ae682a423c7d41265e62d47 Mon Sep 17 00:00:00 2001
++From: Thierry Reding <thierry.reding@avionic-design.de>
++Date: Mon, 30 Aug 2010 13:00:48 +0200
++Subject: [PATCH] mtd: m25p80: Add support for the Winbond W25Q64
++
++This patch adds support for the Winbond W25Q64 serial flash.
++
++Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
++Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
++Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
++---
++ drivers/mtd/devices/m25p80.c | 1 +
++ 1 file changed, 1 insertion(+)
++
++diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
++index 1f0f703..b6fd7c2 100644
++--- a/drivers/mtd/devices/m25p80.c
+++++ b/drivers/mtd/devices/m25p80.c
++@@ -716,6 +716,7 @@ static const struct spi_device_id m25p_ids[] = {
++ { "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) },
++ { "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) },
++ { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
+++ { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
++
++ /* Catalyst / On Semiconductor -- non-JEDEC */
++ { "cat25c11", CAT25_INFO( 16, 8, 16, 1) },
++--
++1.8.5.6
++
+diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0030-net-Don-t-leak-packets-when-a-netns-is-going-down.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0030-net-Don-t-leak-packets-when-a-netns-is-going-down.patch
+new file mode 100644
+index 0000000..ad04217
+--- /dev/null
++++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0030-net-Don-t-leak-packets-when-a-netns-is-going-down.patch
+@@ -0,0 +1,56 @@
++From 0a36b345ab99d6b3c96999e7e3b79bd243cf9bf7 Mon Sep 17 00:00:00 2001
++From: "Eric W. Biederman" <ebiederm@xmission.com>
++Date: Wed, 5 Nov 2008 16:00:24 -0800
++Subject: [PATCH] net: Don't leak packets when a netns is going down
++
++I have been tracking for a while a case where when the
++network namespace exits the cleanup gets stck in an
++endless precessess of:
++
++unregister_netdevice: waiting for lo to become free. Usage count = 3
++unregister_netdevice: waiting for lo to become free. Usage count = 3
++unregister_netdevice: waiting for lo to become free. Usage count = 3
++unregister_netdevice: waiting for lo to become free. Usage count = 3
++unregister_netdevice: waiting for lo to become free. Usage count = 3
++unregister_netdevice: waiting for lo to become free. Usage count = 3
++unregister_netdevice: waiting for lo to become free. Usage count = 3
++
++It turns out that if you listen on a multicast address an unsubscribe
++packet is sent when the network device goes down. If you shutdown
++the network namespace without carefully cleaning up this can trigger
++the unsubscribe packet to be sent over the loopback interface while
++the network namespace is going down.
++
++All of which is fine except when we drop the packet and forget to
++free it leaking the skb and the dst entry attached to. As it
++turns out the dst entry hold a reference to the idev which holds
++the dev and keeps everything from being cleaned up. Yuck!
++
++By fixing my earlier thinko and add the needed kfree_skb and everything
++cleans up beautifully.
++
++Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
++Signed-off-by: David S. Miller <davem@davemloft.net>
++---
++ net/core/dev.c | 4 +++-
++ 1 file changed, 3 insertions(+), 1 deletion(-)
++
++diff --git a/net/core/dev.c b/net/core/dev.c
++index 811507c..a0c60607 100644
++--- a/net/core/dev.c
+++++ b/net/core/dev.c
++@@ -2253,8 +2253,10 @@ int netif_receive_skb(struct sk_buff *skb)
++ rcu_read_lock();
++
++ /* Don't receive packets in an exiting network namespace */
++- if (!net_alive(dev_net(skb->dev)))
+++ if (!net_alive(dev_net(skb->dev))) {
+++ kfree_skb(skb);
++ goto out;
+++ }
++
++ #ifdef CONFIG_NET_CLS_ACT
++ if (skb->tc_verd & TC_NCLS) {
++--
++1.8.1
++
+diff --git a/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0031-IPv6-Print-error-value-when-skb-allocation-fails.patch b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0031-IPv6-Print-error-value-when-skb-allocation-fails.patch
+new file mode 100644
+index 0000000..b638996
+--- /dev/null
++++ b/meta-aspeed/recipes-kernel/linux/files/patch-2.6.28.9/0031-IPv6-Print-error-value-when-skb-allocation-fails.patch
+@@ -0,0 +1,43 @@
++From 5777cee30776da63ecbe2b6d4929e01d82c7d72e Mon Sep 17 00:00:00 2001
++From: Brian Haley <brian.haley@hp.com>
++Date: Tue, 2 Jun 2009 00:20:26 -0700
++Subject: [PATCH] IPv6: Print error value when skb allocation fails
++
++Print-out the error value when sock_alloc_send_skb() fails in
++the IPv6 neighbor discovery code - can be useful for debugging.
++
++Signed-off-by: Brian Haley <brian.haley@hp.com>
++Signed-off-by: David S. Miller <davem@davemloft.net>
++---
++ net/ipv6/ndisc.c | 8 ++++----
++ 1 file changed, 4 insertions(+), 4 deletions(-)
++
++diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
++index d0f54d1..45529b1 100644
++--- a/net/ipv6/ndisc.c
+++++ b/net/ipv6/ndisc.c
++@@ -483,8 +483,8 @@ static void __ndisc_send(struct net_device *dev,
++ 1, &err);
++ if (!skb) {
++ ND_PRINTK0(KERN_ERR
++- "ICMPv6 ND: %s() failed to allocate an skb.\n",
++- __func__);
+++ "ICMPv6 ND: %s() failed to allocate an skb, err=%d.\n",
+++ __func__, err);
++ dst_release(dst);
++ return;
++ }
++@@ -1533,8 +1533,8 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
++ 1, &err);
++ if (buff == NULL) {
++ ND_PRINTK0(KERN_ERR
++- "ICMPv6 Redirect: %s() failed to allocate an skb.\n",
++- __func__);
+++ "ICMPv6 Redirect: %s() failed to allocate an skb, err=%d.\n",
+++ __func__, err);
++ dst_release(dst);
++ return;
++ }
++--
++1.8.1
++
diff --git a/meta-aspeed/recipes-kernel/linux/linux-aspeed_2.6.28.9.bb b/meta-aspeed/recipes-kernel/linux/linux-aspeed_2.6.28.9.bb
index 077e21b..bda2ea3 100644
--- a/meta-aspeed/recipes-kernel/linux/linux-aspeed_2.6.28.9.bb
+++ b/meta-aspeed/recipes-kernel/linux/linux-aspeed_2.6.28.9.bb
@@ -1,10 +1,7 @@
-
# This revision corresponds to the tag "v2.6.28.9"
# We use the revision in order to avoid having to fetch it from the repo during parse
SRCREV = "1e85856853e24e9013d142adaad38c2adc7e48ac"
-PV = "2.6.28.9"
-
SRC_URI = "git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git;protocol=https;branch=linux-2.6.28.y \
file://patch-2.6.28.9/0000-linux-aspeed-064.patch \
file://patch-2.6.28.9/0000-linux-openbmc.patch \
@@ -25,14 +22,30 @@ SRC_URI = "git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
file://patch-2.6.28.9/0028-ipv6-Plug-sk_buff-leak-in-ipv6_rcv-net-ipv6-ip6_inpu.patch \
file://patch-2.6.28.9/0001-bzip2-lzma-library-support-for-gzip-bzip2-and-lzma-d.patch \
file://patch-2.6.28.9/0002-bzip2-lzma-config-and-initramfs-support-for-bzip2-lz.patch \
+ file://patch-2.6.28.9/0032-Create-snapshot-of-OpenBMC.patch \
"
S = "${WORKDIR}/git"
-LINUX_VERSION = "2.6.28.9"
+LINUX_VERSION ?= "2.6.28.9"
LINUX_VERSION_EXTENSION ?= "-aspeed"
PR = "r1"
+PV = "${LINUX_VERSION}"
+
+include linux-aspeed.inc
+
+# Install bounds.h for external module install
+# The default install script handles this. However, it looks for bounds.h from
+# 'include/generated', which doesnot match 2.6.28, where the file is in
+# 'include/linux'.
+do_install[postfuncs] += "install_bounds_h"
+install_bounds_h() {
+ kerneldir=${D}${KERNEL_SRC_PATH}
+ if [ -f include/linux/bounds.h ]; then
+ cp -l include/linux/bounds.h $kerneldir/include/linux/bounds.h
+ fi
+}
KERNEL_CONFIG_COMMAND = "oe_runmake wedge_defconfig && oe_runmake oldconfig"
diff --git a/meta-facebook/meta-wedge/conf/machine/wedge.conf b/meta-facebook/meta-wedge/conf/machine/wedge.conf
index 69f3a90..3ed8ec1 100644
--- a/meta-facebook/meta-wedge/conf/machine/wedge.conf
+++ b/meta-facebook/meta-wedge/conf/machine/wedge.conf
@@ -5,3 +5,8 @@
UBOOT_MACHINE_wedge = "wedge_config"
require conf/machine/include/ast1250.inc
+
+# configuration for preferred version of packages
+PREFERRED_VERSION_libipmi = "0.1"
+PREFERRED_VERSION_ipmid = "0.1"
+PREFERRED_VERSION_rest-api = "0.1"
diff --git a/meta-facebook/meta-wedge/recipes-core/images/wedge-image.inc b/meta-facebook/meta-wedge/recipes-core/images/wedge-image.inc
index 15a4252..7cd89de 100644
--- a/meta-facebook/meta-wedge/recipes-core/images/wedge-image.inc
+++ b/meta-facebook/meta-wedge/recipes-core/images/wedge-image.inc
@@ -39,9 +39,8 @@ NTP_PKGS = " \
# Include modules in rootfs
IMAGE_INSTALL += " \
kernel-modules \
- u-boot \
u-boot-fw-utils \
- fbutils \
+ openbmc-utils \
fan-ctrl \
rackmon \
watchdog-ctrl \
@@ -49,6 +48,8 @@ IMAGE_INSTALL += " \
sensor-setup \
usb-console \
oob-nic \
+ lldp-util \
+ bmc-log \
lmsensors-sensors \
wedge-eeprom \
sms-kcsd \
@@ -61,6 +62,7 @@ IMAGE_INSTALL += " \
${NTP_PKGS} \
iproute2 \
dhcp-client \
+ spatula \
"
IMAGE_FEATURES += " \
diff --git a/meta-facebook/meta-wedge/recipes-core/init-ifupdown/files/dhcpv6_down b/meta-facebook/meta-wedge/recipes-core/init-ifupdown/files/dhcpv6_down
new file mode 100644
index 0000000..a44deb4
--- /dev/null
+++ b/meta-facebook/meta-wedge/recipes-core/init-ifupdown/files/dhcpv6_down
@@ -0,0 +1,27 @@
+#!/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
+#
+
+pid="/var/run/dhclient6.${IFACE}.pid"
+
+if [ -f "${pid}" ]; then
+ kill -9 `cat ${pid}` 2>/dev/null
+fi
+
+exit 0
diff --git a/meta-facebook/meta-wedge/recipes-core/init-ifupdown/files/dhcpv6_up b/meta-facebook/meta-wedge/recipes-core/init-ifupdown/files/dhcpv6_up
new file mode 100644
index 0000000..6469b9f
--- /dev/null
+++ b/meta-facebook/meta-wedge/recipes-core/init-ifupdown/files/dhcpv6_up
@@ -0,0 +1,28 @@
+#!/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
+#
+
+# only care about 'eth0' and 'oob' intf
+[ "$IFACE" != "eth0" ] && [ "$IFACE" != "oob" ] && exit 0
+
+pid="/var/run/dhclient6.${IFACE}.pid"
+
+dhclient -6 -nw -pf ${pid} ${IFACE}
+
+exit 0
diff --git a/meta-facebook/meta-wedge/recipes-core/init-ifupdown/init-ifupdown_%.bbappend b/meta-facebook/meta-wedge/recipes-core/init-ifupdown/init-ifupdown_%.bbappend
index 7d74521..e715c27 100644
--- a/meta-facebook/meta-wedge/recipes-core/init-ifupdown/init-ifupdown_%.bbappend
+++ b/meta-facebook/meta-wedge/recipes-core/init-ifupdown/init-ifupdown_%.bbappend
@@ -1,2 +1,18 @@
FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+SRC_URI += "file://dhcpv6_up \
+ file://dhcpv6_down \
+ "
+
+do_install_append() {
+ # rules to request dhcpv6
+ install -d ${D}/${sysconfdir}/network/if-up.d
+ install -m 755 ${WORKDIR}/dhcpv6_up ${D}${sysconfdir}/network/if-up.d/dhcpv6_up
+ install -d ${D}/${sysconfdir}/network/if-down.d
+ install -m 755 ${WORKDIR}/dhcpv6_down ${D}${sysconfdir}/network/if-down.d/dhcpv6_down
+}
+
+FILES_${PN} += "${sysconfdir}/network/if-up.d/dhcpv6_up \
+ ${sysconfdir}/network/if-down.d/dhcpv6_down \
+ "
diff --git a/meta-facebook/meta-wedge/recipes-kernel/linux/linux-aspeed_2.6%.bbappend b/meta-facebook/meta-wedge/recipes-kernel/linux/linux-aspeed_2.6%.bbappend
index 6bf04da..3c5b71c 100644
--- a/meta-facebook/meta-wedge/recipes-kernel/linux/linux-aspeed_2.6%.bbappend
+++ b/meta-facebook/meta-wedge/recipes-kernel/linux/linux-aspeed_2.6%.bbappend
@@ -2,4 +2,4 @@ LINUX_VERSION_EXTENSION = "-wedge"
COMPATIBLE_MACHINE = "wedge"
-KERNEL_DEFCONFIG_aspeed = "wedge_defconfig"
+KERNEL_CONFIG_COMMAND = "oe_runmake wedge_defconfig && oe_runmake oldconfig"
diff --git a/meta-facebook/meta-wedge/recipes-wedge/bmc-log/bmc-log_0.1.bb b/meta-facebook/meta-wedge/recipes-wedge/bmc-log/bmc-log_0.1.bb
new file mode 100644
index 0000000..2788a36
--- /dev/null
+++ b/meta-facebook/meta-wedge/recipes-wedge/bmc-log/bmc-log_0.1.bb
@@ -0,0 +1,50 @@
+# 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
+#
+
+SUMMARY = "Logging Utility"
+DESCRIPTION = "Util for logging"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://bmc-log.c;beginline=4;endline=16;md5=da35978751a9d71b73679307c4d296ec"
+
+SRC_URI = "file://bmc-log.c \
+ file://bmc-log.h \
+ file://Makefile \
+ file://bmc-log-config \
+ file://bmc-log.sh \
+ "
+
+S = "${WORKDIR}"
+
+do_install() {
+ install -d ${D}${sbindir}
+ install -m 755 bmc-log ${D}${sbindir}/bmc-log
+ install -d ${D}${sysconfdir}/default
+ install -m 755 bmc-log-config ${D}${sysconfdir}/default/bmc-log
+ install -d ${D}${sysconfdir}/init.d
+ install -m 755 bmc-log.sh ${D}${sysconfdir}/init.d/bmc-log.sh
+ update-rc.d -r ${D} bmc-log.sh start 92 S .
+}
+
+FILES_${PN} = "${sbindir} ${sysconfdir} "
+
+# Inhibit complaints about .debug directories
+
+INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
+INHIBIT_PACKAGE_STRIP = "1"
diff --git a/meta-facebook/meta-wedge/recipes-wedge/bmc-log/files/Makefile b/meta-facebook/meta-wedge/recipes-wedge/bmc-log/files/Makefile
new file mode 100644
index 0000000..5004556
--- /dev/null
+++ b/meta-facebook/meta-wedge/recipes-wedge/bmc-log/files/Makefile
@@ -0,0 +1,24 @@
+# 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
+
+LIBS = -lutil
+
+all:
+ ${CC} ${CFLAGS} -o bmc-log bmc-log.c ${LIBS}
+
+clean:
+ rm -rf *.o bmc-log
diff --git a/meta-facebook/meta-wedge/recipes-wedge/bmc-log/files/bmc-log-config b/meta-facebook/meta-wedge/recipes-wedge/bmc-log/files/bmc-log-config
new file mode 100644
index 0000000..529adf2
--- /dev/null
+++ b/meta-facebook/meta-wedge/recipes-wedge/bmc-log/files/bmc-log-config
@@ -0,0 +1,16 @@
+# Configuration used by bmc-log script
+
+#Serial port connected to the micro-server
+US_TTY=""
+
+#IP version of the log collecting server
+LOG_SERVER_IP_VERSION=""
+
+#Host name of the log collecting server
+LOG_SERVER_NAME=""
+
+#Port number of the log collecting server
+LOG_SERVER_PORT=""
+
+#Baud rate to set for the US_TTY
+TTY_BAUD_RATE=""
diff --git a/meta-facebook/meta-wedge/recipes-wedge/bmc-log/files/bmc-log.c b/meta-facebook/meta-wedge/recipes-wedge/bmc-log/files/bmc-log.c
new file mode 100644
index 0000000..078db7b
--- /dev/null
+++ b/meta-facebook/meta-wedge/recipes-wedge/bmc-log/files/bmc-log.c
@@ -0,0 +1,559 @@
+/*
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <string.h>
+#include <linux/serial.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <time.h>
+#include <arpa/inet.h>
+#include <sys/stat.h>
+#include <pty.h>
+#include <errno.h>
+#include <signal.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include "bmc-log.h"
+
+FILE *error_file = NULL;
+
+bool kill_received = false; // To check if a killing interrupt is received
+
+speed_t baud_rate = B57600; // Default baud rate - change if user inputs a different one
+
+int fd_tty = -1, fd_soc = -1;
+
+/* Hostname and port of the server */
+char *hostname;
+int port;
+
+struct termios orig_tty_state;
+
+char *get_time()
+{
+ static char mytime[TIME_FORMAT_SIZE];
+ memset(mytime, 0, sizeof(mytime));
+ time_t this_time;
+ struct tm *this_tm;
+ this_time = time(NULL);
+ this_tm = localtime(&this_time);
+
+ snprintf(mytime, sizeof(mytime), "%04d-%02d-%02d %02d:%02d:%02d",
+ 1900 + this_tm->tm_year, this_tm->tm_mon + 1,
+ this_tm->tm_mday, this_tm->tm_hour,
+ this_tm->tm_min, this_tm->tm_sec);
+ return mytime;
+}
+
+void errlog(char *frmt, ...)
+{
+ va_list args;
+ va_start(args, frmt);
+ struct stat st;
+
+ char *time_now = get_time();
+
+ fprintf(stderr, "[%s] ", time_now);
+ vfprintf(stderr, frmt, args);
+
+ if (error_file) {
+ stat(error_log_file, &st);
+ if (st.st_size >= MAX_LOG_FILE_SIZE) {
+ truncate(error_log_file, 0);
+ }
+ fprintf(error_file, "[%s] ", time_now);
+ vfprintf(error_file, frmt, args);
+ fflush(error_file);
+ }
+}
+
+/* Get the address info of netcons server */
+struct addrinfo *get_addr_info(int ip_version)
+{
+ int ip_family = (ip_version == IPV4) ? AF_INET : AF_INET6;
+ struct addrinfo hints;
+
+ struct addrinfo *result;
+ result = malloc(sizeof(*result));
+ if (!result) {
+ errlog("Error: Unable to allocate memory - %m\n");
+ return NULL;
+ }
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = ip_family; /* Allow IPv4 or IPv6 */
+ hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
+ hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
+ hints.ai_protocol = 0; /* Any protocol */
+ hints.ai_canonname = NULL;
+ hints.ai_addr = NULL;
+ hints.ai_next = NULL;
+
+ if (getaddrinfo(hostname, NULL, &hints, &result)) {
+ errlog("Error: getaddrinfo failed - %m\n");
+ return NULL;
+ }
+
+ return result;
+}
+
+/* Prepare Ipv4 Socket */
+bool prepare_sock(struct sockaddr_in * tgt_addr)
+{
+ struct addrinfo *addr_info;
+ memset(tgt_addr, 0, sizeof(*tgt_addr));
+
+ if ((addr_info = get_addr_info(IPV4)) == NULL) {
+ errlog("Error: Unable to get address info\n");
+ return false;
+ }
+
+ tgt_addr->sin_addr = ((struct sockaddr_in *)addr_info->ai_addr)->sin_addr;
+ tgt_addr->sin_port = htons(port);
+ tgt_addr->sin_family = AF_INET;
+
+ return true;
+}
+
+/* Prepare Ipv6 Socket */
+bool prepare_sock6(struct sockaddr_in6 * tgt_addr6)
+{
+ struct addrinfo *addr_info;
+ memset(tgt_addr6, 0, sizeof(*tgt_addr6));
+
+ if ((addr_info = get_addr_info(IPV6)) == NULL) {
+ errlog("Erorr: Unable to get address info\n");
+ return false;
+ }
+
+ tgt_addr6->sin6_addr = ((struct sockaddr_in6 *)addr_info->ai_addr)->sin6_addr;
+ tgt_addr6->sin6_port = htons(port);
+ tgt_addr6->sin6_family = AF_INET6;
+
+ return true;
+}
+
+/* Set TTY to raw mode */
+bool set_tty(int fd)
+{
+ struct termios tty_state;
+
+ if (tcgetattr(fd, &tty_state) < 0) {
+ return false;
+ }
+
+ if (tcgetattr(fd, &orig_tty_state) < 0) // Save original settings
+ {
+ return false;
+ }
+
+ if (cfsetspeed(&tty_state, baud_rate) == -1) {
+ errlog("Error: Baud Rate not set - %m\n");
+ return false;
+ }
+
+ tty_state.c_lflag &= ~(ICANON | IEXTEN | ISIG | ECHO);
+ tty_state.c_iflag &= ~(IGNCR | ICRNL | INPCK | ISTRIP | IXON | BRKINT);
+ tty_state.c_iflag |= (IGNCR | ICRNL);
+ tty_state.c_oflag &= ~OPOST;
+ tty_state.c_cflag |= CS8;
+
+ tty_state.c_cc[VMIN] = 1;
+ tty_state.c_cc[VTIME] = 0;
+
+ if (tcsetattr(fd, TCSAFLUSH, &tty_state) < 0) {
+ return false;
+ }
+
+ return true;
+}
+
+/* Create a pseudo terminal for other process to use (as this program is using up the actual TTY) */
+int create_pseudo_tty()
+{
+ int amaster, aslave;
+ int flags;
+
+ if (openpty(&amaster, &aslave, NULL, NULL, NULL) == -1) {
+ errlog("Error: Openpty failed - %m\n");
+ return -1;
+ }
+
+ /* Set to non blocking mode */
+ flags = fcntl(amaster, F_GETFL);
+ flags |= O_NONBLOCK;
+ fcntl(amaster, F_SETFL, flags);
+
+ FILE *pseudo_save_file = fopen(pseudo_tty_save_file, "w+");
+ if (!pseudo_save_file) {
+ errlog("Error: Unable to open the pseudo info file - %m\n");
+ return -1;
+ }
+ /* Save the name of the created pseudo tty in a text file for other processes to use */
+ if (fprintf(pseudo_save_file, "%s\n", ttyname(aslave)) == -1) {
+ errlog("Error writing to the pseudo info file\n");
+ fclose(pseudo_save_file);
+ return -1;
+ }
+ fclose(pseudo_save_file);
+
+ if (set_tty(aslave) == -1) {
+ errlog("Error: Slave TTY not set properly\n");
+ return -1;
+ }
+
+ return amaster;
+}
+
+/* Prepare logs from the read_buf and send them to the server */
+bool prepare_log_send(char *read_buf, int max_read, int fd_socket)
+{
+ size_t buff_index = 0; // Index for the read_buf string
+
+ static char line[LINE_LEN] = { 0 };
+ static size_t line_index = 0; // Index for the line string
+
+ char msg[MSG_LEN] = { 0 }; // Message to be sent to the server
+
+ /* Kernel Version */
+ static char kernel_version[KERNEL_VERSION_LEN] = "dummy_kernel";
+ static int kernel_search_pos = 0;
+
+ while (buff_index < max_read && read_buf[buff_index] != '\0') {
+ if (read_buf[buff_index] == 'L') // Check if there is a possibility of new kernel version
+ {
+ kernel_search_pos = line_index;
+ }
+
+ /* Send the log when a line is read */
+ if (read_buf[buff_index] == '\n') {
+ if (kernel_search_pos > 0) {
+ if (strncmp(line + kernel_search_pos, "Linux version ", kernel_search_len) == 0) {
+ sscanf(line + kernel_search_pos + kernel_search_len, "%s", kernel_version);
+ }
+ kernel_search_pos = 0;
+ }
+
+ /* Prepare the message */
+ memset(msg, 0, sizeof(msg));
+ if (snprintf(msg, sizeof(msg), "%s %s %s %s", "kernel:", kernel_version, "- msg", line) < 0) {
+ errlog("Error copying the message - %m\n");
+ return false;
+ }
+
+ /* Send message to the server */
+ if (write(fd_socket, msg, strlen(msg)) < 0) {
+ errlog("Error: Write to socket failed - %m\n");
+ return false;
+ }
+
+ /* Reset the line buffer */
+ line_index = 0;
+ memset(line, 0, sizeof(line));
+
+ buff_index++;
+ continue;
+ }
+
+ /* If line is too big, send only the first few bytes and discard others. */
+ if (line_index >= sizeof(line)) {
+ line[line_index - 1] = 0;
+ buff_index++;
+ continue;
+ }
+
+ line[line_index++] = read_buf[buff_index++];
+ }
+
+ return true;
+}
+
+/* Read text from the TTY and send to send as logs */
+bool read_send(int fd_tty, int fd_socket)
+{
+ char read_buf[LINE_LEN] = { 0 }; // Buffer to be read into.
+ int read_size = 0;
+ fd_set readset;
+ int sel;
+ int fdmax;
+
+ int pseudo_tty = create_pseudo_tty();
+
+ if (pseudo_tty == -1) {
+ errlog("Error: Cannot create a psuedo terminal\n");
+ return false;
+ }
+
+ fdmax = MAX(fd_tty, pseudo_tty);
+
+ while (!kill_received) {
+ do {
+ FD_ZERO(&readset);
+ FD_SET(fd_tty, &readset);
+ FD_SET(pseudo_tty, &readset);
+
+ sel = select(fdmax + 1, &readset, NULL, NULL, NULL);
+ }
+ while (sel == -1 && errno == EINTR && !kill_received);
+
+ memset(read_buf, 0, sizeof(read_buf));
+ if (FD_ISSET(fd_tty, &readset)) {
+ read_size = read(fd_tty, read_buf, sizeof(read_buf) - 1);
+
+ if (read_size == 0) {
+ continue;
+ }
+ if (read_size < 0) {
+ if (errno == EAGAIN) {
+ continue;
+ }
+ errlog("Error: Read from tty failed - %m\n");
+ return false;
+ }
+
+ /* Send the read data to the pseudo terminal */
+ if (write(pseudo_tty, read_buf, read_size) < 0) {
+ if (errno == EAGAIN) // Output buffer full - flush it.
+ {
+ tcflush(pseudo_tty, TCIOFLUSH);
+ continue;
+ }
+
+ errlog("Error: Write to pseudo tty failed - %m\n");
+ return false;
+ }
+
+ /* Prepare log message and send to the server */
+ if (!prepare_log_send(read_buf, sizeof(read_buf), fd_socket)) {
+ errlog("Error: Sending log failed - %m\n");
+ return false;
+ }
+ }
+ /*if (FD_ISSET(fd_tty, &readset)) */
+ if (kill_received) {
+ break;
+ }
+
+ /* Check if there is an data in the pseudo terminal's buffer */
+ if (FD_ISSET(pseudo_tty, &readset)) {
+ read_size = read(pseudo_tty, read_buf, sizeof(read_buf) - 1);
+
+ if (read_size == 0) {
+ continue;
+ }
+ if (read_size < 0) {
+ if (errno == EAGAIN) {
+ continue;
+ }
+ errlog("Error: Read from pseudo tty failed - %m\n");
+ return false;
+ }
+
+ if (write(fd_tty, read_buf, read_size) < 0) {
+ if (errno == EAGAIN) // Output buffer full - flush it.
+ {
+ tcflush(fd_tty, TCIOFLUSH);
+ continue;
+ }
+
+ errlog("Error: Write to tty failed - %m\n");
+ return false;
+ }
+ } /*if (FD_ISSET(pseudo_tty,&readset)) */
+ } /*while (!kill_received) */
+
+ return true;
+}
+
+void cleanup()
+{
+ remove(pseudo_tty_save_file);
+ tcsetattr(fd_tty, TCSAFLUSH, &orig_tty_state); //Restore original settings
+ close(fd_tty);
+ close(fd_soc);
+ fclose(error_file);
+}
+
+void sig_kill(int signum)
+{
+ kill_received = true;
+}
+
+void register_kill()
+{
+ struct sigaction sigact;
+ sigset_t sigset;
+
+ sigemptyset(&sigset);
+ memset(&sigact, 0, sizeof sigact);
+ sigact.sa_handler = sig_kill;
+ sigact.sa_mask = sigset;
+
+ sigaction(SIGHUP, &sigact, NULL);
+ sigaction(SIGINT, &sigact, NULL);
+ sigaction(SIGQUIT, &sigact, NULL);
+ sigaction(SIGPIPE, &sigact, NULL);
+ sigaction(SIGTERM, &sigact, NULL);
+ sigaction(SIGKILL, &sigact, NULL);
+ sigaction(SIGABRT, &sigact, NULL);
+}
+
+void usage(char *prog_name)
+{
+ printf("Usage:\n");
+ printf("\t%s TTY ip_version(4 or 6) hostname port [baud rate (like 57600)]\n", prog_name);
+ printf("\t%s -h : For this help\n", prog_name);
+ printf("Example:\n\t./bmc-log /dev/ttyS1 4 netcons.any.facebook.com 1514\n");
+ printf("\tOR\n\t./bmc-log /dev/ttyS1 6 netcons6.any.facebook.com 1514 57600\n");
+}
+
+bool parse_user_input(int nargs, char **args, char *read_tty, int read_tty_size, int *ip_version)
+{
+ if (nargs < 5) {
+ if ((nargs > 1) && ((strcmp(args[1], "-h") == 0) || (strcmp(args[1], "--help") == 0))) {
+ usage(args[0]);
+ return false; // Not an error but returning -1 for the main function to return
+ }
+ fprintf(stderr, "Error: Invalid number of arguments\n");
+ usage(args[0]);
+ return false;
+ }
+
+ if (strlen(args[1]) > read_tty_size) {
+ fprintf(stderr, "Error: TTY too long\n");
+ usage(args[0]);
+ return false;
+ }
+
+ /* TTT to read the logs from */
+ strncpy(read_tty, args[1], read_tty_size);
+
+ /* IP Version, IP Address and Port of the netcons server */
+ *ip_version = atoi(args[2]);
+ if (*ip_version != IPV4 && *ip_version != IPV6) {
+ fprintf(stderr, "Error: Invalid IP Version input\n");
+ usage(args[0]);
+ return false;
+ }
+
+ hostname = args[3];
+ port = atoi(args[4]);
+
+ baud_rate = B57600;
+ if (nargs == 6)
+ baud_rate = atoi(args[5]);
+
+ return true;
+}
+
+int main(int argc, char **argv)
+{
+ char read_tty[TTY_LEN] = { 0 };
+ int ip_version;
+ int socket_domain = AF_UNSPEC;
+ char cmd[COMMAND_LEN] = { 0 };
+
+ /* Open the error log file */
+ error_file = fopen(error_log_file, "a+");
+ if (!error_file) {
+ printf("Error: Unable to open log file - %m\n");
+ return 1;
+ }
+
+ /* Register actions upon interrupts */
+ register_kill();
+
+ /* Parse the user input */
+ if (!parse_user_input(argc, argv, read_tty, sizeof(read_tty), &ip_version)) {
+ return 2;
+ }
+
+ snprintf(cmd, sizeof(cmd), "%s %s", uS_console, "connect");
+ if (system(cmd) == -1) {
+ errlog("Error: Unable to connect to the micro-server\n");
+ return 3;
+ }
+
+ /* Create a socket to communicate with the netcons server */
+ socket_domain = (ip_version == IPV4) ? AF_INET : AF_INET6;
+ fd_soc = socket(socket_domain, SOCK_DGRAM, 0);
+ if (fd_soc == -1) {
+ errlog("Error: Socket creation failed - %m\n");
+ return 4;
+ }
+
+ if (ip_version == IPV4) { /* IPv4 */
+ struct sockaddr_in tgt_addr;
+ if (!prepare_sock(&tgt_addr)) {
+ close(fd_soc);
+ errlog("Error: Socket not valid\n");
+ return 5;
+ }
+
+ if (connect(fd_soc, (struct sockaddr *)&tgt_addr, sizeof(tgt_addr)) == -1) {
+ close(fd_soc);
+ errlog("Error: Socket connection failed - %m\n");
+ return 6;
+ }
+
+ } else { /* IPv6 */
+
+ struct sockaddr_in6 tgt_addr6;
+ if (!prepare_sock6(&tgt_addr6)) {
+ close(fd_soc);
+ errlog("Error: Socket not valid\n");
+ return 5;
+ }
+
+ if (connect(fd_soc, (struct sockaddr *)&tgt_addr6, sizeof(tgt_addr6)) == -1) {
+ close(fd_soc);
+ errlog("Error: Socket connection failed - %m\n");
+ return 6;
+ }
+ }
+
+ /* TTY Operations */
+ if ((fd_tty = open(read_tty, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1) {
+ close(fd_soc);
+ errlog("Error: Serial Port %s open failed - %m\n", read_tty);
+ return 7;
+ }
+
+ if (!set_tty(fd_tty)) {
+ errlog("Error: tty not set properly\n");
+ cleanup();
+ return 8;
+ }
+
+ /* Read, prepare and send the logs */
+ if (!read_send(fd_tty, fd_soc)) {
+ errlog("Error: Sending logs failed\n");
+ cleanup();
+ return 9;
+ }
+
+ cleanup();
+ return 0;
+}
diff --git a/meta-facebook/meta-wedge/recipes-wedge/bmc-log/files/bmc-log.h b/meta-facebook/meta-wedge/recipes-wedge/bmc-log/files/bmc-log.h
new file mode 100644
index 0000000..5795e6a
--- /dev/null
+++ b/meta-facebook/meta-wedge/recipes-wedge/bmc-log/files/bmc-log.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#ifndef BMC_LOG_H_
+#define BMC_LOG_H_
+
+/* IP Version */
+#define IPV4 (4)
+#define IPV6 (6)
+
+/* Search string for the kernel version */
+#define KERNEL_SEARCH_STR "Linux version "
+
+/* Size constants */
+#define TIME_FORMAT_SIZE (100)
+#define MAX_LOG_FILE_SIZE (1024*1024*5) //5MB
+#define TTY_LEN (50)
+#define LINE_LEN (257)
+#define MSG_LEN (1025)
+#define COMMAND_LEN (100)
+#define KERNEL_VERSION_LEN (100)
+
+static char *uS_console = "/usr/local/fbpackages/utils/us_console.sh";
+
+static char *error_log_file = "/var/log/bmc-log";
+
+static char *pseudo_tty_save_file = "/etc/us_pseudo_tty";
+
+static int kernel_search_len = sizeof(KERNEL_SEARCH_STR) - 1;
+
+#endif
diff --git a/meta-facebook/meta-wedge/recipes-wedge/bmc-log/files/bmc-log.sh b/meta-facebook/meta-wedge/recipes-wedge/bmc-log/files/bmc-log.sh
new file mode 100755
index 0000000..00bf63c
--- /dev/null
+++ b/meta-facebook/meta-wedge/recipes-wedge/bmc-log/files/bmc-log.sh
@@ -0,0 +1,77 @@
+#!/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: bmc-log
+# Required-Start:
+# Required-Stop:
+# Default-Start: S
+# Default-Stop:
+# Short-Description: Collect micro-server kernel logs through serial port
+### END INIT INFO
+
+. /etc/default/bmc-log
+. /etc/init.d/functions
+
+DAEMON=/usr/sbin/bmc-log
+NAME=bmc-log
+DESC="Micro-Server log collection"
+
+TTY=${US_TTY:-/dev/ttyS1}
+IP=${LOG_SERVER_IP_VERSION:-4}
+LOG_SERVER=${LOG_SERVER_NAME:-}
+PORT=${LOG_SERVER_PORT:-}
+BAUD_RATE=${TTY_BAUD_RATE:-}
+
+if [ -z "$LOG_SERVER" ] || [ -z "$PORT" ]
+then
+ echo "Error: Server and/or port not set"
+ exit 0
+fi
+
+
+ACTION="$1"
+
+case "$ACTION" in
+ start)
+ echo -e "Starting $DESC"
+ $DAEMON $TTY $IP $LOG_SERVER $PORT $BAUD_RATE
+ ;;
+ stop)
+ echo -e "Stopping $DESC: "
+ start-stop-daemon --stop --quiet --exec $DAEMON
+ ;;
+ restart|force-reload)
+ echo -e "Restarting $DESC: "
+ start-stop-daemon --stop --quiet --exec $DAEMON
+ sleep 1
+ $DAEMON $TTY $IP $LOG_SERVER $PORT $BAUD_RATE
+ ;;
+ status)
+ stat $DAEMON
+ exit $?
+ ;;
+ *)
+ N=${0##*/}
+ N=${N#[SK]??}
+ echo "Usage: $N {start|stop|status|restart|force-reload}" >&2
+ exit 1
+ ;;
+esac
diff --git a/meta-facebook/meta-wedge/recipes-wedge/fan-ctrl/fan-ctrl/setup-fan.sh b/meta-facebook/meta-wedge/recipes-wedge/fan-ctrl/fan-ctrl/setup-fan.sh
index 0cbdb24..146a787 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/fan-ctrl/fan-ctrl/setup-fan.sh
+++ b/meta-facebook/meta-wedge/recipes-wedge/fan-ctrl/fan-ctrl/setup-fan.sh
@@ -2,6 +2,22 @@
#
# 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: setup-fan
# Required-Start: board-id
@@ -11,7 +27,7 @@
# Short-Description: Set fan speed
### END INIT INFO
-. /usr/local/fbpackages/utils/ast-functions
+. /usr/local/bin/openbmc-utils.sh
# Enable the isolation buffer
wedge_iso_buf_enable
diff --git a/meta-facebook/meta-wedge/recipes-wedge/fan-ctrl/fan-ctrl_0.1.bbappend b/meta-facebook/meta-wedge/recipes-wedge/fan-ctrl/fan-ctrl_0.1.bbappend
new file mode 100644
index 0000000..ef2932e
--- /dev/null
+++ b/meta-facebook/meta-wedge/recipes-wedge/fan-ctrl/fan-ctrl_0.1.bbappend
@@ -0,0 +1,64 @@
+# 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
+
+DEPENDS_append = "libwedge-eeprom update-rc.d-native"
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+SRC_URI += "file://get_fan_speed.sh \
+ file://init_pwm.sh \
+ file://set_fan_speed.sh \
+ file://setup-fan.sh \
+ "
+
+S = "${WORKDIR}"
+
+binfiles += "get_fan_speed.sh \
+ init_pwm.sh \
+ set_fan_speed.sh \
+ "
+
+LDFLAGS_append = " -lwedge_eeprom"
+CXXFLAGS_prepend = "-DCONFIG_WEDGE "
+
+pkgdir = "fan_ctrl"
+
+do_install() {
+ dst="${D}/usr/local/fbpackages/${pkgdir}"
+ bin="${D}/usr/local/bin"
+ install -d $dst
+ install -d $bin
+ for f in ${binfiles}; do
+ install -m 755 $f ${dst}/$f
+ ln -snf ../fbpackages/${pkgdir}/$f ${bin}/$f
+ done
+ for f in ${otherfiles}; do
+ install -m 644 $f ${dst}/$f
+ done
+ install -d ${D}${sysconfdir}/init.d
+ install -d ${D}${sysconfdir}/rcS.d
+ install -m 755 setup-fan.sh ${D}${sysconfdir}/init.d/setup-fan.sh
+ update-rc.d -r ${D} setup-fan.sh start 91 S .
+}
+
+FBPACKAGEDIR = "${prefix}/local/fbpackages"
+
+FILES_${PN} = "${FBPACKAGEDIR}/fan_ctrl ${prefix}/local/bin ${sysconfdir} "
+
+# Inhibit complaints about .debug directories for the fand binary:
+
+INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
+INHIBIT_PACKAGE_STRIP = "1"
diff --git a/meta-facebook/meta-wedge/recipes-wedge/fblibs/files/alert_control/Makefile b/meta-facebook/meta-wedge/recipes-wedge/fblibs/files/alert_control/Makefile
index 74ce8f3..2f27a8c 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/fblibs/files/alert_control/Makefile
+++ b/meta-facebook/meta-wedge/recipes-wedge/fblibs/files/alert_control/Makefile
@@ -1,8 +1,24 @@
# 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
+
lib: libalert_control.so
libalert_control.so: alert_control.c
- $(CC) $(CCFLAGS) -fPIC -c -o alert_control.o alert_control.c
+ $(CC) $(CFLAGS) -fPIC -c -o alert_control.o alert_control.c
$(CC) -shared -o libalert_control.so alert_control.o -lc
.PHONY: clean
diff --git a/meta-facebook/meta-wedge/recipes-wedge/fblibs/files/ipmi/Makefile b/meta-facebook/meta-wedge/recipes-wedge/fblibs/files/ipmi/Makefile
index 8cb69e7..369819c 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/fblibs/files/ipmi/Makefile
+++ b/meta-facebook/meta-wedge/recipes-wedge/fblibs/files/ipmi/Makefile
@@ -1,8 +1,24 @@
# 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
+
lib: libipmi.so
libipmi.so: ipmi.c
- $(CC) $(CCFLAGS) -fPIC -c -o ipmi.o ipmi.c
+ $(CC) $(CFLAGS) -fPIC -c -o ipmi.o ipmi.c
$(CC) -shared -o libipmi.so ipmi.o -lc
.PHONY: clean
diff --git a/meta-facebook/meta-wedge/recipes-wedge/fblibs/libalert-control_0.1.bb b/meta-facebook/meta-wedge/recipes-wedge/fblibs/libalert-control_0.1.bb
index 2ae4ea7..ec02d04 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/fblibs/libalert-control_0.1.bb
+++ b/meta-facebook/meta-wedge/recipes-wedge/fblibs/libalert-control_0.1.bb
@@ -1,4 +1,19 @@
# 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
SUMMARY = "Wedge Alert Control Library"
DESCRIPTION = "library for Wedge Alert Control"
SECTION = "base"
@@ -20,5 +35,4 @@ do_install() {
}
FILES_${PN} = "${libdir}/libalert_control.so"
-FILES_${PN}-dbg = "${libdir}/.debug"
FILES_${PN}-dev = "${includedir}/facebook/alert_control.h"
diff --git a/meta-facebook/meta-wedge/recipes-wedge/fblibs/libipmi_0.1.bb b/meta-facebook/meta-wedge/recipes-wedge/fblibs/libipmi_0.1.bb
index 0b6f3d3..83292be 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/fblibs/libipmi_0.1.bb
+++ b/meta-facebook/meta-wedge/recipes-wedge/fblibs/libipmi_0.1.bb
@@ -1,4 +1,19 @@
# 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
SUMMARY = "Wedge IPMI Client Library"
DESCRIPTION = "library for Wedge IPMI Client"
SECTION = "base"
@@ -21,5 +36,4 @@ do_install() {
}
FILES_${PN} = "${libdir}/libipmi.so"
-FILES_${PN}-dbg = "${libdir}/.debug"
FILES_${PN}-dev = "${includedir}/facebook/ipmi.h"
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
diff --git a/meta-facebook/meta-wedge/recipes-wedge/fbutils/openbmc-utils_%.bbappend b/meta-facebook/meta-wedge/recipes-wedge/fbutils/openbmc-utils_%.bbappend
new file mode 100644
index 0000000..d6641c9
--- /dev/null
+++ b/meta-facebook/meta-wedge/recipes-wedge/fbutils/openbmc-utils_%.bbappend
@@ -0,0 +1,95 @@
+# 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
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+SRC_URI += "file://board-utils.sh \
+ file://us_console.sh \
+ file://sol.sh \
+ file://power_led.sh \
+ file://post_led.sh \
+ file://reset_usb.sh \
+ file://setup-gpio.sh \
+ file://setup_rov.sh \
+ file://mdio.py \
+ file://bcm5396.py \
+ file://bcm5396_util.py \
+ file://at93cx6.py \
+ file://at93cx6_util.py \
+ file://mount_data0.sh \
+ file://eth0_mac_fixup.sh \
+ file://wedge_power.sh \
+ file://power-on.sh \
+ file://wedge_us_mac.sh \
+ file://setup_switch.py \
+ file://create_vlan_intf \
+ file://rc.early \
+ file://rc.local \
+ file://src \
+ file://start_us_monitor.sh \
+ file://us_monitor.sh \
+ "
+
+OPENBMC_UTILS_FILES += " \
+ board-utils.sh us_console.sh sol.sh power_led.sh post_led.sh \
+ reset_usb.sh mdio.py setup_rov.sh wedge_power.sh wedge_us_mac.sh \
+ bcm5396.py bcm5396_util.py setup_switch.py us_monitor.sh \
+ at93cx6.py at93cx6_util.py \
+ "
+
+DEPENDS_append = "update-rc.d-native"
+
+do_install_board() {
+ # for backward compatible, create /usr/local/fbpackages/utils/ast-functions
+ olddir="/usr/local/fbpackages/utils"
+ install -d ${D}${olddir}
+ ln -s "/usr/local/bin/openbmc-utils.sh" ${D}${olddir}/ast-functions
+
+ # common lib and include files
+ install -d ${D}${includedir}/facebook
+ install -m 0644 src/include/i2c-dev.h ${D}${includedir}/facebook/i2c-dev.h
+
+ # init
+ install -d ${D}${sysconfdir}/init.d
+ install -d ${D}${sysconfdir}/rcS.d
+ # the script to mount /mnt/data
+ install -m 0755 ${WORKDIR}/mount_data0.sh ${D}${sysconfdir}/init.d/mount_data0.sh
+ update-rc.d -r ${D} mount_data0.sh start 03 S .
+ install -m 0755 ${WORKDIR}/rc.early ${D}${sysconfdir}/init.d/rc.early
+ update-rc.d -r ${D} rc.early start 04 S .
+ install -m 755 setup-gpio.sh ${D}${sysconfdir}/init.d/setup-gpio.sh
+ update-rc.d -r ${D} setup-gpio.sh start 59 S .
+ # create VLAN intf automatically
+ install -d ${D}/${sysconfdir}/network/if-up.d
+ install -m 755 create_vlan_intf ${D}${sysconfdir}/network/if-up.d/create_vlan_intf
+ # networking is done after rcS, any start level within rcS
+ # for mac fixup should work
+ install -m 755 eth0_mac_fixup.sh ${D}${sysconfdir}/init.d/eth0_mac_fixup.sh
+ update-rc.d -r ${D} eth0_mac_fixup.sh start 70 S .
+ install -m 755 start_us_monitor.sh ${D}${sysconfdir}/init.d/start_us_monitor.sh
+ update-rc.d -r ${D} start_us_monitor.sh start 84 S .
+ install -m 755 power-on.sh ${D}${sysconfdir}/init.d/power-on.sh
+ update-rc.d -r ${D} power-on.sh start 85 S .
+ install -m 0755 ${WORKDIR}/rc.local ${D}${sysconfdir}/init.d/rc.local
+ update-rc.d -r ${D} rc.local start 99 2 3 4 5 .
+}
+
+do_install_append() {
+ do_install_board
+}
+
+FILES_${PN} += "${sysconfdir}"
diff --git a/meta-facebook/meta-wedge/recipes-wedge/ipmid/files/Makefile b/meta-facebook/meta-wedge/recipes-wedge/ipmid/files/Makefile
index 8282964..c21df07 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/ipmid/files/Makefile
+++ b/meta-facebook/meta-wedge/recipes-wedge/ipmid/files/Makefile
@@ -1,4 +1,20 @@
# 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
+
all: ipmid
ipmid: ipmid.c \
diff --git a/meta-facebook/meta-wedge/recipes-wedge/ipmid/files/setup-ipmid.sh b/meta-facebook/meta-wedge/recipes-wedge/ipmid/files/setup-ipmid.sh
index b1fbbb1..b724d70 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/ipmid/files/setup-ipmid.sh
+++ b/meta-facebook/meta-wedge/recipes-wedge/ipmid/files/setup-ipmid.sh
@@ -2,6 +2,22 @@
#
# 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: setup-ipmid
# Required-Start:
diff --git a/meta-facebook/meta-wedge/recipes-wedge/ipmid/ipmid_0.1.bb b/meta-facebook/meta-wedge/recipes-wedge/ipmid/ipmid_0.1.bb
index 3f9c4a7..7d8fd37 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/ipmid/ipmid_0.1.bb
+++ b/meta-facebook/meta-wedge/recipes-wedge/ipmid/ipmid_0.1.bb
@@ -1,4 +1,19 @@
# 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
SUMMARY = "IPMI Daemon"
DESCRIPTION = "Daemon to handle IPMI Messages."
diff --git a/meta-facebook/meta-wedge/recipes-wedge/lm_sensors/lmsensors_%.bbappend b/meta-facebook/meta-wedge/recipes-wedge/lm_sensors/lmsensors_%.bbappend
index 35433ae..90a3954 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/lm_sensors/lmsensors_%.bbappend
+++ b/meta-facebook/meta-wedge/recipes-wedge/lm_sensors/lmsensors_%.bbappend
@@ -4,7 +4,11 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
SRC_URI += "file://wedge.conf \
"
-do_install_append() {
+do_install_board_config() {
install -d ${D}${sysconfdir}/sensors.d
install -m 644 ../wedge.conf ${D}${sysconfdir}/sensors.d/wedge.conf
}
+
+do_install_append() {
+ do_install_board_config
+}
diff --git a/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/Makefile b/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/Makefile
index 0c9f49f..00464e5 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/Makefile
+++ b/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/Makefile
@@ -1,4 +1,20 @@
# 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
+
all: oob-nic i2craw
oob-nic: main.o nic.o intf.o ll_map.o libnetlink.o
diff --git a/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/etc/oob-nic.sh b/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/etc/oob-nic.sh
index 35e1a2a..7eaf581 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/etc/oob-nic.sh
+++ b/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/etc/oob-nic.sh
@@ -40,14 +40,12 @@ DESC="OOB NIC Driver"
test -f $DAEMON || exit 0
# enable the isolation buffer
-. /usr/local/fbpackages/utils/ast-functions
-wedge_iso_buf_enable
+. /usr/local/bin/openbmc-utils.sh
fix_etc_interfaces() {
- local intf_conf rev
- intf_conf="/etc/network/interfaces"
- rev=$(wedge_board_rev)
- if [ $rev -lt 3 ]; then
+ local intf_conf board_rev board_type enable_oob
+ if wedge_should_enable_oob; then
+ intf_conf="/etc/network/interfaces"
if ! grep oob $intf_conf > /dev/null 2>&1; then
echo >> $intf_conf
echo "auto oob" >> $intf_conf
diff --git a/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/i2craw.c b/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/i2craw.c
index f9d499b..83f03b7 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/i2craw.c
+++ b/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/i2craw.c
@@ -27,7 +27,7 @@
#include <stdint.h>
#include "facebook/i2c-dev.h"
-#include "facebook/log.h"
+#include "openbmc/log.h"
void usage(const char *prog) {
printf("Usage: %s [options] <bus number> <slave address>\n", prog);
diff --git a/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/intf.c b/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/intf.c
index 5bf8480..81834b9 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/intf.c
+++ b/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/intf.c
@@ -32,7 +32,7 @@
#include <linux/if_tun.h>
#include <linux/fib_rules.h>
-#include "facebook/log.h"
+#include "openbmc/log.h"
#include "libnetlink.h"
#include "ll_map.h"
diff --git a/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/main.c b/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/main.c
index 4312402..2dc1917 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/main.c
+++ b/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/main.c
@@ -24,7 +24,7 @@
#include "nic.h"
#include "intf.h"
-#include "facebook/log.h"
+#include "openbmc/log.h"
#include "facebook/wedge_eeprom.h"
#define WAIT4PACKET_TIMEOUT 10000 /* 10ms */
@@ -129,28 +129,40 @@ int main(int argc, const char **argv) {
/* read EEPROM for the MAC */
if (wedge_eeprom_parse(NULL, &eeprom) == 0) {
- if (eeprom.fbw_mac_size <= 0) {
+ uint16_t carry;
+ int pos;
+ int adj;
+ /*
+ * OOB MAC comes from this range. We pick the last MAC from the range to
+ * use as OOB MAC.
+ */
+ if (eeprom.fbw_mac_size > 128) {
+ LOG_ERR(EFAULT, "Extended MAC size (%d) is too large.",
+ eeprom.fbw_mac_size);
+ carry = 128;
+ } else {
+ carry = eeprom.fbw_mac_size;
+ }
+
+ /*
+ * Due to various manufacture issues, some FC boards have MAC range overlap
+ * between LEFT and RIGHT sides. A SW workaround is done below to use the
+ * 8th (or 7th for right side FC) last MAC from the range for FC.
+ */
+ if (strncmp(eeprom.fbw_location, "LEFT", FBW_EEPROM_F_LOCATION) == 0) {
+ adj = 8;
+ } else if (strncmp(eeprom.fbw_location, "RIGHT", FBW_EEPROM_F_LOCATION)
+ == 0) {
+ adj = 7;
+ } else {
+ adj = 1;
+ }
+
+ if (carry < adj) {
LOG_ERR(EFAULT, "Invalid extended MAC size: %d", eeprom.fbw_mac_size);
} else {
- uint16_t carry;
- int pos;
- /* use the last MAC address from the extended MAC range */
+ carry -= adj;
memcpy(mac, eeprom.fbw_mac_base, sizeof(mac));
- if (eeprom.fbw_mac_size > 128) {
- LOG_ERR(EFAULT, "Extended MAC size (%d) is too large.",
- eeprom.fbw_mac_size);
- carry = 127;
- } else {
- /*
- * hack around bug device which have the same MAC address on
- * left and right.
- */
- if (strncmp(eeprom.fbw_location, "LEFT", FBW_EEPROM_F_LOCATION) == 0) {
- carry = eeprom.fbw_mac_size - 2;
- } else {
- carry = eeprom.fbw_mac_size - 1;
- }
- }
for (pos = sizeof(mac) - 1; pos >= 0 && carry; pos--) {
uint16_t tmp = mac[pos] + carry;
mac[pos] = tmp & 0xFF;
diff --git a/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/nic.c b/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/nic.c
index a4dc071..c5fa422 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/nic.c
+++ b/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/nic.c
@@ -17,6 +17,7 @@
*/
#include "nic.h"
+#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
@@ -26,7 +27,9 @@
#include <sys/types.h>
#include "facebook/i2c-dev.h"
-#include "facebook/log.h"
+#include "openbmc/log.h"
+
+#define ETHERTYPE_LLDP 0x88cc
struct oob_nic_t {
int on_bus;
@@ -334,12 +337,25 @@ static int oob_nic_set_force_up(oob_nic *dev, int enable) {
static int oob_nic_setup_filters(oob_nic *dev, const uint8_t mac[6]) {
int rc;
- int i;
uint32_t cmd32;
uint8_t buf[32];
uint8_t *cmd;
/*
+ * There are 8 filters in total (MDEF0-MDEF7). Any filter that has a
+ * configuration will be applied. Any packet that matches any filter will
+ * be passed to OOB by the main NIC.
+ *
+ * Each filter has two sets of bits, MDEF and MDEF_EXT. Each bit in the
+ * filter represents a filter with its logical operation. For example,
+ * NIC_FILTER_MDEF_MAC_AND_OFFSET(0) represent MAC filter 0 using AND
+ * operation. So, in order to receive packets matching a specific MAC, MAC0
+ * filter (NIC_FILTER_MAC_NUM:NIC_FILTER_MAC_PAIR0) must be programmed
+ * with the specific MAC. Then set NIC_FILTER_MDEF_MAC_AND_OFFSET (for
+ * AND) or NIC_FILTER_MDEF_MAC_OR_OFFSET (for OR) in one of the filters.
+ */
+
+ /*
* Command to set MAC filter
* Seven bytes are required to load the MAC address filters.
* Data 2—MAC address filters pair number (3:0).
@@ -351,9 +367,8 @@ static int oob_nic_setup_filters(oob_nic *dev, const uint8_t mac[6]) {
cmd = buf;
*cmd++ = NIC_FILTER_MAC_NUM;
*cmd++ = NIC_FILTER_MAC_PAIR0; /* pair 0 */
- for (i = 0; i < 6; i++) {
- *cmd++ = mac[i];
- }
+ memcpy(cmd, mac, 6);
+ cmd += 6;
rc = i2c_smbus_write_block_data(dev->on_file, NIC_WRITE_FILTER_CMD,
cmd - buf, buf);
if (rc < 0) {
@@ -380,17 +395,15 @@ static int oob_nic_setup_filters(oob_nic *dev, const uint8_t mac[6]) {
*cmd++ = NIC_FILTER_DECISION_EXT_NUM;
*cmd++ = NIC_FILTER_MDEF0;
/* enable filter for traffic from network and host */
- cmd32 = NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_EXT_NET_EN_OFFSET)
- | NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_EXT_HOST_EN_OFFSET);
- for (i = 0; i < sizeof(cmd32); i++) {
- *cmd++ = (cmd32 >> (24 - 8 * i)) & 0xFF;
- }
+ cmd32 = htonl(NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_EXT_NET_EN_OFFSET)
+ | NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_EXT_HOST_EN_OFFSET));
+ memcpy(cmd, &cmd32, sizeof(cmd32));
+ cmd += sizeof(cmd32);
/* enable mac pair 0 */
- cmd32 = NIC_FILTER_MDEF_BIT_VAL(NIC_FILTER_MDEF_MAC_AND_OFFSET,
- NIC_FILTER_MAC_PAIR0);
- for (i = 0; i < sizeof(cmd32); i++) {
- *cmd++ = (cmd32 >> (24 - 8 * i)) & 0xFF;
- }
+ cmd32 = htonl(NIC_FILTER_MDEF_BIT_VAL(NIC_FILTER_MDEF_MAC_AND_OFFSET,
+ NIC_FILTER_MAC_PAIR0));
+ memcpy(cmd, &cmd32, sizeof(cmd32));
+ cmd += sizeof(cmd32);
rc = i2c_smbus_write_block_data(dev->on_file, NIC_WRITE_FILTER_CMD,
cmd - buf, buf);
if (rc < 0) {
@@ -398,23 +411,41 @@ static int oob_nic_setup_filters(oob_nic *dev, const uint8_t mac[6]) {
LOG_ERR(rc, "Failed to set MAC filter to MDEF 0");
return -rc;
}
- /* enable ARP and ND on filter 1*/
+
+ /* Program EtherType0 to match LLDP */
+ cmd = buf;
+ *cmd++ = NIC_FILTER_ETHERTYPE_NUM;
+ *cmd++ = NIC_FILTER_ETHERTYPE0;
+ cmd32 = htonl(ETHERTYPE_LLDP);
+ memcpy(cmd, &cmd32, sizeof(cmd32));
+ cmd += sizeof(cmd32);
+ rc = i2c_smbus_write_block_data(dev->on_file, NIC_WRITE_FILTER_CMD,
+ cmd - buf, buf);
+ if (rc < 0) {
+ rc = errno;
+ LOG_ERR(rc, "Failed to program EtherType0 to match LLDP");
+ return -rc;
+ }
+
+ /* enable ARP, ND, and EtheryType0 (OR) on filter 1 */
cmd = buf;
*cmd++ = NIC_FILTER_DECISION_EXT_NUM;
*cmd++ = NIC_FILTER_MDEF1;
- /* enable filter for traffic from network and host */
- cmd32 = NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_EXT_NET_EN_OFFSET)
- | NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_EXT_HOST_EN_OFFSET);
- for (i = 0; i < sizeof(cmd32); i++) {
- *cmd++ = (cmd32 >> (24 - 8 * i)) & 0xFF;
- }
+ /* enable filter for traffic from network and host, matching ethertype0 */
+ cmd32 = htonl(NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_EXT_NET_EN_OFFSET)
+ | NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_EXT_HOST_EN_OFFSET)
+ | NIC_FILTER_MDEF_BIT_VAL(
+ NIC_FILTER_MDEF_EXT_ETHTYPE_OR_OFFSET,
+ NIC_FILTER_ETHERTYPE0));
+ memcpy(cmd, &cmd32, sizeof(cmd32));
+ cmd += sizeof(cmd32);
+
/* enable ARP and ND */
- cmd32 = NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_ARP_REQ_OR_OFFSET)
- | NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_ARP_RES_OR_OFFSET)
- | NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_NBG_OR_OFFSET);
- for (i = 0; i < sizeof(cmd32); i++) {
- *cmd++ = (cmd32 >> (24 - 8 * i)) & 0xFF;
- }
+ cmd32 = htonl(NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_ARP_REQ_OR_OFFSET)
+ | NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_ARP_RES_OR_OFFSET)
+ | NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_NBG_OR_OFFSET));
+ memcpy(cmd, &cmd32, sizeof(cmd32));
+ cmd += sizeof(cmd32);
rc = i2c_smbus_write_block_data(dev->on_file, NIC_WRITE_FILTER_CMD,
cmd - buf, buf);
if (rc < 0) {
@@ -426,10 +457,9 @@ static int oob_nic_setup_filters(oob_nic *dev, const uint8_t mac[6]) {
/* make filter 0, matching MAC, to be mng only */
cmd = buf;
*cmd++ = NIC_FILTER_MNG_ONLY_NUM;
- cmd32 = NIC_FILTER_MNG_ONLY_FILTER0;
- for (i = 0; i < sizeof(cmd32); i++) {
- *cmd++ = (cmd32 >> (24 - 8 * i)) & 0xFF;
- }
+ cmd32 = htonl(NIC_FILTER_MNG_ONLY_FILTER0);
+ memcpy(cmd, &cmd32, sizeof(cmd32));
+ cmd += sizeof(cmd32);
rc = i2c_smbus_write_block_data(dev->on_file, NIC_WRITE_FILTER_CMD,
cmd - buf, buf);
if (rc < 0) {
diff --git a/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/nic_defs.h b/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/nic_defs.h
index 1ae8721..87574f0 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/nic_defs.h
+++ b/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic/src/nic_defs.h
@@ -76,12 +76,6 @@ struct oob_nic_status_t {
/** Update MNG RCV Filter Parameters */
#define NIC_WRITE_FILTER_CMD 0xCC
-#define NIC_FILTER_MAC_NUM 0x66
-#define NIC_FILTER_MAC_PAIR0 0
-#define NIC_FILTER_MAC_PAIR1 1
-#define NIC_FILTER_MAC_PAIR2 2
-#define NIC_FILTER_MAC_PAIR3 3
-
#define NIC_FILTER_MNG_ONLY_NUM 0xF
#define NIC_FILTER_MNG_ONLY_FILTER0 (0x1)
#define NIC_FILTER_MNG_ONLY_FILTER1 (0x1 << 1)
@@ -89,6 +83,18 @@ struct oob_nic_status_t {
#define NIC_FILTER_MNG_ONLY_FILTER3 (0x1 << 3)
#define NIC_FILTER_MNG_ONLY_FILTER4 (0x1 << 4)
+#define NIC_FILTER_MAC_NUM 0x66
+#define NIC_FILTER_MAC_PAIR0 0
+#define NIC_FILTER_MAC_PAIR1 1
+#define NIC_FILTER_MAC_PAIR2 2
+#define NIC_FILTER_MAC_PAIR3 3
+
+#define NIC_FILTER_ETHERTYPE_NUM 0x67
+#define NIC_FILTER_ETHERTYPE0 0
+#define NIC_FILTER_ETHERTYPE1 1
+#define NIC_FILTER_ETHERTYPE2 2
+#define NIC_FILTER_ETHERTYPE3 3
+
#define NIC_FILTER_DECISION_EXT_NUM 0x68
#define NIC_FILTER_MDEF0 0 /* index 0 */
#define NIC_FILTER_MDEF1 1 /* index 1 */
diff --git a/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic_0.1.bb b/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic_0.1.bb
index 1df83dc..82a5296 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic_0.1.bb
+++ b/meta-facebook/meta-wedge/recipes-wedge/oob-nic/oob-nic_0.1.bb
@@ -1,4 +1,19 @@
# 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
SUMMARY = "OOB Shared NIC driver"
DESCRIPTION = "The shared-nic driver"
@@ -12,7 +27,7 @@ SRC_URI = "file://src \
S = "${WORKDIR}/src"
-DEPENDS += "fbutils libwedge-eeprom"
+DEPENDS += "openbmc-utils liblog libwedge-eeprom"
RDEPENDS_${PN} += "libwedge-eeprom"
diff --git a/meta-facebook/meta-wedge/recipes-wedge/po-eeprom/files/Makefile b/meta-facebook/meta-wedge/recipes-wedge/po-eeprom/files/Makefile
index 408de95..0b3fd71 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/po-eeprom/files/Makefile
+++ b/meta-facebook/meta-wedge/recipes-wedge/po-eeprom/files/Makefile
@@ -1,4 +1,20 @@
# 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
+
all: po-eeprom
po-eeprom: po-eeprom.o
diff --git a/meta-facebook/meta-wedge/recipes-wedge/po-eeprom/po-eeprom_0.1.bb b/meta-facebook/meta-wedge/recipes-wedge/po-eeprom/po-eeprom_0.1.bb
index e1d8b32..ad635dc 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/po-eeprom/po-eeprom_0.1.bb
+++ b/meta-facebook/meta-wedge/recipes-wedge/po-eeprom/po-eeprom_0.1.bb
@@ -1,4 +1,21 @@
# 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
+#
+
SUMMARY = "PowerOne EEPROM Utilities"
DESCRIPTION = "Util for PowerOne eeprom"
SECTION = "base"
diff --git a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/Makefile b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/Makefile
index 4a3c25d..926bf52 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/Makefile
+++ b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/Makefile
@@ -1,16 +1,40 @@
# Copyright 2014-present Facebook. All Rights Reserved.
-all: modbuscmd gpiowatch modbussim
+#
+# 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
+
+override CFLAGS+=-D_GNU_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=199309 -Wall -Werror -std=c99
+override LDFLAGS+=-pthread
+all: modbuscmd gpiowatch modbussim rackmond rackmondata
+
+rackmondata: rackmondata.c modbus.c
+ $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
+
+rackmond: rackmond.c modbus.c
+ $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
modbuscmd: modbuscmd.c modbus.c
- $(CC) -D_BSD_SOURCE -Wall -Werror -std=c99 -o $@ $^ $(LDFLAGS)
+ $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
modbussim: modbussim.c modbus.c
- $(CC) -D_BSD_SOURCE -Wall -Werror -std=c99 -o $@ $^ $(LDFLAGS)
+ $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
gpiowatch: gpiowatch.c
- $(CC) -D_BSD_SOURCE -Wall -Werror -std=c99 -o $@ $^ $(LDFLAGS)
+ $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
.PHONY: clean
clean:
- rm -rf *.o modbuscmd gpiowatch modbussim
+ rm -rf *.o modbuscmd gpiowatch modbussim rackmond rackmondata
diff --git a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/hexfile.py b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/hexfile.py
new file mode 100644
index 0000000..c484fdf
--- /dev/null
+++ b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/hexfile.py
@@ -0,0 +1,174 @@
+# The MIT License (MIT)
+# =====================
+#
+# Copyright (c) 2014 Ryan Sturmer
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+# https://github.com/ryansturmer/hexfile/blob/master/hexfile/core.py
+
+import itertools
+
+def short(msb,lsb):
+ return (msb<<8) | lsb
+
+class HexFile(object):
+ def __init__(self, segments):
+ self.segments = segments
+
+ def __getitem__(self, val):
+ if isinstance(val, slice):
+ address = val.start
+ else:
+ address = val
+
+ for segment in self.segments:
+ if address in segment:
+ return segment[val]
+
+ raise IndexError('No segment contains address 0x%x' % address)
+
+ def __len__(self):
+ return sum(map(len, self.segments))
+
+ @property
+ def size(self):
+ return len(self)
+
+ def __iter__(self):
+ return itertools.chain(*self.segments)
+
+ @staticmethod
+ def load(filename):
+ segments = [Segment(0)]
+
+ with open(filename) as fp:
+ lines = fp.readlines()
+
+ extended_linear_address = 0
+ current_address = 0
+ end_of_file = False
+
+ lineno = 0
+ for line in lines:
+ lineno += 1
+ line = line.strip();
+ if not line.startswith(':'):
+ continue
+
+ if end_of_file:
+ raise Exception("Record found after end of file on line %d" % lineno)
+
+ bytes = [int(line[i:i+2], 16) for i in range(1,len(line), 2)]
+ byte_count = bytes[0]
+ address = short(*bytes[1:3])
+ record_type = bytes[3]
+ checksum = bytes[-1]
+ data = bytes[4:-1]
+ computed_checksum = ((1 << 8)-(sum(bytes[:-1]) & 0xff)) & 0xff
+
+ if(computed_checksum != checksum):
+ raise Exception("Record checksum doesn't match on line %d" % lineno)
+
+ if record_type == 0:
+ if byte_count == len(data):
+ current_address = (address | extended_linear_address)
+ have_segment = False
+ for segment in segments:
+ if segment.end_address == current_address:
+ segment.data.extend(data)
+ have_segment = True
+ break
+ if not have_segment:
+ segments.append(Segment(current_address, data))
+ else:
+ raise Exception("Data record reported size does not match actual size on line %d" % lineno)
+ elif record_type == 1:
+ end_of_file = True
+ elif record_type == 4:
+ if byte_count != 2 or len(data) != 2:
+ raise Exception("Byte count misreported in extended linear address record on line %d" % lineno)
+ extended_linear_address = short(*data) << 16
+
+ else:
+ raise Exception("Unknown record type: %s" % record_type)
+ return HexFile(segments)
+
+ def pretty_string(self, stride=16):
+ retval = []
+ for segment in self.segments:
+ retval.append('Segment @ 0x%08x (%d bytes)' % (segment.start_address, segment.size))
+ retval.append(segment.pretty_string(stride=stride))
+ retval.append('')
+ return '\n'.join(retval)
+
+def load(filename):
+ return HexFile.load(filename)
+
+class Segment(object):
+ def __init__(self, start_address, data = None):
+ self.start_address = start_address
+ self.data = data or []
+
+ def pretty_string(self, stride=16):
+ retval = []
+ addresses = self.addresses
+ ranges = [addresses[i:i+stride] for i in range(0, self.size, stride)]
+ for r in ranges:
+ retval.append('%08x ' % r[0] + ' '.join(['%02x' % self[addr] for addr in r]))
+ return '\n'.join(retval)
+
+ def __str__(self):
+ return '<%d byte segment @ 0x%08x>' % (self.size, self.start_address)
+ def __repr__(self):
+ return str(self)
+
+ @property
+ def end_address(self):
+ return self.start_address + len(self.data)
+
+ @property
+ def size(self):
+ return len(self.data)
+
+ def __contains__(self, address):
+ return address >= self.start_address and address < self.end_address
+
+ def __getitem__(self, address):
+ if isinstance(address, slice):
+ if address.start not in self or address.stop-1 not in self:
+ raise IndexError('Address out of range for this segment')
+ else:
+ d = self.data[address.start-self.start_address:address.stop-self.start_address:address.step]
+ start_address = address.start + self.start_address
+ return Segment(start_address, d)
+ else:
+ if not address in self:
+ raise IndexError("Address 0x%x is not in this segment" % address)
+ return self.data[address-self.start_address]
+
+ @property
+ def addresses(self):
+ return range(self.start_address, self.end_address)
+
+ def __len__(self):
+ return len(self.data)
+
+ def __iter__(self):
+ return iter(self.data)
diff --git a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/modbus.c b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/modbus.c
index 46618a9..8fb0835 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/modbus.c
+++ b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/modbus.c
@@ -16,6 +16,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <time.h>
#include "modbus.h"
#include <termios.h>
#include <unistd.h>
@@ -26,9 +27,15 @@
#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>
+#include <sched.h>
+#include <pthread.h>
-static int loops = 0;
-void waitfd(int fd) {
+int verbose = 0;
+
+#define TIOCSERWAITTEMT 0x5499
+int waitfd(int fd) {
+ int loops = 0;
+ ioctl(fd, TIOCSERWAITTEMT, DEFAULT_GPIO);
while(1) {
int lsr;
int ret = ioctl(fd, TIOCSERGETLSR, &lsr);
@@ -37,8 +44,10 @@ void waitfd(int fd) {
break;
}
if(lsr & TIOCSER_TEMT) break;
+ // never should hit this with new ioctl
loops++;
}
+ return loops;
}
void gpio_on(int fd) {
@@ -60,8 +69,7 @@ void decode_hex_in_place(char* buf, size_t* len) {
void append_modbus_crc16(char* buf, size_t* len) {
uint16_t crc = modbus_crc16(buf, *len);
- if (verbose)
- fprintf(stderr, "[*] Append Modbus CRC16 %04x\n", crc);
+ dbg("[*] Append Modbus CRC16 %04x\n", crc);
buf[(*len)++] = crc >> 8;
buf[(*len)++] = crc & 0x00FF;
}
@@ -78,7 +86,7 @@ size_t read_wait(int fd, char* dst, size_t maxlen, int mdelay_us) {
size_t read_size = 0;
size_t pos = 0;
memset(dst, 0, maxlen);
- for(;;) {
+ while(pos < maxlen) {
FD_ZERO(&fdset);
FD_SET(fd, &fdset);
timeout.tv_sec = 0;
@@ -95,10 +103,11 @@ size_t read_wait(int fd, char* dst, size_t maxlen, int mdelay_us) {
fprintf(stderr, "read error: %s\n", strerror(errno));
exit(1);
}
- if((pos + read_size) < maxlen) {
+ if((pos + read_size) <= maxlen) {
memcpy(dst + pos, read_buf, read_size);
pos += read_size;
} else {
+ return pos;
fprintf(stderr, "Response buffer overflowed!\n");
}
}
@@ -181,3 +190,163 @@ uint16_t modbus_crc16(char* buffer, size_t buffer_length) {
return (crc_hi << 8 | crc_lo);
}
+
+
+double ts_diff (struct timespec* begin, struct timespec* end) {
+ return 1000.0 * (end->tv_sec) + (1e-6 * end->tv_nsec)
+ - (1000.0 * (begin->tv_sec) + (1e-6 * begin->tv_nsec));
+}
+
+static long success = 0;
+static long crcfail = 0;
+static long timeout = 0;
+static long stat_wait = 0;
+
+int modbuscmd(modbus_req *req) {
+ int error = 0;
+ struct termios tio;
+ char modbus_cmd[req->cmd_len + 2];
+ size_t cmd_len = req->cmd_len;
+
+ if (verbose)
+ fprintf(stderr, "[*] Setting TTY flags!\n");
+ memset(&tio, 0, sizeof(tio));
+ // CREAD should be left *off* until we've confirmed THRE
+ // to avoid catching false character starts
+ cfsetspeed(&tio,B19200);
+ tio.c_cflag |= PARENB;
+ tio.c_cflag |= CLOCAL;
+ tio.c_cflag |= CS8;
+ tio.c_iflag |= INPCK;
+ tio.c_cc[VMIN] = 1;
+ tio.c_cc[VTIME] = 0;
+ CHECK(tcsetattr(req->tty_fd,TCSANOW,&tio));
+
+ memcpy(modbus_cmd, req->modbus_cmd, cmd_len);
+ append_modbus_crc16(modbus_cmd, &cmd_len);
+
+ // print command as sent
+ if (verbose) {
+ fprintf(stderr, "Will send: ");
+ print_hex(stderr, modbus_cmd, cmd_len);
+ fprintf(stderr, "\n");
+ }
+
+ dbg("[*] Writing!\n");
+
+ // hoped adding the ioctl to do the switching would have alleviated the
+ // need to do SCHED_FIFO, but we still get preempted between the write and
+ // ioctl syscalls w/o it often enough to break f/w updates.
+ struct sched_param sp;
+ sp.sched_priority = 50;
+ int policy = SCHED_FIFO;
+ CHECKP(sched, pthread_setschedparam(pthread_self(), policy, &sp));
+ // gpio on, write, wait, gpio off
+ gpio_on(req->gpio_fd);
+ struct timespec write_begin;
+ struct timespec wait_begin;
+ struct timespec wait_end;
+ struct timespec read_end;
+ clock_gettime(CLOCK_MONOTONIC_RAW, &write_begin);
+ write(req->tty_fd, modbus_cmd, cmd_len);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &wait_begin);
+ int waitloops = waitfd(req->tty_fd);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &wait_end);
+ gpio_off(req->gpio_fd);
+ sp.sched_priority = 0;
+ // Enable UART read
+ tio.c_cflag |= CREAD;
+ CHECK(tcsetattr(req->tty_fd,TCSANOW,&tio));
+ policy = SCHED_OTHER;
+ CHECKP(sched, pthread_setschedparam(pthread_self(), policy, &sp));
+
+ dbg("[*] waitfd loops: %d\n", waitloops);
+ dbg("[*] reading any response...\n");
+ // Read back response
+ size_t mb_pos = 0;
+ memset(req->dest_buf, 0, req->dest_limit);
+ if(req->expected_len == 0) {
+ req->expected_len = req->dest_limit;
+ }
+ if(req->expected_len > req->dest_limit) {
+ return -1;
+ }
+ mb_pos = read_wait(req->tty_fd, req->dest_buf, req->expected_len, req->timeout);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &read_end);
+ req->dest_len = mb_pos;
+ if(mb_pos >= 4) {
+ uint16_t crc = modbus_crc16(req->dest_buf, mb_pos - 2);
+ dbg("Modbus response CRC: %04X\n ", crc);
+ if((req->dest_buf[mb_pos - 2] == (crc >> 8)) &&
+ (req->dest_buf[mb_pos - 1] == (crc & 0x00FF))) {
+ dbg("CRC OK!\n");
+ } else {
+ dbg("BAD CRC :(\n");
+ fprintf(stderr, "bad crc timings:");
+ fprintf(stderr, " write: %.2f ms", ts_diff(&write_begin, &wait_begin));
+ fprintf(stderr, " wait: %.2f ms", ts_diff(&wait_begin, &wait_end));
+ fprintf(stderr, " read: %.2f ms\n", ts_diff(&wait_end, &read_end));
+ if(!req->scan) {
+ crcfail++;
+ }
+ if(verbose) {
+ print_hex(stderr, req->dest_buf, mb_pos);
+ }
+ return MODBUS_BAD_CRC;
+ }
+ } else {
+ fprintf(stderr, "timeout timings:");
+ fprintf(stderr, " write: %.2f ms", ts_diff(&write_begin, &wait_begin));
+ fprintf(stderr, " wait: %.2f ms", ts_diff(&wait_begin, &wait_end));
+ fprintf(stderr, " wait: %d iters", waitloops);
+ fprintf(stderr, " read: %.2f ms\n", ts_diff(&wait_end, &read_end));
+ dbg("No response :(\n");
+ if(!req->scan) {
+ timeout++;
+ }
+ return MODBUS_RESPONSE_TIMEOUT;
+ }
+
+cleanup:
+ if(error != 0) {
+ error = -1;
+ fprintf(stderr, "%s\n", strerror(errno));
+ } else {
+ //fprintf(stderr, "success, timings:");
+ //fprintf(stderr, " write: %.2f ms", ts_diff(&write_begin, &wait_begin));
+ //fprintf(stderr, " wait: %.2f ms", ts_diff(&wait_begin, &wait_end));
+ //fprintf(stderr, " read: %.2f ms -- ", ts_diff(&wait_end, &read_end));
+ if(stat_wait == 0 && !req->scan) {
+ fprintf(stderr, "success: %.2f%% crcfail %.2f%%, timeout %.2f%%\n",
+ ((double) 100.0 * success / (success + crcfail + timeout)),
+ ((double) 100.0 * crcfail / (success + crcfail + timeout)),
+ ((double) 100.0 * timeout / (success + crcfail + timeout)));
+ stat_wait = 1000;
+ fprintf(stderr, "success timings:");
+ fprintf(stderr, " write: %.2f ms", ts_diff(&write_begin, &wait_begin));
+ fprintf(stderr, " wait: %.2f ms", ts_diff(&wait_begin, &wait_end));
+ fprintf(stderr, " wait: %d iters", waitloops);
+ fprintf(stderr, " read: %.2f ms\n", ts_diff(&wait_end, &read_end));
+ } else if (!req->scan) {
+ stat_wait--;
+ }
+ if(!req->scan) {
+ success++;
+ }
+ }
+ return 0;
+}
+
+const char* modbus_strerror(int mb_err) {
+ if (mb_err < 0) {
+ mb_err = -mb_err;
+ }
+ switch(mb_err) {
+ case 4:
+ return "timed out";
+ case 5:
+ return "crc check failed";
+ default:
+ return "unknown";
+ }
+}
diff --git a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/modbus.h b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/modbus.h
index 435d518..1354feb 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/modbus.h
+++ b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/modbus.h
@@ -26,12 +26,27 @@ uint16_t modbus_crc16(char* buffer, size_t length);
#define DEFAULT_TTY "/dev/ttyS3"
#define DEFAULT_GPIO 45
-#define CHECK(x) { if((x) < 0) { \
- error = x; \
+extern int verbose;
+#define dbg(...) if(verbose) { fprintf(stderr, __VA_ARGS__); }
+#define log(...) { fprintf(stderr, __VA_ARGS__); }
+
+#define CHECK(expr) { int _check = expr; if((_check) < 0) { \
+ error = _check; \
+ goto cleanup; \
+} }
+#define CHECKP(name, expr) { int _check = expr; if((_check) < 0) { \
+ error = _check; \
+ perror(#name); \
goto cleanup; \
} }
+#define BAIL(...) { \
+ fprintf(stderr, __VA_ARGS__); \
+ fflush(stderr); \
+ error = -1; \
+ goto cleanup; \
+}
-void waitfd(int fd);
+int waitfd(int fd);
void gpio_on(int fd);
void gpio_off(int fd);
void decode_hex_in_place(char* buf, size_t* len);
@@ -41,6 +56,30 @@ void print_hex(FILE* f, char* buf, size_t len);
// Read until maxlen bytes or no bytes in mdelay_us microseconds
size_t read_wait(int fd, char* dst, size_t maxlen, int mdelay_us);
-extern int verbose;
+
+typedef struct _modbus_req {
+ int tty_fd;
+ int gpio_fd;
+ const char *modbus_cmd;
+ size_t cmd_len;
+ int timeout;
+ size_t expected_len;
+ char *dest_buf;
+ size_t dest_limit;
+ size_t dest_len;
+ int scan;
+} modbus_req;
+
+int modbuscmd(modbus_req *req);
+// Modbus errors
+
+#define MODBUS_RESPONSE_TIMEOUT -4
+#define MODBUS_BAD_CRC -5
+
+const char* modbus_strerror(int mb_err);
+
+// Modbus constants
+#define MODBUS_READ_HOLDING_REGISTERS 3
+
#endif
diff --git a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/modbuscmd.c b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/modbuscmd.c
index 2d33039..78f62a1 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/modbuscmd.c
+++ b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/modbuscmd.c
@@ -16,51 +16,54 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <termios.h>
-#include <unistd.h>
+#include <errno.h>
#include <fcntl.h>
-#include <stdlib.h>
+#include <getopt.h>
+#include <sched.h>
#include <stdint.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
-#include <errno.h>
+#include <unistd.h>
#include <sys/ioctl.h>
-#include <getopt.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
#include "modbus.h"
-
-int verbose;
+#include "rackmond.h"
void usage() {
fprintf(stderr,
- "modbuscmd [-v] [-t <tty>] [-g <gpio>] modbus_command\n"
- "\ttty defaults to %s\n"
- "\tgpio defaults to %d\n"
+ "modbuscmd [-v] [-t <timeout in ms>] [-x <expected response length>] modbus_command\n"
"\tmodbus command should be specified in hex\n"
- "\teg:\ta40300000008\n",
- DEFAULT_TTY, DEFAULT_GPIO);
+ "\teg:\ta40300000008\n"
+ "\tif an expected response length is provided, modbuscmd will stop receving and check crc immediately "
+ "after receiving that many bytes\n");
exit(1);
}
+
int main(int argc, char **argv) {
int error = 0;
- int fd;
- struct termios tio;
- char gpio_filename[255];
- int gpio_fd = 0;
- int gpio_n = DEFAULT_GPIO;
- char *tty = DEFAULT_TTY;
char *modbus_cmd = NULL;
size_t cmd_len = 0;
+ int expected = 0;
+ uint32_t timeout = 0;
verbose = 0;
+ rackmond_command *cmd = NULL;
+ char *response = NULL;
+ int clisock;
+ uint16_t response_len_actual;
+ struct sockaddr_un rackmond_addr;
int opt;
- while((opt = getopt(argc, argv, "t:g:v")) != -1) {
+ while((opt = getopt(argc, argv, "w:x:t:g:v")) != -1) {
switch (opt) {
- case 't':
- tty = optarg;
+ case 'x':
+ expected = atoi(optarg);
break;
- case 'g':
- gpio_n = atoi(optarg);
+ case 't':
+ timeout = atol(optarg);
break;
case 'v':
verbose = 1;
@@ -77,29 +80,6 @@ int main(int argc, char **argv) {
usage();
}
- if (verbose)
- fprintf(stderr, "[*] Opening TTY\n");
- fd = open(tty, O_RDWR | O_NOCTTY);
- CHECK(fd);
-
- if (verbose)
- fprintf(stderr, "[*] Opening GPIO %d\n", gpio_n);
- snprintf(gpio_filename, 255, "/sys/class/gpio/gpio%d/value", gpio_n);
- gpio_fd = open(gpio_filename, O_WRONLY | O_SYNC);
- CHECK(gpio_fd);
-
- if (verbose)
- fprintf(stderr, "[*] Setting TTY flags!\n");
- memset(&tio, 0, sizeof(tio));
- cfsetspeed(&tio,B19200);
- tio.c_cflag |= PARENB;
- tio.c_cflag |= CLOCAL;
- tio.c_cflag |= CS8;
- tio.c_iflag |= INPCK;
- tio.c_cc[VMIN] = 1;
- tio.c_cc[VTIME] = 0;
- CHECK(tcsetattr(fd,TCSANOW,&tio));
-
//convert hex to bytes
cmd_len = strlen(modbus_cmd);
if(cmd_len < 4) {
@@ -107,57 +87,45 @@ int main(int argc, char **argv) {
exit(1);
}
decode_hex_in_place(modbus_cmd, &cmd_len);
- append_modbus_crc16(modbus_cmd, &cmd_len);
- // print command as sent
- if (verbose) {
- fprintf(stderr, "Will send: ");
- print_hex(stderr, modbus_cmd, cmd_len);
- fprintf(stderr, "\n");
- }
-
- if (verbose)
- fprintf(stderr, "[*] Writing!\n");
-
- // gpio on, write, wait, gpio off
- gpio_on(gpio_fd);
- write(fd, modbus_cmd, cmd_len);
- waitfd(fd);
- gpio_off(gpio_fd);
+ cmd = malloc(sizeof(rackmond_command) + cmd_len);
+ cmd->type = COMMAND_TYPE_RAW_MODBUS;
+ cmd->raw_modbus.length = cmd_len;
+ cmd->raw_modbus.custom_timeout = timeout;
+ memcpy(cmd->raw_modbus.data, modbus_cmd, cmd_len);
+ cmd->raw_modbus.expected_response_length = expected;
+ response = malloc(expected ? expected : 1024);
+ uint16_t wire_cmd_len = sizeof(rackmond_command) + cmd_len;
- // Enable UART read
- tio.c_cflag |= CREAD;
- CHECK(tcsetattr(fd,TCSANOW,&tio));
-
- if(verbose)
- fprintf(stderr, "[*] reading any response...\n");
- // Read back response
- char modbus_buf[255];
- size_t mb_pos = 0;
- memset(modbus_buf, 0, sizeof(modbus_buf));
- mb_pos = read_wait(fd, modbus_buf, sizeof(modbus_buf), 90000);
- if(mb_pos >= 4) {
- uint16_t crc = modbus_crc16(modbus_buf, mb_pos - 2);
- if(verbose)
- fprintf(stderr, "Modbus response CRC: %04X\n ", crc);
- if((modbus_buf[mb_pos - 2] == (crc >> 8)) &&
- (modbus_buf[mb_pos - 1] == (crc & 0x00FF))) {
- if(verbose)
- fprintf(stderr, "CRC OK!\n");
- print_hex(stdout, modbus_buf, mb_pos);
- printf("\n");
- } else {
- fprintf(stderr, "BAD CRC :(\n");
- return 5;
- }
- } else {
- fprintf(stderr, "No response :(\n");
- return 4;
+ clisock = socket(AF_UNIX, SOCK_STREAM, 0);
+ CHECKP(socket, clisock);
+ rackmond_addr.sun_family = AF_UNIX;
+ strcpy(rackmond_addr.sun_path, "/var/run/rackmond.sock");
+ int addr_len = strlen(rackmond_addr.sun_path) + sizeof(rackmond_addr.sun_family);
+ CHECKP(connect, connect(clisock, (struct sockaddr*) &rackmond_addr, addr_len));
+ CHECKP(send, send(clisock, &wire_cmd_len, sizeof(wire_cmd_len), 0));
+ CHECKP(send, send(clisock, cmd, wire_cmd_len, 0));
+ CHECKP(recv, recv(clisock, &response_len_actual, sizeof(response_len_actual), 0));
+ if(response_len_actual == 0) {
+ uint16_t errcode = 0;
+ CHECKP(recv, recv(clisock, &errcode, sizeof(errcode), 0));
+ fprintf(stderr, "modbus error: %d (%s)\n", errcode, modbus_strerror(errcode));
+ error = 1;
+ goto cleanup;
+ }
+ CHECKP(recv, recv(clisock, response, response_len_actual, 0));
+ if(error == 0) {
+ printf("Response: ");
+ print_hex(stdout, response, response_len_actual);
+ printf("\n");
}
-
cleanup:
+ free(cmd);
+ free(response);
if(error != 0) {
+ if(errno != 0) {
+ fprintf(stderr, "errno err: %s\n", strerror(errno));
+ }
error = 1;
- fprintf(stderr, "%s\n", strerror(errno));
}
return error;
}
diff --git a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/modbussim.c b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/modbussim.c
index bf8c6c8..e276501 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/modbussim.c
+++ b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/modbussim.c
@@ -28,8 +28,6 @@
#include <getopt.h>
#include "modbus.h"
-int verbose = 0;
-
void usage() {
fprintf(stderr,
"modbussim [-v] [-t <tty>] [-g <gpio>] modbus_request modbus_reply\n"
diff --git a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/psu-update-delta.py b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/psu-update-delta.py
new file mode 100755
index 0000000..a92cf8e
--- /dev/null
+++ b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/psu-update-delta.py
@@ -0,0 +1,269 @@
+#!/usr/bin/env python
+from __future__ import print_function
+
+import os.path
+import socket
+import struct
+import sys
+import argparse
+import traceback
+
+import hexfile
+
+
+def auto_int(x):
+ return int(x, 0)
+
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--addr', type=auto_int, required=True,
+ help="PSU Modbus Address")
+parser.add_argument('file', help="firmware file")
+
+
+class ModbusTimeout(Exception):
+ pass
+
+
+class ModbusCRCFail(Exception):
+ pass
+
+
+class ModbusUnknownError(Exception):
+ pass
+
+
+class BadMEIResponse(Exception):
+ pass
+
+
+def rackmon_command(cmd):
+ srvpath = "/var/run/rackmond.sock"
+ replydata = []
+ if os.path.exists(srvpath):
+ client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ client.connect(srvpath)
+ cmdlen = struct.pack("@H", len(cmd))
+ client.send(cmdlen)
+ client.send(cmd)
+ while True:
+ data = client.recv(1024)
+ if not data:
+ break
+ replydata.append(data)
+ client.close()
+ return ''.join(replydata)
+
+
+def pause_monitoring():
+ COMMAND_TYPE_PAUSE_MONITORING = 0x04
+ command = struct.pack("@Hxx", COMMAND_TYPE_PAUSE_MONITORING)
+ result = rackmon_command(command)
+ (res_n, ) = struct.unpack("@B", result)
+ if res_n == 1:
+ print("Monitoring was already paused when tried to pause")
+ elif res_n == 0:
+ print("Monitoring paused")
+ else:
+ print("Unknown response pausing monitoring: %d" % res_n)
+
+
+def resume_monitoring():
+ COMMAND_TYPE_START_MONITORING = 0x05
+ command = struct.pack("@Hxx", COMMAND_TYPE_START_MONITORING)
+ result = rackmon_command(command)
+ (res_n, ) = struct.unpack("@B", result)
+ if res_n == 1:
+ print("Monitoring was already running when tried to resume")
+ elif res_n == 0:
+ print("Monitoring resumed")
+ else:
+ print("Unknown response resuming monitoring: %d" % res_n)
+
+
+def modbuscmd(raw_cmd, expected=0, timeout=0):
+ COMMAND_TYPE_RAW_MODBUS = 1
+ send_command = struct.pack("@HxxHHL",
+ COMMAND_TYPE_RAW_MODBUS,
+ len(raw_cmd),
+ expected,
+ timeout) + raw_cmd
+ result = rackmon_command(send_command)
+ if len(result) == 0:
+ raise ModbusUnknownError()
+ (resp_len,) = struct.unpack("@H", result[:2])
+ if resp_len == 0:
+ (error, ) = struct.unpack("@H", result[2:4])
+ if error == 4:
+ raise ModbusTimeout()
+ if error == 5:
+ raise ModbusCRCFail()
+ print("Unknown modbus error: " + str(error))
+ raise ModbusUnknownError()
+ return result[2:resp_len]
+
+
+def mei_command(addr, func_code, mei_type=0x64, data=None, timeout=0):
+ i_data = data
+ if i_data is None:
+ i_data = ("\xFF" * 7)
+ if len(i_data) < 7:
+ i_data = i_data + ("\xFF" * (7 - len(i_data)))
+ assert len(i_data) == 7
+ command = struct.pack("BBBB", addr, 0x2b, mei_type, func_code) + i_data
+ return modbuscmd(command, expected=13, timeout=timeout)
+
+
+def enter_bootloader(addr):
+ try:
+ print("Entering bootloader...")
+ mei_command(addr, 0xFB, timeout=4000)
+ except ModbusTimeout:
+ print("Enter bootloader timed out (expected.)")
+ pass
+
+
+def mei_expect(response, addr, data_pfx, error, success_mei_type=0x71):
+ expected = struct.pack("BBB", addr, 0x2B, success_mei_type) + \
+ data_pfx + ("\xFF" * (8 - len(data_pfx)))
+ if response != expected:
+ print(error + ", response: " + response.encode('hex'))
+ raise BadMEIResponse()
+
+
+def start_programming(addr):
+ print("Send start programming...")
+ response = mei_command(addr, 0x70, timeout=10000)
+ mei_expect(response, addr, "\xB0", "Start programming failed")
+ print("Start programming succeeded.")
+
+
+def get_challenge(addr):
+ print("Send get seed")
+ response = mei_command(addr, 0x27, timeout=3000)
+ expected = struct.pack("BBBB", addr, 0x2B, 0x71, 0x67)
+ if response[:len(expected)] != expected:
+ print("Bad response to get seed: " + response.encode('hex'))
+ raise BadMEIResponse()
+ challenge = response[len(expected):len(expected) + 4]
+ print("Got seed: " + challenge.encode('hex'))
+ return challenge
+
+
+def send_key(addr, key):
+ print("Send key")
+ response = mei_command(addr, 0x28, data=key, timeout=3000)
+ mei_expect(response, addr, "\x68", "Start programming failed")
+ print("Send key successful.")
+
+
+def delta_seccalckey(challenge):
+ (seed, ) = struct.unpack(">L", challenge)
+ for i in range(32):
+ if seed & 1 != 0:
+ seed = seed ^ 0xc758a5b6
+ seed = (seed >> 1) & 0x7fffffff
+ seed = seed ^ 0x06854137
+ return struct.pack(">L", seed)
+
+
+def verify_flash(addr):
+ print("Verifying program...")
+ response = mei_command(addr, 0x76, timeout=60000)
+ mei_expect(response, addr, "\xB6", "Program verification failed")
+
+
+def set_write_address(psu_addr, flash_addr):
+ # print("Set write address to " + hex(flash_addr))
+ data = struct.pack(">LB", flash_addr, 0xEA)
+ response = mei_command(psu_addr, 0x61, data=data, timeout=3000)
+ mei_expect(response, psu_addr, "\xA1\xEA", "Set address failed")
+
+
+def write_data(addr, data):
+ assert(len(data) == 8)
+ command = struct.pack(">BBB", addr, 0x2b, 0x65) + data
+ response = modbuscmd(command, expected=13, timeout=3000)
+ expected = struct.pack(">B", addr) +\
+ "\x2b\x73\xf0\xaa\xff\xff\xff\xff\xff\xff"
+ if response != expected:
+ print("Bad response to writing data: " +
+ response.encode('hex'))
+ raise BadMEIResponse()
+
+
+def send_image(addr, fwimg):
+ total_chunks = sum([len(s) for s in fwimg.segments]) / 8
+ sent_chunks = 0
+ for s in fwimg.segments:
+ if len(s) == 0:
+ continue
+ print("Sending " + str(s))
+ set_write_address(addr, s.start_address)
+ for i in xrange(0, len(s), 8):
+ chunk = s.data[i:i+8]
+ if len(chunk) < 8:
+ chunk = chunk + ("\xFF" * (8 - len(chunk)))
+ sent_chunks += 1
+ print("\r[%.2f%%] Sending chunk %d of %d..." %
+ (sent_chunks * 100.0 / total_chunks,
+ sent_chunks, total_chunks), end="")
+ sys.stdout.flush()
+ write_data(addr, str(bytearray(chunk)))
+ print("")
+
+
+def reset_psu(addr):
+ print("Resetting PSU...")
+ try:
+ response = mei_command(addr, 0x72, timeout=10000)
+ except ModbusTimeout:
+ print("No reply from PSU reset (expected.)")
+ return
+ expected = struct.pack(">BBBB", addr, 0x2b, 0x71, 0xb2) +\
+ ("\xFF" * 7)
+ if response != expected:
+ print("Bad response to unit reset request: " +
+ response.encode('hex'))
+ raise BadMEIResponse()
+
+
+def erase_flash(addr):
+ print("Erasing flash... ")
+ sys.stdout.flush()
+ response = mei_command(addr, 0x65, timeout=30000)
+ expected = struct.pack(">BBBB", addr, 0x2b, 0x71, 0xa5) +\
+ ("\xFF" * 7)
+ if response != expected:
+ print("Bad response to erasing flash: " +
+ response.encode('hex'))
+ raise BadMEIResponse()
+
+
+def update_psu(addr, filename):
+ pause_monitoring()
+ fwimg = hexfile.load(filename)
+ enter_bootloader(addr)
+ start_programming(addr)
+ challenge = get_challenge(addr)
+ send_key(addr, delta_seccalckey(challenge))
+ erase_flash(addr)
+ send_image(addr, fwimg)
+ verify_flash(addr)
+ reset_psu(addr)
+
+
+def main():
+ args = parser.parse_args()
+ try:
+ update_psu(args.addr, args.file)
+ except:
+ traceback.print_exc()
+ print("Firmware update failed")
+ resume_monitoring()
+ sys.exit(1)
+ resume_monitoring()
+ sys.exit(0)
+
+if __name__ == "__main__":
+ main()
diff --git a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/rackmon-config.py b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/rackmon-config.py
new file mode 100644
index 0000000..e93dfae
--- /dev/null
+++ b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/rackmon-config.py
@@ -0,0 +1,93 @@
+from __future__ import print_function
+import struct
+import socket
+import os, os.path
+
+reglist = [
+ {"begin": 0x0, #MFR_MODEL
+ "length": 8},
+ {"begin": 0x10, #MFR_DATE
+ "length": 8},
+ {"begin": 0x20, #FB Part #
+ "length": 8},
+ {"begin": 0x30, #HW Revision
+ "length": 4},
+ {"begin": 0x38, #FW Revision
+ "length": 4},
+ {"begin": 0x40, #MFR Serial #
+ "length": 16},
+ {"begin": 0x60, #Workorder #
+ "length": 4},
+ {"begin": 0x68, #PSU Status
+ "length": 1,
+ "keep": 10, # 10-sample ring buffer
+ "flags": 1},
+ {"begin": 0x69, #Battery Status
+ "length": 1,
+ "keep": 10, # 10-sample ring buffer
+ "flags": 1},
+ {"begin": 0x80, #Input VAC
+ "length": 1,
+ "keep": 10},
+ {"begin": 0x82, #Input Current AC
+ "length": 1,
+ "keep": 10},
+ {"begin": 0x84, #Battery Voltage
+ "length": 1,
+ "keep": 10},
+ {"begin": 0x86, #Battery Current Output
+ "length": 1},
+ {"begin": 0x88, #Battery Current Input
+ "length": 1},
+ {"begin": 0x8A, #Output Voltage (main converter)
+ "length": 1,
+ "keep": 10},
+ {"begin": 0x8C, #Output Current (main converter)
+ "length": 1,
+ "keep": 10},
+ {"begin": 0x8E, #IT Load Voltage Output
+ "length": 1},
+ {"begin": 0x90, #IT Load Current Output
+ "length": 1},
+ {"begin": 0x92, #Bulk Cap Voltage
+ "length": 1},
+ {"begin": 0x94, #Input Power
+ "length": 1,
+ "keep": 10},
+ {"begin": 0x96, #Output Power
+ "length": 1,
+ "keep": 10},
+ {"begin": 0x98, #RPM Fan 0
+ "length": 1},
+ {"begin": 0x9A, #RPM Fan 1
+ "length": 1},
+ {"begin": 0x9E, #Temp 0
+ "length": 1},
+ {"begin": 0xA0, #Temp 1
+ "length": 1},
+]
+
+def main():
+ COMMAND_TYPE_SET_CONFIG = 2
+ config_command = struct.pack("@HxxH",
+ COMMAND_TYPE_SET_CONFIG,
+ len(reglist))
+ for r in reglist:
+ keep = 1
+ if "keep" in r:
+ keep = r["keep"]
+ flags = 0
+ if "flags" in r:
+ flags = r["flags"]
+ monitor_interval = struct.pack("@HHHH", r["begin"], r["length"], keep, flags)
+ config_command += monitor_interval
+
+ config_packet = struct.pack("H", len(config_command)) + config_command
+ srvpath = "/var/run/rackmond.sock"
+ if os.path.exists(srvpath):
+ client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ client.connect(srvpath)
+ client.send(config_packet)
+
+if __name__ == "__main__":
+ main()
diff --git a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/rackmond.c b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/rackmond.c
new file mode 100644
index 0000000..cce3ba4
--- /dev/null
+++ b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/rackmond.c
@@ -0,0 +1,637 @@
+#include "modbus.h"
+#include "rackmond.h"
+#include <string.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <poll.h>
+#include <time.h>
+#include <stdarg.h>
+#include <syslog.h>
+#include <signal.h>
+
+#define MAX_ACTIVE_ADDRS 12
+#define REGISTER_PSU_STATUS 0x68
+
+struct _lock_holder {
+ pthread_mutex_t *lock;
+ int held;
+};
+
+#define lock_holder(holder_name, lock_expr) \
+ struct _lock_holder holder_name; \
+ holder_name.lock = lock_expr; \
+ holder_name.held = 0;
+
+#define lock_take(holder_name) { \
+ pthread_mutex_lock(holder_name.lock); \
+ holder_name.held = 1; \
+}
+
+#define lock_release(holder_name) { \
+ if(holder_name.held) { \
+ pthread_mutex_unlock(holder_name.lock); \
+ holder_name.held = 0; \
+ } \
+}
+
+int scanning = 0;
+
+typedef struct _rs485_dev {
+ // hold this for the duration of a command
+ pthread_mutex_t lock;
+ int tty_fd;
+ int gpio_fd;
+} rs485_dev;
+
+typedef struct _register_req {
+ uint16_t begin;
+ int num;
+} register_req;
+
+typedef struct register_range_data {
+ monitor_interval* i;
+ void* mem_begin;
+ size_t mem_pos;
+} register_range_data;
+
+typedef struct monitoring_data {
+ uint8_t addr;
+ register_range_data range_data[1];
+} monitoring_data;
+
+typedef struct _rackmond_data {
+ // global rackmond lock
+ pthread_mutex_t lock;
+ // number of register read commands to send to each PSU
+ int num_reqs;
+ // register read commands (begin+length)
+ register_req *reqs;
+ monitoring_config *config;
+
+ uint8_t num_active_addrs;
+ uint8_t active_addrs[MAX_ACTIVE_ADDRS];
+ monitoring_data* stored_data[MAX_ACTIVE_ADDRS];
+ FILE *status_log;
+
+ // timeout in nanosecs
+ int modbus_timeout;
+
+ int paused;
+
+ rs485_dev rs485;
+} rackmond_data;
+
+rackmond_data world;
+
+char psu_address(int rack, int shelf, int psu) {
+ int rack_a = ((rack & 3) << 3);
+ int shelf_a = ((shelf & 1) << 2);
+ int psu_a = (psu & 3);
+ return 0xA0 | rack_a | shelf_a | psu_a;
+}
+
+int modbus_command(rs485_dev* dev, int timeout, char* command, size_t len, char* destbuf, size_t dest_limit, size_t expect) {
+ int error = 0;
+ lock_holder(devlock, &dev->lock);
+ modbus_req req;
+ req.tty_fd = dev->tty_fd;
+ req.gpio_fd = dev->gpio_fd;
+ req.modbus_cmd = command;
+ req.cmd_len = len;
+ req.dest_buf = destbuf;
+ req.dest_limit = dest_limit;
+ req.timeout = timeout;
+ req.expected_len = expect != 0 ? expect : dest_limit;
+ req.scan = scanning;
+ lock_take(devlock);
+ int cmd_error = modbuscmd(&req);
+ CHECK(cmd_error);
+cleanup:
+ lock_release(devlock);
+ if (error >= 0) {
+ return req.dest_len;
+ }
+
+ return error;
+}
+
+int read_registers(rs485_dev *dev, int timeout, uint8_t addr, uint16_t begin, uint16_t num, uint16_t* out) {
+ int error = 0;
+ // address, function, begin, length in # of regs
+ char command[sizeof(addr) + 1 + sizeof(begin) + sizeof(num)];
+ // address, function, length (1 byte), data (2 bytes per register), crc
+ // (VLA)
+ char response[sizeof(addr) + 1 + 1 + (2 * num) + 2];
+ command[0] = addr;
+ command[1] = MODBUS_READ_HOLDING_REGISTERS;
+ command[2] = begin << 8;
+ command[3] = begin & 0xFF;
+ command[4] = num << 8;
+ command[5] = num & 0xFF;
+
+ int dest_len =
+ modbus_command(
+ dev, timeout,
+ command, sizeof(addr) + 1 + sizeof(begin) + sizeof(num),
+ response, sizeof(addr) + 1 + 1 + (2 * num) + 2, 0);
+ CHECK(dest_len);
+
+ if (dest_len >= 5) {
+ memcpy(out, response + 3, num * 2);
+ } else {
+ log("Unexpected short but CRC correct response!\n");
+ error = -1;
+ goto cleanup;
+ }
+ if (response[0] != addr) {
+ log("Got response for addr %02x when expected %02x\n", response[0], addr);
+ error = -1;
+ goto cleanup;
+ }
+ if (response[2] != (num * 2)) {
+ log("Got %d register data bytes when expecting %d\n", response[2], (num * 2));
+ error = -1;
+ goto cleanup;
+ }
+cleanup:
+ return error;
+}
+
+int sub_uint8s(const void* a, const void* b) {
+ return (*(uint8_t*)a) - (*(uint8_t*)b);
+}
+
+int check_active_psus() {
+ int error = 0;
+ lock_holder(worldlock, &world.lock);
+ lock_take(worldlock);
+ if (world.paused == 1) {
+ usleep(1000);
+ goto cleanup;
+ }
+ if (world.config == NULL) {
+ lock_release(worldlock);
+ usleep(5000);
+ goto cleanup;
+ }
+ world.num_active_addrs = 0;
+
+ scanning = 1;
+ //fprintf(stderr, "Begin presence check: ");
+ for(int rack = 0; rack < 3; rack++) {
+ for(int shelf = 0; shelf < 2; shelf++) {
+ for(int psu = 0; psu < 3; psu++) {
+ char addr = psu_address(rack, shelf, psu);
+ uint16_t status = 0;
+ int err = read_registers(&world.rs485, world.modbus_timeout, addr, REGISTER_PSU_STATUS, 1, &status);
+ if (err == 0) {
+ world.active_addrs[world.num_active_addrs] = addr;
+ world.num_active_addrs++;
+ //fprintf(stderr, "%02x - active (%04x) ", addr, status);
+ } else {
+ dbg("%02x - %d; ", addr, err);
+ }
+ }
+ }
+ }
+ //its the only stdlib sort
+ qsort(world.active_addrs, world.num_active_addrs,
+ sizeof(uint8_t), sub_uint8s);
+cleanup:
+ scanning = 0;
+ lock_release(worldlock);
+ return error;
+}
+
+monitoring_data* alloc_monitoring_data(uint8_t addr) {
+ size_t size = sizeof(monitoring_data) +
+ sizeof(register_range_data) * world.config->num_intervals;
+ for(int i = 0; i < world.config->num_intervals; i++) {
+ monitor_interval *iv = &world.config->intervals[i];
+ int pitch = sizeof(uint32_t) + (sizeof(uint16_t) * iv->len);
+ int data_size = pitch * iv->keep;
+ size += data_size;
+ }
+ monitoring_data* d = calloc(1, size);
+ if (d == NULL) {
+ log("Failed to allocate memory for sensor data.\n");
+ return NULL;
+ }
+ d->addr = addr;
+ void* mem = d;
+ mem = mem + (sizeof(monitoring_data) +
+ sizeof(register_range_data) * world.config->num_intervals);
+ for(int i = 0; i < world.config->num_intervals; i++) {
+ monitor_interval *iv = &world.config->intervals[i];
+ int pitch = sizeof(uint32_t) + (sizeof(uint16_t) * iv->len);
+ int data_size = pitch * iv->keep;
+ d->range_data[i].i = iv;
+ d->range_data[i].mem_begin = mem;
+ d->range_data[i].mem_pos = 0;
+ mem = mem + data_size;
+ }
+ return d;
+}
+
+int sub_storeptrs(const void* va, const void *vb) {
+ //more *s than i like :/
+ monitoring_data* a = *(monitoring_data**)va;
+ monitoring_data* b = *(monitoring_data**)vb;
+ //nulls to the end
+ if (b == NULL && a == NULL) {
+ return 0;
+ }
+ if (b == NULL) {
+ return -1;
+ }
+ if (a == NULL) {
+ return 1;
+ }
+ return a->addr - b->addr;
+}
+
+int alloc_monitoring_datas() {
+ int error = 0;
+ if (world.config == NULL) {
+ goto cleanup;
+ }
+ qsort(world.stored_data, MAX_ACTIVE_ADDRS,
+ sizeof(monitoring_data*), sub_storeptrs);
+ int data_pos = 0;
+ for(int i = 0; i < world.num_active_addrs; i++) {
+ uint8_t addr = world.active_addrs[i];
+ while(world.stored_data[data_pos] != NULL &&
+ world.stored_data[data_pos]->addr != addr) {
+ data_pos++;
+ }
+ if (world.stored_data[data_pos] == NULL) {
+ log("Detected PSU at address 0x%02x\n", addr);
+ //syslog(LOG_INFO, "Detected PSU at address 0x%02x", addr);
+ world.stored_data[data_pos] = alloc_monitoring_data(addr);
+ if (world.stored_data[data_pos] == NULL) {
+ BAIL("allocation failed\n");
+ }
+ //reset search pos after alloc (post-sorted addrs may already be alloc'd, need to check again)
+ data_pos = 0;
+ continue;
+ }
+ if (world.stored_data[data_pos]->addr == addr) {
+ continue;
+ }
+ BAIL("shouldn't get here!\n");
+ }
+cleanup:
+ return error;
+}
+
+void record_data(register_range_data* rd, uint32_t time, uint16_t* regs) {
+ int n_regs = (rd->i->len);
+ int pitch = sizeof(time) + (sizeof(uint16_t) * n_regs);
+ int mem_size = pitch * rd->i->keep;
+
+ memcpy(rd->mem_begin + rd->mem_pos, &time, sizeof(time));
+ rd->mem_pos += sizeof(time);
+ memcpy(rd->mem_begin + rd->mem_pos, regs, n_regs * sizeof(uint16_t));
+ rd->mem_pos += n_regs * sizeof(uint16_t);
+ rd->mem_pos = rd->mem_pos % mem_size;
+}
+
+int fetch_monitored_data() {
+ int error = 0;
+ int data_pos = 0;
+ lock_holder(worldlock, &world.lock);
+ lock_take(worldlock);
+ if (world.paused == 1) {
+ usleep(1000);
+ goto cleanup;
+ }
+ if (world.config == NULL) {
+ goto cleanup;
+ }
+ lock_release(worldlock);
+
+ usleep(1000); // wait a sec btween PSUs to not overload RT scheduling
+ // threshold
+ while(world.stored_data[data_pos] != NULL && data_pos < MAX_ACTIVE_ADDRS) {
+ uint8_t addr = world.stored_data[data_pos]->addr;
+ //log("readpsu %02x\n", addr);
+ for(int r = 0; r < world.config->num_intervals; r++) {
+ register_range_data* rd = &world.stored_data[data_pos]->range_data[r];
+ monitor_interval* i = rd->i;
+ uint16_t regs[i->len];
+ int err = read_registers(&world.rs485,
+ world.modbus_timeout, addr, i->begin, i->len, regs);
+ if (err) {
+ log("Error %d reading %02x registers at %02x from %02x\n",
+ err, i->len, i->begin, addr);
+ continue;
+ }
+ struct timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ uint32_t timestamp = ts.tv_sec;
+ if (rd->i->flags & MONITOR_FLAG_ONLY_CHANGES) {
+ int pitch = sizeof(timestamp) + (sizeof(uint16_t) * i->len);
+ int lastpos = rd->mem_pos - pitch;
+ if (lastpos < 0) {
+ lastpos = (pitch * rd->i->keep) - pitch;
+ }
+ if (!memcmp(rd->mem_begin + lastpos + sizeof(timestamp),
+ regs, sizeof(uint16_t) * i->len) &&
+ memcmp(rd->mem_begin, "\x00\x00\x00\x00", 4)) {
+ continue;
+ }
+
+ if (world.status_log) {
+ time_t rawt;
+ struct tm* ti;
+ time(&rawt);
+ ti = localtime(&rawt);
+ char timestr[80];
+ strftime(timestr, sizeof(timestr), "%b %e %T", ti);
+ fprintf(world.status_log,
+ "%s: Change to status register %02x on address %02x. New value: %02x\n",
+ timestr, i->begin, addr, regs[0]);
+ fflush(world.status_log);
+ }
+
+ }
+ lock_take(worldlock);
+ record_data(rd, timestamp, regs);
+ lock_release(worldlock);
+ }
+ data_pos++;
+ }
+cleanup:
+ lock_release(worldlock);
+ return error;
+}
+
+// check for new psus every N rounds of sensor reads
+#define SEARCH_PSUS_EVERY 200
+void* monitoring_loop(void* arg) {
+ (void) arg;
+ int until_search = 0;
+ world.status_log = fopen("/var/log/psu-status.log", "a+");
+ while(1) {
+ if (until_search == 0) {
+ check_active_psus();
+ alloc_monitoring_datas();
+ until_search = SEARCH_PSUS_EVERY;
+ } else {
+ until_search--;
+ }
+ fetch_monitored_data();
+ }
+ return NULL;
+}
+
+int open_rs485_dev(const char* tty_filename, int gpio_num, rs485_dev *dev) {
+ int error = 0;
+ int tty_fd, gpio_fd;
+ char gpio_filename[128];
+ dbg("[*] Opening TTY\n");
+ tty_fd = open(tty_filename, O_RDWR | O_NOCTTY);
+ CHECK(tty_fd);
+
+ dbg("[*] Opening GPIO %d\n", gpio_num);
+ snprintf(gpio_filename, sizeof(gpio_filename), "/sys/class/gpio/gpio%d/value", gpio_num);
+ gpio_fd = open(gpio_filename, O_WRONLY | O_SYNC);
+ CHECK(gpio_fd);
+
+ dev->tty_fd = tty_fd;
+ dev->gpio_fd = gpio_fd;
+ pthread_mutex_init(&dev->lock, NULL);
+cleanup:
+ return error;
+}
+
+int do_command(int sock, rackmond_command* cmd) {
+ int error = 0;
+ lock_holder(worldlock, &world.lock);
+ switch(cmd->type) {
+ case COMMAND_TYPE_RAW_MODBUS:
+ {
+ uint16_t expected = cmd->raw_modbus.expected_response_length;
+ int timeout = world.modbus_timeout;
+ if (cmd->raw_modbus.custom_timeout) {
+ //ms to us
+ timeout = cmd->raw_modbus.custom_timeout * 1000;
+ }
+ if (expected == 0) {
+ expected = 1024;
+ }
+ char response[expected];
+ int response_len = modbus_command(
+ &world.rs485, timeout,
+ cmd->raw_modbus.data, cmd->raw_modbus.length,
+ response, expected, expected);
+ uint16_t response_len_wire = response_len;
+ if(response_len < 0) {
+ uint16_t error = -response_len;
+ response_len_wire = 0;
+ send(sock, &response_len_wire, sizeof(uint16_t), 0);
+ send(sock, &error, sizeof(uint16_t), 0);
+ break;
+ }
+ send(sock, &response_len_wire, sizeof(uint16_t), 0);
+ send(sock, response, response_len, 0);
+ break;
+ }
+ case COMMAND_TYPE_SET_CONFIG:
+ {
+ lock_take(worldlock);
+ if (world.config != NULL) {
+ BAIL("rackmond already configured\n");
+ }
+ size_t config_size = sizeof(monitoring_config) +
+ (sizeof(monitor_interval) * cmd->set_config.config.num_intervals);
+ world.config = calloc(1, config_size);
+ memcpy(world.config, &cmd->set_config.config, config_size);
+ syslog(LOG_INFO, "got configuration");
+ lock_release(worldlock);
+ break;
+ }
+ case COMMAND_TYPE_DUMP_DATA_JSON:
+ {
+ lock_take(worldlock);
+ if (world.config == NULL) {
+ send(sock, "[]", 2, 0);
+ } else {
+ struct timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ uint32_t now = ts.tv_sec;
+ send(sock, "[", 1, 0);
+ int data_pos = 0;
+ while(world.stored_data[data_pos] != NULL && data_pos < MAX_ACTIVE_ADDRS) {
+ dprintf(sock, "{\"addr\":%d,\"now\":%d,\"ranges\":[",
+ world.stored_data[data_pos]->addr, now);
+ for(int i = 0; i < world.config->num_intervals; i++) {
+ uint32_t time;
+ register_range_data *rd = &world.stored_data[data_pos]->range_data[i];
+ char* mem_pos = rd->mem_begin;
+ dprintf(sock,"{\"begin\":%d,\"readings\":[", rd->i->begin);
+ // want to cut the list off early just before
+ // the first entry with time == 0
+ memcpy(&time, mem_pos, sizeof(time));
+ for(int j = 0; j < rd->i->keep && time != 0; j++) {
+ mem_pos += sizeof(time);
+ dprintf(sock, "{\"time\":%d,\"data\":\"", time);
+ for(int c = 0; c < rd->i->len * 2; c++) {
+ dprintf(sock, "%02x", *mem_pos);
+ mem_pos++;
+ }
+ send(sock, "\"}", 2, 0);
+ memcpy(&time, mem_pos, sizeof(time));
+ if (time == 0) {
+ break;
+ }
+ if ((j+1) < rd->i->keep) {
+ send(sock, ",", 1, 0);
+ }
+ }
+ send(sock, "]}", 2, 0);
+ if ((i+1) < world.config->num_intervals) {
+ send(sock, ",", 1, 0);
+ }
+ }
+ data_pos++;
+ if (data_pos < MAX_ACTIVE_ADDRS && world.stored_data[data_pos] != NULL) {
+ send(sock, "]},", 3, 0);
+ } else {
+ send(sock, "]}", 2, 0);
+ }
+ }
+ send(sock, "]", 1, 0);
+ }
+ lock_release(worldlock);
+ break;
+ }
+ case COMMAND_TYPE_PAUSE_MONITORING:
+ {
+ lock_take(worldlock);
+ uint8_t was_paused = world.paused;
+ world.paused = 1;
+ send(sock, &was_paused, sizeof(was_paused), 0);
+ lock_release(worldlock);
+ break;
+ }
+ case COMMAND_TYPE_START_MONITORING:
+ {
+ lock_take(worldlock);
+ uint8_t was_started = !world.paused;
+ world.paused = 0;
+ send(sock, &was_started, sizeof(was_started), 0);
+ lock_release(worldlock);
+ break;
+ }
+ default:
+ CHECK(-1);
+ }
+cleanup:
+ lock_release(worldlock);
+ return error;
+}
+
+typedef enum {
+ CONN_WAITING_LENGTH,
+ CONN_WAITING_BODY
+} rackmond_connection_state;
+
+// receive the command as a length prefixed block
+// (uint16_t, followed by data)
+// this is all over a local socket, won't be doing
+// endian flipping, clients should only be local procs
+// compiled for the same arch
+int handle_connection(int sock) {
+ int error = 0;
+ rackmond_connection_state state = CONN_WAITING_LENGTH;
+ char bodybuf[1024];
+ uint16_t expected_len = 0;
+ struct pollfd pfd;
+ int recvret = 0;
+ pfd.fd = sock;
+ pfd.events = POLLIN | POLLERR | POLLHUP;
+ // if you don't do anything for a whole second we bail
+next:
+ CHECKP(poll, poll(&pfd, 1, 1000));
+ if (pfd.revents & (POLLERR | POLLHUP)) {
+ goto cleanup;
+ }
+ switch(state) {
+ case CONN_WAITING_LENGTH:
+ recvret = recv(sock, &expected_len, 2, MSG_DONTWAIT);
+ if (recvret == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
+ goto next;
+ }
+ if (expected_len == 0 || expected_len > sizeof(bodybuf)) {
+ // bad length; bail
+ goto cleanup;
+ }
+ state = CONN_WAITING_BODY;
+ goto next;
+ break;
+ case CONN_WAITING_BODY:
+ recvret = recv(sock, &bodybuf, expected_len, MSG_DONTWAIT);
+ if (recvret == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
+ goto next;
+ }
+ CHECK(do_command(sock, (rackmond_command*) bodybuf));
+ }
+cleanup:
+ close(sock);
+ if (error != 0) {
+ fprintf(stderr, "Warning: possible error handling user connection (%d)\n", error);
+ }
+ return 0;
+}
+
+int main(int argc, char** argv) {
+ if (getenv("RACKMOND_FOREGROUND") == NULL) {
+ daemon(0, 0);
+ }
+ signal(SIGPIPE, SIG_IGN);
+ int error = 0;
+ world.paused = 0;
+ world.modbus_timeout = 300000;
+ if (getenv("RACKMOND_TIMEOUT") != NULL) {
+ world.modbus_timeout = atoll(getenv("RACKMOND_TIMEOUT"));
+ fprintf(stderr, "Timeout from env: %dms\n",
+ (world.modbus_timeout / 1000));
+ }
+ world.config = NULL;
+ pthread_mutex_init(&world.lock, NULL);
+ verbose = getenv("RACKMOND_VERBOSE") != NULL ? 1 : 0;
+ openlog("rackmond", 0, LOG_USER);
+ syslog(LOG_INFO, "rackmon/modbus service starting");
+ CHECK(open_rs485_dev(DEFAULT_TTY, DEFAULT_GPIO, &world.rs485));
+ pthread_t monitoring_thread;
+ pthread_create(&monitoring_thread, NULL, monitoring_loop, NULL);
+ struct sockaddr_un local, client;
+ int sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ strcpy(local.sun_path, "/var/run/rackmond.sock");
+ local.sun_family = AF_UNIX;
+ int socknamelen = sizeof(local.sun_family) + strlen(local.sun_path);
+ unlink(local.sun_path);
+ CHECKP(bind, bind(sock, (struct sockaddr *)&local, socknamelen));
+ CHECKP(listen, listen(sock, 5));
+ syslog(LOG_INFO, "rackmon/modbus service listening");
+ while(1) {
+ socklen_t clisocklen = sizeof(struct sockaddr_un);
+ int clisock = accept(sock, (struct sockaddr*) &client, &clisocklen);
+ CHECKP(accept, clisock);
+ CHECK(handle_connection(clisock));
+ }
+
+cleanup:
+ if (error != 0) {
+ error = 1;
+ }
+ return error;
+}
diff --git a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/rackmond.h b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/rackmond.h
new file mode 100644
index 0000000..2c0e8a0
--- /dev/null
+++ b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/rackmond.h
@@ -0,0 +1,46 @@
+#include <stdint.h>
+
+//would've been nice to have thrift
+
+// Raw modbus command
+// Response is just the raw response data
+typedef struct raw_modbus_command {
+ uint16_t length;
+ uint16_t expected_response_length;
+ uint32_t custom_timeout; // 0 for default
+ char data[1];
+} raw_modbus_command;
+
+// only store new value if different from most recent
+// (for watching changes to status flags registers)
+#define MONITOR_FLAG_ONLY_CHANGES 0x1
+
+typedef struct monitor_interval {
+ uint16_t begin;
+ uint16_t len;
+ uint16_t keep; // How long of a history to keep?
+ uint16_t flags;
+} monitor_interval;
+
+typedef struct monitoring_config {
+ uint16_t num_intervals;
+ monitor_interval intervals[1];
+} monitoring_config;
+
+typedef struct set_config_command {
+ monitoring_config config;
+} set_config_command;
+
+#define COMMAND_TYPE_RAW_MODBUS 0x01
+#define COMMAND_TYPE_SET_CONFIG 0x02
+#define COMMAND_TYPE_DUMP_DATA_JSON 0x03
+#define COMMAND_TYPE_PAUSE_MONITORING 0x04
+#define COMMAND_TYPE_START_MONITORING 0x05
+
+typedef struct rackmond_command {
+ uint16_t type;
+ union {
+ raw_modbus_command raw_modbus;
+ set_config_command set_config;
+ };
+} rackmond_command;
diff --git a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/rackmondata.c b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/rackmondata.c
new file mode 100644
index 0000000..391b5be
--- /dev/null
+++ b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/rackmondata.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include "modbus.h"
+#include "rackmond.h"
+
+int main(int argc, char **argv) {
+ int error = 0;
+ rackmond_command cmd;
+ int clisock;
+ uint16_t wire_cmd_len = sizeof(cmd);
+ struct sockaddr_un rackmond_addr;
+ cmd.type = COMMAND_TYPE_DUMP_DATA_JSON;
+ clisock = socket(AF_UNIX, SOCK_STREAM, 0);
+ CHECKP(socket, clisock);
+ rackmond_addr.sun_family = AF_UNIX;
+ strcpy(rackmond_addr.sun_path, "/var/run/rackmond.sock");
+ int addr_len = strlen(rackmond_addr.sun_path) + sizeof(rackmond_addr.sun_family);
+ CHECKP(connect, connect(clisock, (struct sockaddr*) &rackmond_addr, addr_len));
+ CHECKP(send, send(clisock, &wire_cmd_len, sizeof(wire_cmd_len), 0));
+ CHECKP(send, send(clisock, &cmd, wire_cmd_len, 0));
+ char readbuf[256];
+ ssize_t n_read;
+ while((n_read = read(clisock, readbuf, sizeof(readbuf))) > 0) {
+ write(1, readbuf, n_read);
+ }
+cleanup:
+ if(error != 0) {
+ if(errno != 0) {
+ fprintf(stderr, "%s\n", strerror(errno));
+ }
+ error = 1;
+ }
+ return error;
+}
diff --git a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/setup-rackmond.sh b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/setup-rackmond.sh
new file mode 100644
index 0000000..85a1e22
--- /dev/null
+++ b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon/setup-rackmond.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+#
+# Copyright 2014-present Facebook. All Rights Reserved.
+#
+### BEGIN INIT INFO
+# Provides: setup-rackmond
+# Required-Start:
+# Required-Stop:
+# Default-Start: S
+# Default-Stop:
+# Short-Description: Start Rackmon service
+### END INIT INFO
+
+echo -n "Starting rackmon background service..."
+/usr/local/bin/rackmond
+echo "done."
+
+echo -n "Configuring rackmon service..."
+python /etc/rackmon-config.py
+echo "done."
diff --git a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon_0.1.bb b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon_0.1.bb
index d3e79e4..399f7c0 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon_0.1.bb
+++ b/meta-facebook/meta-wedge/recipes-wedge/rackmon/rackmon_0.1.bb
@@ -1,4 +1,19 @@
# 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
SUMMARY = "Rackmon Functionality"
DESCRIPTION = "Rackmon Functionality"
SECTION = "base"
@@ -6,7 +21,7 @@ PR = "r1"
LICENSE = "GPLv2"
LIC_FILES_CHKSUM = "file://modbus.c;beginline=4;endline=16;md5=da35978751a9d71b73679307c4d296ec"
-#DEPENDS_append = " update-rc.d-native"
+DEPENDS_append = " update-rc.d-native"
SRC_URI = "file://Makefile \
file://modbuscmd.c \
@@ -14,6 +29,13 @@ SRC_URI = "file://Makefile \
file://modbus.c \
file://modbus.h \
file://gpiowatch.c \
+ file://rackmond.c \
+ file://rackmond.h \
+ file://rackmondata.c \
+ file://setup-rackmond.sh \
+ file://rackmon-config.py \
+ file://psu-update-delta.py \
+ file://hexfile.py \
"
S = "${WORKDIR}"
@@ -21,6 +43,10 @@ S = "${WORKDIR}"
binfiles = "modbuscmd \
modbussim \
gpiowatch \
+ rackmond \
+ rackmondata \
+ psu-update-delta.py \
+ hexfile.py \
"
#otherfiles = "README"
@@ -36,6 +62,11 @@ do_install() {
install -m 755 $f ${dst}/$f
ln -snf ../fbpackages/${pkgdir}/$f ${bin}/$f
done
+ install -d ${D}${sysconfdir}/init.d
+ install -d ${D}${sysconfdir}/rcS.d
+ install -m 755 setup-rackmond.sh ${D}${sysconfdir}/init.d/setup-rackmond.sh
+ install -m 755 rackmon-config.py ${D}${sysconfdir}/rackmon-config.py
+ update-rc.d -r ${D} setup-rackmond.sh start 95 2 3 4 5 .
}
FBPACKAGEDIR = "${prefix}/local/fbpackages"
diff --git a/meta-facebook/meta-wedge/recipes-wedge/rest-api/files/rest.py b/meta-facebook/meta-wedge/recipes-wedge/rest-api/files/rest.py
index 6d59fd6..52c98d9 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/rest-api/files/rest.py
+++ b/meta-facebook/meta-wedge/recipes-wedge/rest-api/files/rest.py
@@ -20,14 +20,24 @@
from ctypes import *
-from bottle import route, run, template, request, response
+from bottle import route, run, template, request, response, ServerAdapter
from bottle import abort
+from wsgiref.simple_server import make_server, WSGIRequestHandler, WSGIServer
import json
-from rest_fruid import *
-from rest_server import *
-from rest_sensors import *
-from rest_bmc import *
-from rest_gpios import *
+import ssl
+import socket
+import os
+import rest_fruid
+import rest_server
+import rest_sensors
+import rest_bmc
+import rest_gpios
+import rest_modbus
+import rest_slotid
+
+CONSTANTS = {
+ 'certificate': '/usr/lib/ssl/certs/rest_server.pem',
+}
# Handler for root resource endpoint
@route('/api')
@@ -50,7 +60,8 @@ def rest_sys():
"Description": "Wedge System",
},
"Actions": [],
- "Resources": [ "mb", "bmc", "server", "sensors", "gpios"],
+ "Resources": [ "mb", "bmc", "server", "sensors", "gpios",
+ "modbus_registers", "slotid"],
}
return result
@@ -70,33 +81,72 @@ def rest_sys():
# Handler for sys/mb/fruid resource endpoint
@route('/api/sys/mb/fruid')
-def rest_fruid():
- return get_fruid()
+def rest_fruid_hdl():
+ return rest_fruid.get_fruid()
# Handler for sys/bmc resource endpoint
@route('/api/sys/bmc')
-def rest_bmc():
- return get_bmc()
+def rest_bmc_hdl():
+ return rest_bmc.get_bmc()
# Handler for sys/server resource endpoint
@route('/api/sys/server')
-def rest_bmc():
- return get_server()
+def rest_server_hdl():
+ return rest_server.get_server()
# Handler for uServer resource endpoint
@route('/api/sys/server', method='POST')
-def rest_server():
+def rest_server_act_hdl():
data = json.load(request.body)
- return server_action(data)
+ return rest_server.server_action(data)
# Handler for sensors resource endpoint
@route('/api/sys/sensors')
-def rest_sensors():
- return get_sensors()
+def rest_sensors_hdl():
+ return rest_sensors.get_sensors()
# Handler for sensors resource endpoint
@route('/api/sys/gpios')
-def rest_gpios():
- return get_gpios()
+def rest_gpios_hdl():
+ return rest_gpios.get_gpios()
+
+@route('/api/sys/modbus_registers')
+def modbus_registers_hdl():
+ return rest_modbus.get_modbus_registers()
+
+# Handler for sensors resource endpoint
+@route('/api/sys/slotid')
+def rest_slotid_hdl():
+ return rest_slotid.get_slotid()
run(host = "::", port = 8080)
+
+# SSL Wrapper for Rest API
+class SSLWSGIRefServer(ServerAdapter):
+ def run(self, handler):
+ if self.quiet:
+ class QuietHandler(WSGIRequestHandler):
+ def log_request(*args, **kw): pass
+ self.options['handler_class'] = QuietHandler
+
+ # IPv6 Support
+ server_cls = self.options.get('server_class', WSGIServer)
+
+ if ':' in self.host:
+ if getattr(server_cls, 'address_family') == socket.AF_INET:
+ class server_cls(server_cls):
+ address_family = socket.AF_INET6
+
+ srv = make_server(self.host, self.port, handler,
+ server_class=server_cls, **self.options)
+ srv.socket = ssl.wrap_socket (
+ srv.socket,
+ certfile=CONSTANTS['certificate'],
+ server_side=True)
+ srv.serve_forever()
+
+# Use SSL if the certificate exists. Otherwise, run without SSL.
+if os.access(CONSTANTS['certificate'], os.R_OK):
+ run(server=SSLWSGIRefServer(host="::", port=8443))
+else:
+ run(host = "::", port = 8080)
diff --git a/meta-facebook/meta-wedge/recipes-wedge/rest-api/files/rest_bmc.py b/meta-facebook/meta-wedge/recipes-wedge/rest-api/files/rest_bmc.py
index d9600ae..c4f661e 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/rest-api/files/rest_bmc.py
+++ b/meta-facebook/meta-wedge/recipes-wedge/rest-api/files/rest_bmc.py
@@ -20,6 +20,7 @@
from subprocess import *
+import re
# Handler for FRUID resource endpoint
def get_bmc():
@@ -51,6 +52,14 @@ def get_bmc():
mem_usage = adata[0]
cpu_usage = adata[1]
+ # Get OpenBMC version
+ version = ""
+ data = Popen('cat /etc/issue', \
+ shell=True, stdout=PIPE).stdout.read()
+ ver = re.search(r'v([\w\d._-]*)\s', data)
+ if ver:
+ version = ver.group(1)
+
result = {
"Information": {
"Description": "Wedge BMC",
@@ -58,6 +67,7 @@ def get_bmc():
"Uptime": uptime,
"Memory Usage": mem_usage,
"CPU Usage": cpu_usage,
+ "OpenBMC Version": version,
},
"Actions": [],
"Resources": [],
diff --git a/meta-facebook/meta-wedge/recipes-wedge/rest-api/files/rest_modbus.py b/meta-facebook/meta-wedge/recipes-wedge/rest-api/files/rest_modbus.py
new file mode 100644
index 0000000..9d213fc
--- /dev/null
+++ b/meta-facebook/meta-wedge/recipes-wedge/rest-api/files/rest_modbus.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+#
+# 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
+#
+
+import subprocess
+from subprocess import Popen
+
+# Handler for sensors resource endpoint
+def get_modbus_registers():
+ p = Popen('/usr/local/bin/rackmondata', stdout=subprocess.PIPE)
+ out, err = p.communicate()
+ return out
diff --git a/meta-facebook/meta-wedge/recipes-wedge/rest-api/files/rest_sensors.py b/meta-facebook/meta-wedge/recipes-wedge/rest-api/files/rest_sensors.py
index f4f83d3..fa65372 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/rest-api/files/rest_sensors.py
+++ b/meta-facebook/meta-wedge/recipes-wedge/rest-api/files/rest_sensors.py
@@ -39,12 +39,10 @@ def get_sensors():
if (len(tdata) < 2):
continue
sresult[tdata[0].strip()] = tdata[1].strip()
- result.append(sresult)
-
+ result.append(sresult)
fresult = {
"Information": result,
"Actions": [],
"Resources": [],
}
-
return fresult
diff --git a/meta-facebook/meta-wedge/recipes-wedge/rest-api/files/rest_slotid.py b/meta-facebook/meta-wedge/recipes-wedge/rest-api/files/rest_slotid.py
new file mode 100644
index 0000000..ee407ac
--- /dev/null
+++ b/meta-facebook/meta-wedge/recipes-wedge/rest-api/files/rest_slotid.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+#
+# 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
+#
+
+import subprocess
+
+# Handler for sensors resource endpoint
+def get_slotid():
+ p = subprocess.Popen('source /usr/local/bin/openbmc-utils.sh;'
+ 'wedge_slot_id $(wedge_board_type)',
+ shell=True, stdout=subprocess.PIPE)
+ out, err = p.communicate()
+ try:
+ slot = int(out.strip('\n'))
+ except:
+ slot = 0
+ return { 'slotid' : slot }
diff --git a/meta-facebook/meta-wedge/recipes-wedge/rest-api/files/setup-rest-api.sh b/meta-facebook/meta-wedge/recipes-wedge/rest-api/files/setup-rest-api.sh
index fe01c23..bdd79b6 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/rest-api/files/setup-rest-api.sh
+++ b/meta-facebook/meta-wedge/recipes-wedge/rest-api/files/setup-rest-api.sh
@@ -2,6 +2,22 @@
#
# 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: setup-rest-api
# Required-Start:
diff --git a/meta-facebook/meta-wedge/recipes-wedge/rest-api/rest-api_0.1.bb b/meta-facebook/meta-wedge/recipes-wedge/rest-api/rest-api_0.1.bb
index 2753f30..5dec4bf 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/rest-api/rest-api_0.1.bb
+++ b/meta-facebook/meta-wedge/recipes-wedge/rest-api/rest-api_0.1.bb
@@ -1,4 +1,19 @@
# 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
SUMMARY = "Rest API Daemon"
DESCRIPTION = "Daemon to handle RESTful interface."
SECTION = "base"
@@ -16,11 +31,13 @@ SRC_URI = "file://setup-rest-api.sh \
file://rest_gpios.py \
file://rest_server.py \
file://rest_sensors.py \
+ file://rest_modbus.py \
+ file://rest_slotid.py \
"
S = "${WORKDIR}"
-binfiles = "rest.py rest_bmc.py rest_fruid.py rest_gpios.py rest_server.py rest_sensors.py setup-rest-api.sh"
+binfiles = "rest.py rest_bmc.py rest_fruid.py rest_gpios.py rest_server.py rest_sensors.py rest_modbus.py rest_slotid.py setup-rest-api.sh"
pkgdir = "rest-api"
diff --git a/meta-facebook/meta-wedge/recipes-wedge/sensor-setup/sensor-setup_0.1.bb b/meta-facebook/meta-wedge/recipes-wedge/sensor-setup/sensor-setup_0.1.bb
index ad6bb0c..1b0f937 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/sensor-setup/sensor-setup_0.1.bb
+++ b/meta-facebook/meta-wedge/recipes-wedge/sensor-setup/sensor-setup_0.1.bb
@@ -1,4 +1,19 @@
# 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
SUMMARY = "Configure the sensors"
DESCRIPTION = "The script configure sensors"
SECTION = "base"
diff --git a/meta-facebook/meta-wedge/recipes-wedge/sms-kcsd/sms-kcsd/Makefile b/meta-facebook/meta-wedge/recipes-wedge/sms-kcsd/sms-kcsd/Makefile
index 6425261..dba9dbb 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/sms-kcsd/sms-kcsd/Makefile
+++ b/meta-facebook/meta-wedge/recipes-wedge/sms-kcsd/sms-kcsd/Makefile
@@ -1,4 +1,20 @@
# 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
+
all: sms-kcsd
sms-kcsd: sms-kcsd.c
diff --git a/meta-facebook/meta-wedge/recipes-wedge/sms-kcsd/sms-kcsd/setup-sms-kcs.sh b/meta-facebook/meta-wedge/recipes-wedge/sms-kcsd/sms-kcsd/setup-sms-kcs.sh
index d369f5c..b4234a4 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/sms-kcsd/sms-kcsd/setup-sms-kcs.sh
+++ b/meta-facebook/meta-wedge/recipes-wedge/sms-kcsd/sms-kcsd/setup-sms-kcs.sh
@@ -2,6 +2,22 @@
#
# 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: setup-sms-kcs
# Required-Start:
diff --git a/meta-facebook/meta-wedge/recipes-wedge/sms-kcsd/sms-kcsd_0.1.bb b/meta-facebook/meta-wedge/recipes-wedge/sms-kcsd/sms-kcsd_0.1.bb
index 1f3ea08..812d815 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/sms-kcsd/sms-kcsd_0.1.bb
+++ b/meta-facebook/meta-wedge/recipes-wedge/sms-kcsd/sms-kcsd_0.1.bb
@@ -1,4 +1,19 @@
# 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
SUMMARY = "SMS KCS Daemon"
DESCRIPTION = "Daemon to handle SMS KCS interface."
SECTION = "base"
diff --git a/meta-facebook/meta-wedge/recipes-wedge/usb-console/usb-console_0.1.bb b/meta-facebook/meta-wedge/recipes-wedge/usb-console/usb-console_0.1.bb
index f92511c..c934f46 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/usb-console/usb-console_0.1.bb
+++ b/meta-facebook/meta-wedge/recipes-wedge/usb-console/usb-console_0.1.bb
@@ -1,4 +1,19 @@
# 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
SUMMARY = "Set up a USB serial console"
DESCRIPTION = "Sets up a USB serial console"
SECTION = "base"
diff --git a/meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/files/lib/Makefile b/meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/files/lib/Makefile
index 0264efe..8c05686 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/files/lib/Makefile
+++ b/meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/files/lib/Makefile
@@ -1,8 +1,24 @@
# 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
+
lib: libwedge_eeprom.so
libwedge_eeprom.so: wedge_eeprom.c
- $(CC) $(CCFLAGS) -fPIC -c -o wedge_eeprom.o wedge_eeprom.c
+ $(CC) $(CFLAGS) -fPIC -c -o wedge_eeprom.o wedge_eeprom.c
$(CC) -shared -o libwedge_eeprom.so wedge_eeprom.o -lc
.PHONY: clean
diff --git a/meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/files/lib/wedge_eeprom.c b/meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/files/lib/wedge_eeprom.c
index 44f708d..e66941e 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/files/lib/wedge_eeprom.c
+++ b/meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/files/lib/wedge_eeprom.c
@@ -23,9 +23,11 @@
#include <stdio.h>
#include <string.h>
-#include <facebook/log.h>
+#include <openbmc/log.h>
+#ifndef FBW_EEPROM_FILE
#define FBW_EEPROM_FILE "/sys/class/i2c-adapter/i2c-6/6-0050/eeprom"
+#endif
#define FBW_EEPROM_VERSION 0
#define FBW_EEPROM_V0_SIZE 162
diff --git a/meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/files/utils/Makefile b/meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/files/utils/Makefile
index 30aac75..f2aeadc 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/files/utils/Makefile
+++ b/meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/files/utils/Makefile
@@ -1,4 +1,20 @@
# 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
+
utils: weutil
weutil: weutil.o
diff --git a/meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/files/utils/weutil.c b/meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/files/utils/weutil.c
index 9e932aa..90aca10 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/files/utils/weutil.c
+++ b/meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/files/utils/weutil.c
@@ -20,7 +20,7 @@
#include <stdio.h>
#include <facebook/wedge_eeprom.h>
-#include <facebook/log.h>
+#include <openbmc/log.h>
int main(int argc, const char *argv[])
{
diff --git a/meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/libwedge-eeprom_0.1.bb b/meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/libwedge-eeprom_0.1.bb
index 781cf76..6f62557 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/libwedge-eeprom_0.1.bb
+++ b/meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/libwedge-eeprom_0.1.bb
@@ -1,4 +1,19 @@
# 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
SUMMARY = "Wedge EEPROM Library"
DESCRIPTION = "library for wedge eeprom"
SECTION = "base"
@@ -9,7 +24,7 @@ LIC_FILES_CHKSUM = "file://wedge_eeprom.c;beginline=4;endline=16;md5=da35978751a
SRC_URI = "file://lib \
"
-DEPENDS += "fbutils"
+DEPENDS += "liblog"
S = "${WORKDIR}/lib"
@@ -22,5 +37,4 @@ do_install() {
}
FILES_${PN} = "${libdir}/libwedge_eeprom.so"
-FILES_${PN}-dbg = "${libdir}/.debug"
FILES_${PN}-dev = "${includedir}/facebook/wedge_eeprom.h"
diff --git a/meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/wedge-eeprom_0.1.bb b/meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/wedge-eeprom_0.1.bb
index 51bdbb9..3afbed1 100644
--- a/meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/wedge-eeprom_0.1.bb
+++ b/meta-facebook/meta-wedge/recipes-wedge/wedge-eeprom/wedge-eeprom_0.1.bb
@@ -1,4 +1,19 @@
# 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
SUMMARY = "Wedge EEPROM Utilities"
DESCRIPTION = "Util for wedge eeprom"
SECTION = "base"
diff --git a/meta-facebook/meta-yosemite/conf/bblayers.conf.sample b/meta-facebook/meta-yosemite/conf/bblayers.conf.sample
new file mode 100644
index 0000000..8827e9d
--- /dev/null
+++ b/meta-facebook/meta-yosemite/conf/bblayers.conf.sample
@@ -0,0 +1,21 @@
+# LAYER_CONF_VERSION is increased each time build/conf/bblayers.conf
+# changes incompatibly
+LCONF_VERSION = "6"
+
+BBPATH = "${TOPDIR}"
+BBFILES ?= ""
+
+BBLAYERS ?= " \
+ ##OEROOT##/meta \
+ ##OEROOT##/meta-yocto \
+ ##OEROOT##/meta-yocto-bsp \
+ ##OEROOT##/meta-openembedded/meta-oe \
+ ##OEROOT##/meta-openembedded/meta-networking \
+ ##OEROOT##/meta-openbmc \
+ ##OEROOT##/meta-openbmc/meta-aspeed \
+ ##OEROOT##/meta-openbmc/meta-facebook/meta-yosemite \
+ "
+BBLAYERS_NON_REMOVABLE ?= " \
+ ##OEROOT##/meta \
+ ##OEROOT##/meta-yocto \
+ "
diff --git a/meta-facebook/meta-yosemite/conf/conf-notes.txt b/meta-facebook/meta-yosemite/conf/conf-notes.txt
new file mode 100644
index 0000000..87ebd18
--- /dev/null
+++ b/meta-facebook/meta-yosemite/conf/conf-notes.txt
@@ -0,0 +1,2 @@
+Common targets are:
+ yosemite-image
diff --git a/meta-facebook/meta-yosemite/conf/layer.conf b/meta-facebook/meta-yosemite/conf/layer.conf
new file mode 100644
index 0000000..281d2cc
--- /dev/null
+++ b/meta-facebook/meta-yosemite/conf/layer.conf
@@ -0,0 +1,10 @@
+# We have a conf and classes directory, add to BBPATH
+BBPATH .= ":${LAYERDIR}"
+
+# We have recipes-* directories, add to BBFILES
+BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
+ ${LAYERDIR}/recipes-*/*/*.bbappend"
+
+BBFILE_COLLECTIONS += "yosemite"
+BBFILE_PATTERN_yosemite = "^${LAYERDIR}/"
+BBFILE_PRIORITY_yosemite = "8"
diff --git a/meta-facebook/meta-yosemite/conf/local.conf.sample b/meta-facebook/meta-yosemite/conf/local.conf.sample
new file mode 100644
index 0000000..9204236
--- /dev/null
+++ b/meta-facebook/meta-yosemite/conf/local.conf.sample
@@ -0,0 +1,140 @@
+#
+# Local configuration file for building the OpenBMC image.
+#
+
+# Always look for packages first in our own local package mirror
+SOURCE_MIRROR_URL ?= "file://${TOPDIR}/../meta-openbmc/source_mirror/"
+INHERIT += "own-mirrors"
+
+# Save local tarballs for all packages we download.
+# This can be used to update our mirror directory above.
+BB_GENERATE_MIRROR_TARBALLS = "1"
+
+# The following setting will prevent bitbake from downloading anything over the
+# network. This can be used to ensure that we get everything from a local
+# file:// mirror.
+#
+# Comment this out if you do need to download new packages from the internet.
+# However, once you have downloaded the package you should check them into our
+# mirror repository so that other developers will always get it from the mirror
+# repo.
+BB_NO_NETWORK = "fb-only"
+
+# Parallelism Options
+#
+# How many tasks bitbake should run in parallel:
+BB_NUMBER_THREADS ?= "${@oe.utils.cpu_count()}"
+# How many processes make should run in parallel:
+PARALLEL_MAKE ?= "-j ${@oe.utils.cpu_count()}"
+
+# Machine Selection
+MACHINE ??= "yosemite"
+
+# Build directory locationds.
+#
+#DL_DIR ?= "${TOPDIR}/downloads"
+#SSTATE_DIR ?= "${TOPDIR}/sstate-cache"
+#TMPDIR = "${TOPDIR}/tmp"
+
+#
+# Default policy config
+# We could eventually create our own distro config if desired,
+# but for now we use the standard poky distro settings.
+#
+DISTRO ?= "poky"
+
+# Use RPM packages
+PACKAGE_CLASSES ?= "package_rpm"
+
+# Extra image features.
+# Currently we do not enable anything extra here.
+#EXTRA_IMAGE_FEATURES = ""
+
+# We build on CentOS 6.3.
+# Don't complain about it, even though it isn't in poky's default
+# list of supported distros.
+SANITY_TESTED_DISTROS_append ?= " CentOS-6.3 \n "
+
+#
+# Additional image features
+#
+# The following is a list of additional classes to use when building images which
+# enable extra features. Some available options which can be included in this variable
+# are:
+# - 'buildstats' collect build statistics
+# - 'image-mklibs' to reduce shared library files size for an image
+# - 'image-prelink' in order to prelink the filesystem image
+# - 'image-swab' to perform host system intrusion detection
+# NOTE: if listing mklibs & prelink both, then make sure mklibs is before prelink
+# NOTE: mklibs also needs to be explicitly enabled for a given image, see local.conf.extended
+USER_CLASSES ?= "buildstats image-mklibs image-prelink"
+
+#
+# Interactive shell configuration
+#
+# Under certain circumstances the system may need input from you and to do this it
+# can launch an interactive shell. It needs to do this since the build is
+# multithreaded and needs to be able to handle the case where more than one parallel
+# process may require the user's attention. The default is iterate over the available
+# terminal types to find one that works.
+#
+# Examples of the occasions this may happen are when resolving patches which cannot
+# be applied, to use the devshell or the kernel menuconfig
+#
+# Supported values are auto, gnome, xfce, rxvt, screen, konsole (KDE 3.x only), none
+# Note: currently, Konsole support only works for KDE 3.x due to the way
+# newer Konsole versions behave
+#OE_TERMINAL = "auto"
+# By default disable interactive patch resolution (tasks will just fail instead):
+PATCHRESOLVE = "noop"
+
+#
+# Disk Space Monitoring during the build
+#
+# Monitor the disk space during the build. If there is less that 1GB of space or less
+# than 100K inodes in any key build location (TMPDIR, DL_DIR, SSTATE_DIR), gracefully
+# shutdown the build. If there is less that 100MB or 1K inodes, perform a hard abort
+# of the build. The reason for this is that running completely out of space can corrupt
+# files and damages the build in ways which may not be easily recoverable.
+BB_DISKMON_DIRS = "\
+ STOPTASKS,${TMPDIR},1G,100K \
+ STOPTASKS,${DL_DIR},1G,100K \
+ STOPTASKS,${SSTATE_DIR},1G,100K \
+ ABORT,${TMPDIR},100M,1K \
+ ABORT,${DL_DIR},100M,1K \
+ ABORT,${SSTATE_DIR},100M,1K"
+
+#
+# Shared-state files from other locations
+#
+# As mentioned above, shared state files are prebuilt cache data objects which can
+# used to accelerate build time. This variable can be used to configure the system
+# to search other mirror locations for these objects before it builds the data itself.
+#
+# This can be a filesystem directory, or a remote url such as http or ftp. These
+# would contain the sstate-cache results from previous builds (possibly from other
+# machines). This variable works like fetcher MIRRORS/PREMIRRORS and points to the
+# cache locations to check for the shared objects.
+# NOTE: if the mirror uses the same structure as SSTATE_DIR, you need to add PATH
+# at the end as shown in the examples below. This will be substituted with the
+# correct path within the directory structure.
+#SSTATE_MIRRORS ?= "\
+#file://.* http://someserver.tld/share/sstate/PATH;downloadfilename=PATH \n \
+#file://.* file:///some/local/dir/sstate/PATH"
+
+
+# CONF_VERSION is increased each time build/conf/ changes incompatibly and is used to
+# track the version of this file when it was generated. This can safely be ignored if
+# this doesn't mean anything to you.
+CONF_VERSION = "1"
+
+
+# Update root password to '0penBmc' and change the root shell back to bash.
+# This default root password is used at the ODM and system integrator. It will be
+# changed during provisioning at the datacenter.
+INHERIT += "extrausers"
+
+EXTRA_USERS_PARAMS = " \
+ usermod -s /bin/bash root; \
+ usermod -p '\$1\$UGMqyqdG\$FZiylVFmRRfl9Z0Ue8G7e/' root; \
+ "
diff --git a/meta-facebook/meta-yosemite/conf/machine/yosemite.conf b/meta-facebook/meta-yosemite/conf/machine/yosemite.conf
new file mode 100644
index 0000000..cd48ed6
--- /dev/null
+++ b/meta-facebook/meta-yosemite/conf/machine/yosemite.conf
@@ -0,0 +1,7 @@
+#@TYPE: Machine
+#@NAME: Yosemite
+#@DESCRIPTION: Machine configuration for Facebook Yosemite
+
+UBOOT_MACHINE_yosemite = "fbyosemite_config"
+
+require conf/machine/include/ast1250.inc
diff --git a/meta-facebook/meta-yosemite/recipes-core/busybox/busybox/busybox.cfg b/meta-facebook/meta-yosemite/recipes-core/busybox/busybox/busybox.cfg
new file mode 100644
index 0000000..66da117
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-core/busybox/busybox/busybox.cfg
@@ -0,0 +1,18 @@
+CONFIG_SH_MATH_SUPPORT_64=y
+CONFIG_DEVMEM=y
+CONFIG_LSUSB=y
+CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS=y
+CONFIG_RX=y
+CONFIG_FLASHCP=y
+CONFIG_FLASH_LOCK=y
+CONFIG_FLASH_UNLOCK=y
+CONFIG_FLASH_ERASEALL=y
+CONFIG_TRACEROUTE6=y
+CONFIG_VCONFIG=y
+# we use the standalone ip util
+CONFIG_IP=n
+# use dhclient, as udhcpc will flush all v6 link local addresses during renew
+CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP=y
+CONFIG_UDHCPD=n
+CONFIG_UDHCPC=n
+CONFIG_UDHCPC6=n
diff --git a/meta-facebook/meta-yosemite/recipes-core/busybox/busybox_%.bbappend b/meta-facebook/meta-yosemite/recipes-core/busybox/busybox_%.bbappend
new file mode 100644
index 0000000..b8641ee
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-core/busybox/busybox_%.bbappend
@@ -0,0 +1,5 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+SRC_URI += " \
+ file://busybox.cfg \
+ " \ No newline at end of file
diff --git a/meta-facebook/meta-yosemite/recipes-core/images/yosemite-image.bb b/meta-facebook/meta-yosemite/recipes-core/images/yosemite-image.bb
new file mode 100644
index 0000000..300f167
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-core/images/yosemite-image.bb
@@ -0,0 +1 @@
+include yosemite-image.inc
diff --git a/meta-facebook/meta-yosemite/recipes-core/images/yosemite-image.inc b/meta-facebook/meta-yosemite/recipes-core/images/yosemite-image.inc
new file mode 100644
index 0000000..5356c20
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-core/images/yosemite-image.inc
@@ -0,0 +1,82 @@
+inherit aspeed_uboot_image
+
+# /dev
+require recipes-core/images/aspeed-dev.inc
+
+# Base this image on core-image-minimal
+include recipes-core/images/core-image-minimal.bb
+
+# Changing the image compression from gz to lzma achieves 30% saving (~3M).
+# However, the current u-boot does not have lzma enabled. Stick to gz
+# until we generate a new u-boot image.
+IMAGE_FSTYPES += "cpio.lzma.u-boot"
+UBOOT_IMAGE_ENTRYPOINT = "0x40800000"
+
+PYTHON_PKGS = " \
+ python-core \
+ python-io \
+ python-json \
+ python-shell \
+ python-subprocess \
+ python-argparse \
+ python-ctypes \
+ python-datetime \
+ python-email \
+ python-threading \
+ python-mime \
+ python-pickle \
+ python-misc \
+ python-netserver \
+ "
+
+NTP_PKGS = " \
+ ntp \
+ ntp-utils \
+ sntp \
+ ntpdate \
+ "
+
+# Include modules in rootfs
+IMAGE_INSTALL += " \
+ kernel-modules \
+ u-boot-fw-utils \
+ fbutils \
+ fan-ctrl \
+ watchdog-ctrl \
+ i2c-tools \
+ sensor-setup \
+ usb-console \
+ lmsensors-sensors \
+ rest-api \
+ bottle \
+ ipmid \
+ ${PYTHON_PKGS} \
+ ${NTP_PKGS} \
+ iproute2 \
+ dhcp-client \
+ fruid \
+ ipmbd \
+ bic-cached \
+ bic-util \
+ yosemite-sensors \
+ sensor-util \
+ sensor-mon \
+ gpiod \
+ front-paneld \
+ power-util \
+ consoled \
+ cfg-util \
+ "
+
+IMAGE_FEATURES += " \
+ ssh-server-openssh \
+ tools-debug \
+ "
+
+DISTRO_FEATURES += " \
+ ext2 \
+ ipv6 \
+ nfs \
+ usbgadget \
+ usbhost \
+ "
diff --git a/meta-facebook/meta-yosemite/recipes-core/init-ifupdown/files/interfaces b/meta-facebook/meta-yosemite/recipes-core/init-ifupdown/files/interfaces
new file mode 100644
index 0000000..36e342e
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-core/init-ifupdown/files/interfaces
@@ -0,0 +1,11 @@
+# The loopback interface
+auto lo
+iface lo inet loopback
+
+auto eth0
+iface eth0 inet dhcp
+
+auto usb0
+iface usb0 inet6 static
+ address fe80::1
+ netmask 64
diff --git a/meta-facebook/meta-yosemite/recipes-core/init-ifupdown/init-ifupdown_%.bbappend b/meta-facebook/meta-yosemite/recipes-core/init-ifupdown/init-ifupdown_%.bbappend
new file mode 100644
index 0000000..7d74521
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-core/init-ifupdown/init-ifupdown_%.bbappend
@@ -0,0 +1,2 @@
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
diff --git a/meta-facebook/meta-yosemite/recipes-core/sysvinit/sysvinit-inittab_%.bbappend b/meta-facebook/meta-yosemite/recipes-core/sysvinit/sysvinit-inittab_%.bbappend
new file mode 100644
index 0000000..9624d65
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-core/sysvinit/sysvinit-inittab_%.bbappend
@@ -0,0 +1,2 @@
+# ttyS0 is UART5, BMC's serial port
+SERIAL_CONSOLES += "57600;ttyS0"
diff --git a/meta-facebook/meta-yosemite/recipes-kernel/linux/linux-aspeed_2.6%.bbappend b/meta-facebook/meta-yosemite/recipes-kernel/linux/linux-aspeed_2.6%.bbappend
new file mode 100644
index 0000000..a317986
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-kernel/linux/linux-aspeed_2.6%.bbappend
@@ -0,0 +1,5 @@
+LINUX_VERSION_EXTENSION = "-yosemite"
+
+COMPATIBLE_MACHINE = "yosemite"
+
+KERNEL_CONFIG_COMMAND = "oe_runmake yosemite_defconfig && oe_runmake oldconfig"
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/bic-cached/bic-cached_0.1.bb b/meta-facebook/meta-yosemite/recipes-yosemite/bic-cached/bic-cached_0.1.bb
new file mode 100644
index 0000000..ef7a15c
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/bic-cached/bic-cached_0.1.bb
@@ -0,0 +1,44 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+
+SUMMARY = "Bridge IC Cache Daemon"
+DESCRIPTION = "Daemon to provide Bridge IC Cache information."
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://bic-cached.c;beginline=5;endline=17;md5=da35978751a9d71b73679307c4d296ec"
+
+
+DEPENDS_append = "libbic update-rc.d-native"
+
+SRC_URI = "file://Makefile \
+ file://setup-bic-cached.sh \
+ file://bic-cached.c \
+ "
+
+S = "${WORKDIR}"
+
+binfiles = "bic-cached"
+
+pkgdir = "bic-cached"
+
+do_install() {
+ dst="${D}/usr/local/fbpackages/${pkgdir}"
+ bin="${D}/usr/local/bin"
+ install -d $dst
+ install -d $bin
+ install -m 755 bic-cached ${dst}/bic-cached
+ ln -snf ../fbpackages/${pkgdir}/bic-cached ${bin}/bic-cached
+ install -d ${D}${sysconfdir}/init.d
+ install -d ${D}${sysconfdir}/rcS.d
+ install -m 755 setup-bic-cached.sh ${D}${sysconfdir}/init.d/setup-bic-cached.sh
+ update-rc.d -r ${D} setup-bic-cached.sh start 66 S .
+}
+
+FBPACKAGEDIR = "${prefix}/local/fbpackages"
+
+FILES_${PN} = "${FBPACKAGEDIR}/bic-cached ${prefix}/local/bin ${sysconfdir} "
+
+# Inhibit complaints about .debug directories:
+
+INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
+INHIBIT_PACKAGE_STRIP = "1"
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/bic-cached/files/Makefile b/meta-facebook/meta-yosemite/recipes-yosemite/bic-cached/files/Makefile
new file mode 100644
index 0000000..478b25e
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/bic-cached/files/Makefile
@@ -0,0 +1,10 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+all: bic-cached
+
+bic-cached: bic-cached.c
+ $(CC) -pthread -lbic -std=c99 -o $@ $^ $(LDFLAGS)
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o bic-cached
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/bic-cached/files/bic-cached.c b/meta-facebook/meta-yosemite/recipes-yosemite/bic-cached/files/bic-cached.c
new file mode 100644
index 0000000..3a2dd28
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/bic-cached/files/bic-cached.c
@@ -0,0 +1,133 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <syslog.h>
+#include <string.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <openbmc/ipmi.h>
+#include <openbmc/ipmb.h>
+#include <facebook/bic.h>
+
+#define LAST_RECORD_ID 0xFFFF
+#define MAX_SENSOR_NUM 0xFF
+#define BYTES_ENTIRE_RECORD 0xFF
+
+void
+fruid_cache_init(uint8_t slot_id) {
+ // Initialize Slot0's fruid
+ int ret;
+ int i;
+ char fruid_temp_path[64] = {0};
+ char fruid_path[64] = {0};
+
+ sprintf(fruid_temp_path, "/tmp/tfruid_slot%d.bin", slot_id);
+ sprintf(fruid_path, "/tmp/fruid_slot%d.bin", slot_id);
+
+ ret = bic_read_fruid(slot_id, 0, fruid_temp_path);
+ if (ret) {
+ syslog(LOG_ALERT, "fruid_cache_init: bic_read_fruid returns %d\n", ret);
+ }
+
+ rename(fruid_temp_path, fruid_path);
+
+ return;
+}
+
+void
+sdr_cache_init(uint8_t slot_id) {
+ int ret;
+ int fd;
+ uint8_t rlen;
+ uint8_t rbuf[MAX_IPMB_RES_LEN] = {0};
+ char *path = NULL;
+ char sdr_temp_path[64] = {0};
+ char sdr_path[64] = {0};
+
+ sprintf(sdr_temp_path, "/tmp/tsdr_slot%d.bin", slot_id);
+ sprintf(sdr_path, "/tmp/sdr_slot%d.bin", slot_id);
+
+ ipmi_sel_sdr_req_t req;
+ ipmi_sel_sdr_res_t *res = (ipmi_sel_sdr_res_t *) rbuf;
+
+ req.rsv_id = 0;
+ req.rec_id = 0;
+ req.offset = 0;
+ req.nbytes = BYTES_ENTIRE_RECORD;
+
+ // Read Slot0's SDR records and store
+ path = sdr_temp_path;
+ unlink(path);
+ fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0666);
+ if (fd < 0) {
+ syslog(LOG_ALERT, "sdr_cache_init: open fails for path: %s\n", path);
+ return;
+ }
+
+ while (1) {
+ ret = bic_get_sdr(slot_id, &req, res, &rlen);
+ if (ret) {
+ syslog(LOG_ALERT, "sdr_cache_init:bic_get_sdr returns %d\n", ret);
+ continue;
+ }
+
+ sdr_full_t *sdr = res->data;
+
+ write(fd, sdr, sizeof(sdr_full_t));
+
+ req.rec_id = res->next_rec_id;
+ if (req.rec_id == LAST_RECORD_ID) {
+ // syslog(LOG_INFO, "This record is LAST record\n");
+ break;
+ }
+ }
+
+ rename(sdr_temp_path, sdr_path);
+}
+
+int
+main (int argc, char * const argv[])
+{
+ int ret;
+ ipmi_dev_id_t id = {0};
+ uint8_t slot_id;
+
+ if (argc != 2) {
+ return -1;
+ }
+
+ slot_id = atoi(argv[1]);
+
+ do {
+ ret = bic_get_dev_id(slot_id, &id);
+ sleep(5);
+ } while (ret != 0);
+
+ fruid_cache_init(slot_id);
+ sdr_cache_init(slot_id);
+
+ return 0;
+}
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/bic-cached/files/setup-bic-cached.sh b/meta-facebook/meta-yosemite/recipes-yosemite/bic-cached/files/setup-bic-cached.sh
new file mode 100644
index 0000000..45eb1e3
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/bic-cached/files/setup-bic-cached.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+#
+# Copyright 2015-present Facebook. All Rights Reserved.
+#
+### BEGIN INIT INFO
+# Provides: setup-bic-cached
+# Required-Start:
+# Required-Stop:
+# Default-Start: S
+# Default-Stop:
+# Short-Description: Set Cachcing for Bridge IC info
+### END INIT INFO
+
+. /usr/local/fbpackages/utils/ast-functions
+
+echo -n "Setup Caching for Bridge IC info.."
+if [ $(is_server_prsnt 1) == "1" ]; then
+ /usr/local/bin/bic-cached 1 > /dev/null 2>&1 &
+fi
+
+if [ $(is_server_prsnt 2) == "1" ]; then
+/usr/local/bin/bic-cached 2 > /dev/null 2>&1 &
+fi
+
+if [ $(is_server_prsnt 3) == "1" ]; then
+/usr/local/bin/bic-cached 3 > /dev/null 2>&1 &
+fi
+
+if [ $(is_server_prsnt 4) == "1" ]; then
+/usr/local/bin/bic-cached 4 > /dev/null 2>&1 &
+fi
+
+echo "done."
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/consoled/consoled_0.1.bbappend b/meta-facebook/meta-yosemite/recipes-yosemite/consoled/consoled_0.1.bbappend
new file mode 100644
index 0000000..12a1d17
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/consoled/consoled_0.1.bbappend
@@ -0,0 +1,53 @@
+# 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
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+SRC_URI += "file://setup-consoled.sh \
+ "
+
+S = "${WORKDIR}"
+
+
+pkgdir = "consoled"
+
+do_install() {
+ dst="${D}/usr/local/fbpackages/${pkgdir}"
+ bin="${D}/usr/local/bin"
+ install -d $dst
+ install -d $bin
+ for f in ${binfiles}; do
+ install -m 755 $f ${dst}/$f
+ ln -snf ../fbpackages/${pkgdir}/$f ${bin}/$f
+ done
+ for f in ${otherfiles}; do
+ install -m 644 $f ${dst}/$f
+ done
+ install -d ${D}${sysconfdir}/init.d
+ install -d ${D}${sysconfdir}/rcS.d
+ install -m 755 setup-consoled.sh ${D}${sysconfdir}/init.d/setup-consoled.sh
+ update-rc.d -r ${D} setup-consoled.sh start 91 S .
+}
+
+FBPACKAGEDIR = "${prefix}/local/fbpackages"
+
+FILES_${PN} = "${FBPACKAGEDIR}/consoled ${prefix}/local/bin ${sysconfdir} "
+
+# Inhibit complaints about .debug directories for the sensord binary:
+
+INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
+INHIBIT_PACKAGE_STRIP = "1"
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/consoled/files/setup-consoled.sh b/meta-facebook/meta-yosemite/recipes-yosemite/consoled/files/setup-consoled.sh
new file mode 100644
index 0000000..8c50e49
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/consoled/files/setup-consoled.sh
@@ -0,0 +1,51 @@
+#!/bin/sh
+#
+# 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
+#
+
+### BEGIN INIT INFO
+# Provides: setup-consoled
+# Required-Start:
+# Required-Stop:
+# Default-Start: S
+# Default-Stop:
+# Short-Description: Setup console history buffering
+### END INIT INFO
+
+. /usr/local/fbpackages/utils/ast-functions
+
+# TODO: check for the if slot/server is present before starting the daemon
+echo -n "Setup console buffering..."
+
+ if [ $(is_server_prsnt 1) == "1" ] ; then
+ /usr/local/bin/consoled slot1 --buffer
+ fi
+
+ if [ $(is_server_prsnt 2) == "1" ] ; then
+ /usr/local/bin/consoled slot2 --buffer
+ fi
+
+ if [ $(is_server_prsnt 3) == "1" ] ; then
+ /usr/local/bin/consoled slot3 --buffer
+ fi
+
+ if [ $(is_server_prsnt 4) == "1" ] ; then
+ /usr/local/bin/consoled slot4 --buffer
+ fi
+
+echo "done."
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fan-ctrl/fan-ctrl/get_fan_speed.sh b/meta-facebook/meta-yosemite/recipes-yosemite/fan-ctrl/fan-ctrl/get_fan_speed.sh
new file mode 100755
index 0000000..c77c6f0
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fan-ctrl/fan-ctrl/get_fan_speed.sh
@@ -0,0 +1,53 @@
+#!/bin/sh
+#
+# 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
+#
+usage() {
+ echo "Usage: $0 [Fan Unit (0..1)]" >&2
+}
+
+PWM_DIR=/sys/devices/platform/ast_pwm_tacho.0
+set -e
+
+# refer to the comments in init_pwn.sh regarding
+# the fan unit and tacho mapping
+if [ "$#" -eq 0 ]; then
+ TACHOS="0:0 1:1"
+elif [ "$#" -eq 1 ]; then
+ case "$1" in
+ "0")
+ TACHOS="0:0"
+ ;;
+ "1")
+ TACHOS="1:1"
+ ;;
+ *)
+ usage
+ exit 1
+ ;;
+ esac
+else
+ usage
+ exit 1
+fi
+
+for fan_tacho in $TACHOS; do
+ fan=${fan_tacho%%:*}
+ tacho=${fan_tacho##*:}
+ echo "Fan $fan RPM: $(cat $PWM_DIR/tacho${tacho}_rpm)"
+done
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fan-ctrl/fan-ctrl/init_pwm.sh b/meta-facebook/meta-yosemite/recipes-yosemite/fan-ctrl/fan-ctrl/init_pwm.sh
new file mode 100755
index 0000000..8c8adc6
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fan-ctrl/fan-ctrl/init_pwm.sh
@@ -0,0 +1,64 @@
+#!/bin/sh
+#
+# 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
+#
+PWM_DIR=/sys/devices/platform/ast_pwm_tacho.0
+
+set -e
+
+# The PWM frequency is
+
+# clk_source / ((2 ^ division_) * (2 * division_l) * (unit + 1))
+#
+# Our clk_source is 24Mhz. 4-pin fans are generally supposed to be driven with
+# a 25Khz PWM control signal. Therefore we want the divisor to equal 960.
+#
+# We also want the unit to be as large as possible, since this controls the
+# granularity with which we can modulate the PWM signal. The following
+# settings allow us to set the fan from 0 to 100% in increments of 1/96th.
+#
+# The AST chip supports 3 different PWM clock configurations, but we only use
+# type M for now.
+echo 0 > $PWM_DIR/pwm_type_m_division_h
+echo 5 > $PWM_DIR/pwm_type_m_division_l
+echo 95 > $PWM_DIR/pwm_type_m_unit
+
+# On Yosemite, there are 2 fans connected.
+# Each fan uses same PWM input and provide one tacho output.
+# Here is the mapping between the fan and PWN/Tacho,
+# staring from the one from the edge
+# Fan 0: PWM 0, Tacho0
+# Fan 1: PWM 0, Tacho1
+
+# For each fan, setting the type, and 100% initially
+for pwm in 0 1; do
+ echo 0 > $PWM_DIR/pwm${pwm}_type
+ echo 0 > $PWM_DIR/pwm${pwm}_rising
+ echo 0 > $PWM_DIR/pwm${pwm}_falling
+ echo 1 > $PWM_DIR/pwm${pwm}_en
+done
+
+# Enable Tach 0..1
+echo 0 > $PWM_DIR/tacho0_source
+echo 1 > $PWM_DIR/tacho1_source
+
+t=0
+while [ $t -le 1 ]; do
+ echo 1 > $PWM_DIR/tacho${t}_en
+ t=$((t+1))
+done
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fan-ctrl/fan-ctrl/set_fan_speed.sh b/meta-facebook/meta-yosemite/recipes-yosemite/fan-ctrl/fan-ctrl/set_fan_speed.sh
new file mode 100755
index 0000000..49ef55b
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fan-ctrl/fan-ctrl/set_fan_speed.sh
@@ -0,0 +1,79 @@
+#!/bin/sh
+#
+# 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
+#
+usage() {
+ echo "Usage: $0 <PERCENT (0..100)> <Fan Unit (0..1)> " >&2
+}
+
+PWM_DIR=/sys/devices/platform/ast_pwm_tacho.0
+
+# The maximum unit setting.
+# This should be the value in pwm_type_m_unit plus 1
+PWM_UNIT_MAX=96
+
+set -e
+
+if [ "$#" -ne 2 ] && [ "$#" -ne 1 ]; then
+ usage
+ exit 1
+fi
+
+# refer to the comments in init_pwn.sh regarding
+# the fan unit and PWM mapping
+if [ "$#" -eq 1 ]; then
+ PWMS="0:0 1:0"
+else
+ case "$2" in
+ "0")
+ PWMS="0:0"
+ ;;
+ "1")
+ PWMS="1:0"
+ ;;
+ *)
+ usage
+ exit 1
+ ;;
+ esac
+fi
+
+# Convert the percentage to our 1/96th unit.
+unit=$(( ( $1 * $PWM_UNIT_MAX ) / 100 ))
+
+for FAN_PWM in $PWMS; do
+ FAN_N=${FAN_PWM%%:*}
+ PWM_N=${FAN_PWM##*:}
+ if [ "$unit" -eq 0 ]; then
+ # For 0%, turn off the PWM entirely
+ echo 0 > $PWM_DIR/pwm${PWM_N}_en
+ else
+ if [ "$unit" -eq $PWM_UNIT_MAX ]; then
+ # For 100%, set falling and rising to the same value
+ unit=0
+ fi
+
+ # always use type M. refer to the comments in init_pwm.sh
+ echo 0 > $PWM_DIR/pwm${PWM_N}_type
+ echo 0 > $PWM_DIR/pwm${PWM_N}_rising
+ echo "$unit" > $PWM_DIR/pwm${PWM_N}_falling
+ echo 1 > $PWM_DIR/pwm${PWM_N}_en
+ fi
+
+ echo "Successfully set fan ${FAN_N} (PWM: $PWM_N) speed to $1%"
+done
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fan-ctrl/fan-ctrl/setup-fan.sh b/meta-facebook/meta-yosemite/recipes-yosemite/fan-ctrl/fan-ctrl/setup-fan.sh
new file mode 100644
index 0000000..72016d0
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fan-ctrl/fan-ctrl/setup-fan.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+#
+# 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
+#
+
+### BEGIN INIT INFO
+# Provides: setup-fan
+# Required-Start: board-id
+# Required-Stop:
+# Default-Start: S
+# Default-Stop:
+# Short-Description: Set fan speed
+### END INIT INFO
+
+. /usr/local/fbpackages/utils/ast-functions
+
+echo -n "Setup fan speed... "
+/usr/local/bin/init_pwm.sh
+/usr/local/bin/set_fan_speed.sh 50
+/usr/local/bin/fand
+echo "done."
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fan-ctrl/fan-ctrl_0.1.bbappend b/meta-facebook/meta-yosemite/recipes-yosemite/fan-ctrl/fan-ctrl_0.1.bbappend
new file mode 100644
index 0000000..d5659ae
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fan-ctrl/fan-ctrl_0.1.bbappend
@@ -0,0 +1,64 @@
+# 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
+
+DEPENDS_append = "update-rc.d-native libyosemite-sensor"
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+SRC_URI += "file://get_fan_speed.sh \
+ file://init_pwm.sh \
+ file://set_fan_speed.sh \
+ file://setup-fan.sh \
+ "
+
+S = "${WORKDIR}"
+
+binfiles += "get_fan_speed.sh \
+ init_pwm.sh \
+ set_fan_speed.sh \
+ "
+
+CXXFLAGS_prepend = "-DCONFIG_YOSEMITE "
+LDFLAGS_append = " -lyosemite_sensor"
+
+pkgdir = "fan_ctrl"
+
+do_install() {
+ dst="${D}/usr/local/fbpackages/${pkgdir}"
+ bin="${D}/usr/local/bin"
+ install -d $dst
+ install -d $bin
+ for f in ${binfiles}; do
+ install -m 755 $f ${dst}/$f
+ ln -snf ../fbpackages/${pkgdir}/$f ${bin}/$f
+ done
+ for f in ${otherfiles}; do
+ install -m 644 $f ${dst}/$f
+ done
+ install -d ${D}${sysconfdir}/init.d
+ install -d ${D}${sysconfdir}/rcS.d
+ install -m 755 setup-fan.sh ${D}${sysconfdir}/init.d/setup-fan.sh
+ update-rc.d -r ${D} setup-fan.sh start 91 S .
+}
+
+FBPACKAGEDIR = "${prefix}/local/fbpackages"
+
+FILES_${PN} = "${FBPACKAGEDIR}/fan_ctrl ${prefix}/local/bin ${sysconfdir} "
+
+# Inhibit complaints about .debug directories for the fand binary:
+
+INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
+INHIBIT_PACKAGE_STRIP = "1"
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/Makefile b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/Makefile
new file mode 100644
index 0000000..12cb085
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/Makefile
@@ -0,0 +1,11 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+lib: libbic.so
+
+libbic.so: bic.c
+ $(CC) $(CFLAGS) -fPIC -c -o bic.o bic.c
+ $(CC) -lipmb -shared -o libbic.so bic.o -lc
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o libbic.so
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/bic.c b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/bic.c
new file mode 100644
index 0000000..55cd56b
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/bic.c
@@ -0,0 +1,466 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * This file contains code to support IPMI2.0 Specificaton available @
+ * http://www.intel.com/content/www/us/en/servers/ipmi/ipmi-specifications.html
+ *
+ * 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.
+ */
+#include <stdio.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include "bic.h"
+
+#define FRUID_READ_COUNT_MAX 0x30
+#define SDR_READ_COUNT_MAX 0x1A
+
+enum {
+ IPMB_BUS_SLOT1 = 3,
+ IPMB_BUS_SLOT2 = 1,
+ IPMB_BUS_SLOT3 = 7,
+ IPMB_BUS_SLOT4 = 5,
+};
+
+#pragma pack(push, 1)
+typedef struct _sdr_rec_hdr_t {
+ uint16_t rec_id;
+ uint8_t ver;
+ uint8_t type;
+ uint8_t len;
+} sdr_rec_hdr_t;
+#pragma pack(pop)
+
+// Common IPMB Wrapper function
+
+static int
+get_ipmb_bus_id(uint8_t slot_id) {
+ int bus_id;
+
+ switch(slot_id) {
+ case 1:
+ bus_id = IPMB_BUS_SLOT1;
+ break;
+ case 2:
+ bus_id = IPMB_BUS_SLOT2;
+ break;
+ case 3:
+ bus_id = IPMB_BUS_SLOT3;
+ break;
+ case 4:
+ bus_id = IPMB_BUS_SLOT4;
+ break;
+ default:
+ bus_id = -1;
+ break;
+ }
+
+ return bus_id;
+}
+
+static int
+bic_ipmb_wrapper(uint8_t slot_id, uint8_t netfn, uint8_t cmd,
+ uint8_t *txbuf, uint8_t txlen,
+ uint8_t *rxbuf, uint8_t *rxlen) {
+ ipmb_req_t *req;
+ ipmb_res_t *res;
+ uint8_t rbuf[MAX_IPMB_RES_LEN] = {0};
+ uint8_t tbuf[MAX_IPMB_RES_LEN] = {0};
+ uint8_t tlen = 0;
+ uint8_t rlen = 0;
+ int count = 0;
+ int i = 0;
+ int ret;
+ uint8_t bus_id;
+
+ ret = get_ipmb_bus_id(slot_id);
+ if (ret < 0) {
+ printf("bic_ipmb_wrapper: Wrong Slot ID %d\n", slot_id);
+ return ret;
+ }
+
+ bus_id = (uint8_t) ret;
+
+ req = (ipmb_req_t*)tbuf;
+
+ req->res_slave_addr = BRIDGE_SLAVE_ADDR << 1;
+ req->netfn_lun = netfn << LUN_OFFSET;
+ req->hdr_cksum = req->res_slave_addr +
+ req->netfn_lun;
+ req->hdr_cksum = ZERO_CKSUM_CONST - req->hdr_cksum;
+
+ req->req_slave_addr = BMC_SLAVE_ADDR << 1;
+ req->seq_lun = 0x00;
+ req->cmd = cmd;
+
+ //copy the data to be send
+ if (txlen) {
+ memcpy(req->data, txbuf, txlen);
+ }
+
+ tlen = IPMB_HDR_SIZE + IPMI_REQ_HDR_SIZE + txlen;
+
+ // Invoke IPMB library handler
+ lib_ipmb_handle(bus_id, tbuf, tlen, &rbuf, &rlen);
+ if (rlen == 0) {
+ printf("bic_ipmb_wrapper: Zero bytes received\n");
+ return -1;
+ }
+
+ // Handle IPMB response
+ res = (ipmb_res_t*) rbuf;
+
+ if (res->cc) {
+ printf("bic_ipmb_wrapper: Completion Code: 0x%X\n", res->cc);
+ return -1;
+ }
+
+ // copy the received data back to caller
+ *rxlen = rlen - IPMB_HDR_SIZE - IPMI_RESP_HDR_SIZE;
+ memcpy(rxbuf, res->data, *rxlen);
+
+ return 0;
+}
+
+// Get Device ID
+int
+bic_get_dev_id(uint8_t slot_id, ipmi_dev_id_t *dev_id) {
+ uint8_t rlen = 0;
+ int ret;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_APP_REQ, CMD_APP_GET_DEVICE_ID, NULL, 0, (uint8_t *) dev_id, &rlen);
+
+ return ret;
+}
+
+// Get GPIO value and configuration
+int
+bic_get_gpio(uint8_t slot_id, bic_gpio_t *gpio) {
+ uint8_t rlen = 0;
+ int ret;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_OEM_1S_REQ, CMD_OEM_1S_GET_GPIO, NULL, 0, (uint8_t*) gpio, &rlen);
+
+ return ret;
+}
+
+int
+bic_get_gpio_config(uint8_t slot_id, uint8_t gpio, bic_gpio_config_t *gpio_config) {
+ uint8_t tbuf[4] = {0};
+ uint8_t rlen = 0;
+ uint8_t tlen = 0;
+ uint32_t pin;
+ int ret;
+
+ pin = 1 << gpio;
+
+ tbuf[0] = pin & 0xFF;
+ tbuf[1] = (pin >> 8) & 0xFF;
+ tbuf[2] = (pin >> 16) & 0xFF;
+ tbuf[3] = (pin >> 24) & 0xFF;
+
+ tlen = 4;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_OEM_1S_REQ, CMD_OEM_1S_GET_GPIO_CONFIG, tbuf, tlen, (uint8_t *) gpio_config, &rlen);
+
+ return ret;
+}
+
+int
+bic_set_gpio_config(uint8_t slot_id, uint8_t gpio, bic_gpio_config_t *gpio_config) {
+ uint8_t tbuf[5] = {0};
+ uint8_t rlen = 0;
+ uint8_t tlen = 0;
+ uint32_t pin;
+ uint8_t res;
+ int ret;
+
+ pin = 1 << gpio;
+
+ tbuf[0] = pin & 0xFF;
+ tbuf[1] = (pin >> 8) & 0xFF;
+ tbuf[2] = (pin >> 16) & 0xFF;
+ tbuf[3] = (pin >> 24) & 0xFF;
+ tbuf[4] = (*(uint8_t *) gpio_config) & 0x1F;
+
+ tlen = 5;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_OEM_1S_REQ, CMD_OEM_1S_SET_GPIO_CONFIG,
+ tbuf, tlen, &res, &rlen);
+ return ret;
+}
+
+// Get BIC Configuration
+int
+bic_get_config(uint8_t slot_id, bic_config_t *cfg) {
+ uint8_t rlen = 0;
+ int ret;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_OEM_1S_REQ, CMD_OEM_1S_GET_CONFIG,
+ NULL, 0x00, (uint8_t *) cfg, &rlen);
+ return ret;
+}
+
+// Set BIC Configuration
+int
+bic_set_config(uint8_t slot_id, bic_config_t *cfg) {
+ uint8_t rlen = 0;
+ uint8_t rbuf[4] = {0};
+ int ret;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_OEM_1S_REQ, CMD_OEM_1S_SET_CONFIG,
+ (uint8_t *) cfg, 1, rbuf, &rlen);
+ return ret;
+}
+
+// Read POST Buffer
+int
+bic_get_post_buf(uint8_t slot_id, uint8_t *buf, uint8_t *len) {
+ int ret;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_OEM_1S_REQ, CMD_OEM_1S_GET_POST_BUF, NULL, 0, buf, len);
+
+ return ret;
+}
+
+// Read 1S server's FRUID
+int
+bic_get_fruid_info(uint8_t slot_id, uint8_t fru_id, ipmi_fruid_info_t *info) {
+ int ret;
+ uint8_t rlen = 0;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_STORAGE_REQ, CMD_STORAGE_GET_FRUID_INFO, &fru_id, 1, (uint8_t *) info, &rlen);
+
+ return ret;
+}
+
+static int
+_read_fruid(uint8_t slot_id, uint8_t fru_id, uint32_t offset, uint8_t count, uint8_t *rbuf, uint8_t *rlen) {
+ int ret;
+ uint8_t tbuf[4] = {0};
+ uint8_t tlen = 0;
+
+ tbuf[0] = fru_id;
+ tbuf[1] = offset & 0xFF;
+ tbuf[2] = (offset >> 8) & 0xFF;
+ tbuf[3] = count;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_STORAGE_REQ, CMD_STORAGE_READ_FRUID_DATA, tbuf, 4, rbuf, rlen);
+
+ return ret;
+}
+
+int
+bic_read_fruid(uint8_t slot_id, uint8_t fru_id, const char *path) {
+ int ret;
+ uint32_t nread;
+ uint32_t offset;
+ uint8_t count;
+ uint8_t rbuf[256] = {0};
+ uint8_t rlen = 0;
+ int fd;
+ ipmi_fruid_info_t info;
+
+ // Remove the file if exists already
+ unlink(path);
+
+ // Open the file exclusively for write
+ fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0666);
+ if (fd < 0) {
+ printf("bic_read_fruid: open fails for path: %s\n", path);
+ goto error_exit;
+ }
+
+ // Read the FRUID information
+ ret = bic_get_fruid_info(slot_id, fru_id, &info);
+ if (ret) {
+ printf("bic_read_fruid: bic_read_fruid_info returns %d\n", ret);
+ goto error_exit;
+ }
+
+ // Indicates the size of the FRUID
+ nread = (info.size_msb << 8) + (info.size_lsb);
+
+ // Read chunks of FRUID binary data in a loop
+ offset = 0;
+ while (nread > 0) {
+ if (nread > FRUID_READ_COUNT_MAX) {
+ count = FRUID_READ_COUNT_MAX;
+ } else {
+ count = nread;
+ }
+
+ ret = _read_fruid(slot_id, fru_id, offset, count, rbuf, &rlen);
+ if (ret) {
+ printf("bic_read_fruid: ipmb_wrapper fails\n");
+ goto error_exit;
+ }
+
+ // Ignore the first byte as it indicates length of response
+ write(fd, &rbuf[1], rlen-1);
+
+ // Update offset
+ offset += (rlen-1);
+ nread -= (rlen-1);
+ }
+
+error_exit:
+ if (fd > 0 ) {
+ close(fd);
+ }
+
+ return ret;
+}
+
+// Read System Event Log (SEL)
+int
+bic_get_sel_info(uint8_t slot_id, ipmi_sel_sdr_info_t *info) {
+ int ret;
+ uint8_t rlen = 0;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_STORAGE_REQ, CMD_STORAGE_GET_SEL_INFO, NULL, 0, (uint8_t *)info, &rlen);
+
+ return ret;
+}
+
+static int
+_get_sel_rsv(uint8_t slot_id, uint16_t *rsv) {
+ int ret;
+ uint8_t rlen = 0;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_STORAGE_REQ, CMD_STORAGE_RSV_SEL, NULL, 0, (uint8_t *) rsv, &rlen);
+ return ret;
+}
+
+int
+bic_get_sel(uint8_t slot_id, ipmi_sel_sdr_req_t *req, ipmi_sel_sdr_res_t *res, uint8_t *rlen) {
+
+ int ret;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_STORAGE_REQ, CMD_STORAGE_GET_SEL, (uint8_t *)req, sizeof(ipmi_sel_sdr_req_t), (uint8_t*)res, rlen);
+
+ return ret;
+}
+
+// Read Sensor Data Records (SDR)
+int
+bic_get_sdr_info(uint8_t slot_id, ipmi_sel_sdr_info_t *info) {
+ int ret;
+ uint8_t rlen = 0;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_STORAGE_REQ, CMD_STORAGE_GET_SDR_INFO, NULL, 0, (uint8_t *) info, &rlen);
+
+ return ret;
+}
+
+static int
+_get_sdr_rsv(uint8_t slot_id, uint16_t *rsv) {
+ int ret;
+ uint8_t rlen = 0;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_STORAGE_REQ, CMD_STORAGE_RSV_SDR, NULL, 0, (uint8_t *) rsv, &rlen);
+
+ return ret;
+}
+
+static int
+_get_sdr(uint8_t slot_id, ipmi_sel_sdr_req_t *req, ipmi_sel_sdr_res_t *res, uint8_t *rlen) {
+ int ret;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_STORAGE_REQ, CMD_STORAGE_GET_SDR, (uint8_t *)req, sizeof(ipmi_sel_sdr_req_t), (uint8_t*)res, rlen);
+
+ return ret;
+}
+
+int
+bic_get_sdr(uint8_t slot_id, ipmi_sel_sdr_req_t *req, ipmi_sel_sdr_res_t *res, uint8_t *rlen) {
+ int ret;
+ uint8_t tbuf[MAX_IPMB_RES_LEN] = {0};
+ uint8_t tlen;
+ uint8_t len;
+ ipmi_sel_sdr_res_t *tres;
+ sdr_rec_hdr_t *hdr;
+
+ tres = (ipmi_sel_sdr_res_t *) tbuf;
+
+ // Get SDR reservation ID for the given record
+ ret = _get_sdr_rsv(slot_id, &req->rsv_id);
+ if (ret) {
+ printf("bic_read_sdr: _get_sdr_rsv returns %d\n", ret);
+ return ret;
+ }
+
+ // Initialize the response length to zero
+ *rlen = 0;
+
+ // Read SDR Record Header
+ req->offset = 0;
+ req->nbytes = sizeof(sdr_rec_hdr_t);
+
+ ret = _get_sdr(slot_id, req, tbuf, &tlen);
+ if (ret) {
+ printf("bic_read_sdr: _get_sdr returns %d\n", ret);
+ return ret;
+ }
+
+ // Copy the next record id to response
+ res->next_rec_id = tres->next_rec_id;
+
+ // Copy the header excluding first two bytes(next_rec_id)
+ memcpy(res->data, tres->data, tlen-2);
+
+ // Update response length and offset for next request
+ *rlen += tlen-2;
+ req->offset = tlen-2;
+
+ // Find length of data from header info
+ hdr = (sdr_rec_hdr_t *) tres->data;
+ len = hdr->len;
+
+ // Keep reading chunks of SDR record in a loop
+ while (len > 0) {
+ if (len > SDR_READ_COUNT_MAX) {
+ req->nbytes = SDR_READ_COUNT_MAX;
+ } else {
+ req->nbytes = len;
+ }
+
+ ret = _get_sdr(slot_id, req, tbuf, &tlen);
+ if (ret) {
+ printf("bic_read_sdr: _get_sdr returns %d\n", ret);
+ return ret;
+ }
+
+ // Copy the data excluding the first two bytes(next_rec_id)
+ memcpy(&res->data[req->offset], tres->data, tlen-2);
+
+ // Update response length, offset for next request, and remaining length
+ *rlen += tlen-2;
+ req->offset += tlen-2;
+ len -= tlen-2;
+ }
+
+ return 0;
+}
+
+int
+bic_read_sensor(uint8_t slot_id, uint8_t sensor_num, ipmi_sensor_reading_t *sensor) {
+ int ret;
+ int rlen = 0;
+
+ ret = bic_ipmb_wrapper(slot_id, NETFN_SENSOR_REQ, CMD_SENSOR_GET_SENSOR_READING, (uint8_t *)&sensor_num, 1, (uint8_t *)sensor, &rlen);
+
+ return ret;
+}
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/bic.h b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/bic.h
new file mode 100644
index 0000000..47b0baa
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/bic/bic.h
@@ -0,0 +1,156 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ *
+ * 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.
+ */
+
+#ifndef __BIC_H__
+#define __BIC_H__
+
+#include <openbmc/ipmi.h>
+#include <openbmc/ipmb.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAX_GPIO_PINS 32
+
+// GPIO PINS
+enum {
+ PWRGOOD_CPU = 0x0,
+ PWRGD_PCH_PWROK,
+ PVDDR_VRHOT_N,
+ PVCCIN_VRHOT_N,
+ FM_FAST_PROCHOT_N,
+ PCHHOT_CPU_N,
+ FM_CPLD_CPU_DIMM_EVENT_CO_N,
+ FM_CPLD_BDXDE_THERMTRIP_N,
+ THERMTRIP_PCH_N,
+ FM_CPLD_FIVR_FAULT,
+ FM_BDXDE_CATERR_LVT3_N,
+ FM_BDXDE_ERR2_LVT3_N,
+ FM_BDXDE_ERR1_LVT3_N,
+ FM_BDXDE_ERR0_LVT3_N,
+ SLP_S4_N,
+ FM_NMI_EVENT_BMC_N,
+ FM_SMI_BMC_N,
+ RST_PLTRST_BMC_N,
+ FP_RST_BTN_BUF_N,
+ BMC_RST_BTN_OUT_N,
+ FM_BDE_POST_CMPLT_N,
+ FM_BDXDE_SLP3_N,
+ FM_PWR_LED_N,
+ PWRGD_PVCCIN,
+ SVR_ID0,
+ SVR_ID1,
+ SVR_ID2,
+ SVR_ID3,
+ BMC_READY_N,
+ RESERVED_29,
+ RESERVED_30,
+ RESERVED_31,
+};
+
+// Bridge IC Spec
+typedef struct _bic_gpio_t {
+ uint32_t pwrgood_cpu:1;
+ uint32_t pwrgd_pch_pwrok:1;
+ uint32_t pvddr_vrhot_n:1;
+ uint32_t pvccin_vrhot_n:1;
+ uint32_t fm_fast_prochot_n:1;
+ uint32_t pchhot_cpu_n:1;
+ uint32_t fm_cpld_cpu_dimm_event_c0_n:1;
+ uint32_t fm_cpld_bdxde_thermtrip_n:1;
+ uint32_t thermtrip_pch_n:1;
+ uint32_t fm_cpld_fivr_fault:1;
+ uint32_t fm_bdxde_caterr_lvt3_n:1;
+ uint32_t fm_bdxde_err_lvt3_n:3;
+ uint32_t slp_s4_n:1;
+ uint32_t fm_nmi_event_bmc_n:1;
+ uint32_t fm_smi_bmc_n:1;
+ uint32_t rst_pltrst_bmc_n:1;
+ uint32_t fp_rst_btn_buf_n:1;
+ uint32_t bmc_rst_btn_out_n:1;
+ uint32_t fm_bde_post_cmplt_n:1;
+ uint32_t fm_bdxde_slp3_n:1;
+ uint32_t fm_pwr_led_n:1;
+ uint32_t pwrgd_pvccin:1;
+ uint32_t svr_id:4;
+ uint32_t bmc_ready_n:1;
+ uint32_t bmc_com_sw_n:1;
+ uint32_t rsvd:2;
+} bic_gpio_t;
+
+typedef union _bic_gpio_u {
+ uint8_t gpio[4];
+ bic_gpio_t bits;
+} bic_gpio_u;
+
+typedef struct _bic_gpio_config_t {
+ uint8_t dir:1;
+ uint8_t ie:1;
+ uint8_t edge:1;
+ uint8_t trig:2;
+} bic_gpio_config_t;
+
+typedef union _bic_gpio_config_u {
+ uint8_t config;
+ bic_gpio_config_t bits;
+} bic_gpio_config_u;
+
+typedef struct _bic_config_t {
+ uint8_t sol:1;
+ uint8_t post:1;
+ uint8_t kcs:1;
+ uint8_t ipmb:1;
+ uint8_t rsvd:4;
+} bic_config_t;
+
+typedef union _bic_config_u {
+ uint8_t config;
+ bic_config_t bits;
+} bic_config_u;
+
+int bic_get_dev_id(uint8_t slot_id, ipmi_dev_id_t *id);
+
+int bic_get_bic_config(uint8_t slot_id, bic_config_t *cfg);
+int bic_set_bic_config(uint8_t slot_id, bic_config_t *cfg);
+
+int bic_get_gpio(uint8_t slot_id, bic_gpio_t *gpio);
+int bic_get_gpio_config(uint8_t slot_id, uint8_t gpio, bic_gpio_config_t *gpio_config);
+int bic_set_gpio_config(uint8_t slot_id, uint8_t gpio, bic_gpio_config_t *gpio_config);
+int bic_get_post_buf(uint8_t slot_id, uint8_t *buf, uint8_t *len);
+
+int bic_get_fruid_info(uint8_t slot_id, uint8_t fru_id, ipmi_fruid_info_t *info);
+int bic_read_fruid(uint8_t slot_id, uint8_t fru_id, const char *path);
+
+int bic_get_sel_info(uint8_t slot_id, ipmi_sel_sdr_info_t *info);
+int bic_get_sel_rsv(uint8_t slot_id, uint16_t *rsv);
+int bic_get_sel(uint8_t slot_id, ipmi_sel_sdr_req_t *req, ipmi_sel_sdr_res_t *res, uint8_t *rlen);
+
+int bic_get_sdr_info(uint8_t slot_id, ipmi_sel_sdr_info_t *info);
+int bic_get_sdr_rsv(uint8_t slot_id, uint16_t *rsv);
+int bic_get_sdr(uint8_t slot_id, ipmi_sel_sdr_req_t *req, ipmi_sel_sdr_res_t *res, uint8_t *rlen);
+
+int bic_read_sensor(uint8_t slot_id, uint8_t sensor_num, ipmi_sensor_reading_t *sensor);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* __BIC_H__ */
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/Makefile b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/Makefile
new file mode 100644
index 0000000..bab4007
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/Makefile
@@ -0,0 +1,11 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+lib: libpal.so
+
+libpal.so: pal.c
+ $(CC) $(CFLAGS) -fPIC -c -o pal.o pal.c
+ $(CC) -lbic -lyosemite_common -lyosemite_fruid -lyosemite_sensor -shared -o libpal.so pal.o -lc
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o libpal.so
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/pal.c b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/pal.c
new file mode 100644
index 0000000..93a5fbf
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/pal.c
@@ -0,0 +1,1151 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * This file contains code to support IPMI2.0 Specificaton available @
+ * http://www.intel.com/content/www/us/en/servers/ipmi/ipmi-specifications.html
+ *
+ * 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.
+ */
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <syslog.h>
+#include <sys/mman.h>
+#include <string.h>
+#include "pal.h"
+
+#define BIT(value, index) ((value >> index) & 1)
+
+#define YOSEMITE_PLATFORM_NAME "Yosemite"
+#define LAST_KEY "last_key"
+#define YOSEMITE_MAX_NUM_SLOTS 4
+#define GPIO_VAL "/sys/class/gpio/gpio%d/value"
+#define GPIO_DIR "/sys/class/gpio/gpio%d/direction"
+
+#define GPIO_HAND_SW_ID1 138
+#define GPIO_HAND_SW_ID2 139
+#define GPIO_HAND_SW_ID4 140
+#define GPIO_HAND_SW_ID8 141
+
+#define GPIO_RST_BTN 144
+#define GPIO_PWR_BTN 24
+
+#define GPIO_USB_SW0 36
+#define GPIO_USB_SW1 37
+
+#define GPIO_UART_SEL0 32
+#define GPIO_UART_SEL1 33
+#define GPIO_UART_SEL2 34
+#define GPIO_UART_RX 35
+
+#define GPIO_POSTCODE_0 48
+#define GPIO_POSTCODE_1 49
+#define GPIO_POSTCODE_2 50
+#define GPIO_POSTCODE_3 51
+#define GPIO_POSTCODE_4 124
+#define GPIO_POSTCODE_5 125
+#define GPIO_POSTCODE_6 126
+#define GPIO_POSTCODE_7 127
+
+#define GPIO_DBG_CARD_PRSNT 137
+
+#define PAGE_SIZE 0x1000
+#define AST_SCU_BASE 0x1e6e2000
+#define PIN_CTRL1_OFFSET 0x80
+#define PIN_CTRL2_OFFSET 0x84
+
+#define UART1_TXD (1 << 22)
+#define UART2_TXD (1 << 30)
+#define UART3_TXD (1 << 22)
+#define UART4_TXD (1 << 30)
+
+#define BIT(v, i) ((v >> i) & 1)
+#define DELAY_GRACEFUL_SHUTDOWN 1
+#define DELAY_POWER_OFF 5
+
+static uint8_t gpio_rst_btn[5] = { 0, 57, 56, 59, 58 };
+static uint8_t gpio_led[5] = { 0, 97, 96, 99, 98 };
+static uint8_t gpio_prsnt[5] = { 0, 61, 60, 63, 62 };
+static uint8_t gpio_power[5] = { 0, 27, 25, 31, 29 };
+const char pal_fru_list[] = "all, slot1, slot2, slot3, slot4, spb, nic";
+const char pal_server_list[] = "slot1, slot2, slot3, slot4";
+
+char * key_list[] = {
+"pwr_server1_last_state",
+"pwr_server2_last_state",
+"pwr_server3_last_state",
+"pwr_server4_last_state",
+"slot1_por_cfg",
+"slot2_por_cfg",
+"slot3_por_cfg",
+"slot4_por_cfg",
+/* Add more Keys here */
+LAST_KEY /* This is the last key of the list */
+};
+
+// Helper Functions
+static int
+read_device(const char *device, int *value) {
+ FILE *fp;
+ int rc;
+
+ fp = fopen(device, "r");
+ if (!fp) {
+ int err = errno;
+
+ syslog(LOG_INFO, "failed to open device %s", device);
+ return err;
+ }
+
+ rc = fscanf(fp, "%d", value);
+ fclose(fp);
+ if (rc != 1) {
+ syslog(LOG_INFO, "failed to read device %s", device);
+ return ENOENT;
+ } else {
+ return 0;
+ }
+}
+
+static int
+write_device(const char *device, const char *value) {
+ FILE *fp;
+ int rc;
+
+ fp = fopen(device, "w");
+ if (!fp) {
+ int err = errno;
+
+ syslog(LOG_INFO, "failed to open device for write %s", device);
+ return err;
+ }
+
+ rc = fputs(value, fp);
+ fclose(fp);
+
+ if (rc < 0) {
+ syslog(LOG_INFO, "failed to write device %s", device);
+ return ENOENT;
+ } else {
+ return 0;
+ }
+}
+
+// Power On the server in a given slot
+static int
+server_power_on(uint8_t slot_id) {
+ char vpath[64] = {0};
+
+ sprintf(vpath, GPIO_VAL, gpio_power[slot_id]);
+
+ if (write_device(vpath, "1")) {
+ return -1;
+ }
+
+ if (write_device(vpath, "0")) {
+ return -1;
+ }
+
+ sleep(1);
+
+ if (write_device(vpath, "1")) {
+ return -1;
+ }
+
+ return 0;
+}
+
+// Power Off the server in given slot
+static int
+server_power_off(uint8_t slot_id, bool gs_flag) {
+ char vpath[64] = {0};
+
+ if (slot_id < 1 || slot_id > 4) {
+ return -1;
+ }
+
+ sprintf(vpath, GPIO_VAL, gpio_power[slot_id]);
+
+ if (write_device(vpath, "1")) {
+ return -1;
+ }
+
+ sleep(1);
+
+ if (write_device(vpath, "0")) {
+ return -1;
+ }
+
+ if (gs_flag) {
+ sleep(DELAY_GRACEFUL_SHUTDOWN);
+ } else {
+ sleep(DELAY_POWER_OFF);
+ }
+
+ if (write_device(vpath, "1")) {
+ return -1;
+ }
+
+ return 0;
+}
+
+// Debug Card's UART and BMC/SoL port share UART port and need to enable only
+// one TXD i.e. either BMC's TXD or Debug Port's TXD.
+static int
+control_sol_txd(uint8_t slot) {
+ uint32_t scu_fd;
+ uint32_t ctrl;
+ void *scu_reg;
+ void *scu_pin_ctrl1;
+ void *scu_pin_ctrl2;
+
+ scu_fd = open("/dev/mem", O_RDWR | O_SYNC );
+ if (scu_fd < 0) {
+ syslog(LOG_ALERT, "control_sol_txd: open fails\n");
+ return -1;
+ }
+
+ scu_reg = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, scu_fd,
+ AST_SCU_BASE);
+ scu_pin_ctrl1 = (char*)scu_reg + PIN_CTRL1_OFFSET;
+ scu_pin_ctrl2 = (char*)scu_reg + PIN_CTRL2_OFFSET;
+
+ switch(slot) {
+ case 1:
+ // Disable UART2's TXD and enable others
+ ctrl = *(volatile uint32_t*) scu_pin_ctrl2;
+ ctrl |= UART1_TXD;
+ ctrl &= (~UART2_TXD); //Disable
+ *(volatile uint32_t*) scu_pin_ctrl2 = ctrl;
+
+ ctrl = *(volatile uint32_t*) scu_pin_ctrl1;
+ ctrl |= UART3_TXD | UART4_TXD;
+ *(volatile uint32_t*) scu_pin_ctrl1 = ctrl;
+ break;
+ case 2:
+ // Disable UART1's TXD and enable others
+ ctrl = *(volatile uint32_t*) scu_pin_ctrl2;
+ ctrl &= (~UART1_TXD); // Disable
+ ctrl |= UART2_TXD;
+ *(volatile uint32_t*) scu_pin_ctrl2 = ctrl;
+
+ ctrl = *(volatile uint32_t*) scu_pin_ctrl1;
+ ctrl |= UART3_TXD | UART4_TXD;
+ *(volatile uint32_t*) scu_pin_ctrl1 = ctrl;
+ break;
+ case 3:
+ // Disable UART4's TXD and enable others
+ ctrl = *(volatile uint32_t*) scu_pin_ctrl2;
+ ctrl |= UART1_TXD | UART2_TXD;
+ *(volatile uint32_t*) scu_pin_ctrl2 = ctrl;
+
+ ctrl = *(volatile uint32_t*) scu_pin_ctrl1;
+ ctrl |= UART3_TXD;
+ ctrl &= (~UART4_TXD); // Disable
+ *(volatile uint32_t*) scu_pin_ctrl1 = ctrl;
+ break;
+ case 4:
+ // Disable UART3's TXD and enable others
+ ctrl = *(volatile uint32_t*) scu_pin_ctrl2;
+ ctrl |= UART1_TXD | UART2_TXD;
+ *(volatile uint32_t*) scu_pin_ctrl2 = ctrl;
+
+ ctrl = *(volatile uint32_t*) scu_pin_ctrl1;
+ ctrl &= (~UART3_TXD); // Disable
+ ctrl |= UART4_TXD;
+ *(volatile uint32_t*) scu_pin_ctrl1 = ctrl;
+ break;
+ default:
+ // Any other slots we need to enable all TXDs
+ ctrl = *(volatile uint32_t*) scu_pin_ctrl2;
+ ctrl |= UART1_TXD | UART2_TXD;
+ *(volatile uint32_t*) scu_pin_ctrl2 = ctrl;
+
+ ctrl = *(volatile uint32_t*) scu_pin_ctrl1;
+ ctrl |= UART3_TXD | UART4_TXD;
+ *(volatile uint32_t*) scu_pin_ctrl1 = ctrl;
+ break;
+ }
+
+ munmap(scu_reg, PAGE_SIZE);
+ close(scu_fd);
+
+ return 0;
+}
+
+// Display the given POST code using GPIO port
+static int
+pal_post_display(uint8_t status) {
+ char path[64] = {0};
+ int ret;
+ char *val;
+
+ syslog(LOG_ALERT, "pal_post_display: status is %d\n", status);
+
+ sprintf(path, GPIO_VAL, GPIO_POSTCODE_0);
+
+ if (BIT(status, 0)) {
+ val = "1";
+ } else {
+ val = "0";
+ }
+
+ ret = write_device(path, val);
+ if (ret) {
+ goto post_exit;
+ }
+
+ sprintf(path, GPIO_VAL, GPIO_POSTCODE_1);
+ if (BIT(status, 1)) {
+ val = "1";
+ } else {
+ val = "0";
+ }
+
+ ret = write_device(path, val);
+ if (ret) {
+ goto post_exit;
+ }
+
+ sprintf(path, GPIO_VAL, GPIO_POSTCODE_2);
+ if (BIT(status, 2)) {
+ val = "1";
+ } else {
+ val = "0";
+ }
+
+ ret = write_device(path, val);
+ if (ret) {
+ goto post_exit;
+ }
+
+ sprintf(path, GPIO_VAL, GPIO_POSTCODE_3);
+ if (BIT(status, 3)) {
+ val = "1";
+ } else {
+ val = "0";
+ }
+
+ ret = write_device(path, val);
+ if (ret) {
+ goto post_exit;
+ }
+
+ sprintf(path, GPIO_VAL, GPIO_POSTCODE_4);
+ if (BIT(status, 4)) {
+ val = "1";
+ } else {
+ val = "0";
+ }
+
+ ret = write_device(path, val);
+ if (ret) {
+ goto post_exit;
+ }
+
+ sprintf(path, GPIO_VAL, GPIO_POSTCODE_5);
+ if (BIT(status, 5)) {
+ val = "1";
+ } else {
+ val = "0";
+ }
+
+ ret = write_device(path, val);
+ if (ret) {
+ goto post_exit;
+ }
+
+ sprintf(path, GPIO_VAL, GPIO_POSTCODE_6);
+ if (BIT(status, 6)) {
+ val = "1";
+ } else {
+ val = "0";
+ }
+
+ ret = write_device(path, val);
+ if (ret) {
+ goto post_exit;
+ }
+
+ sprintf(path, GPIO_VAL, GPIO_POSTCODE_7);
+ if (BIT(status, 7)) {
+ val = "1";
+ } else {
+ val = "0";
+ }
+
+ ret = write_device(path, val);
+ if (ret) {
+ goto post_exit;
+ }
+
+post_exit:
+ if (ret) {
+ syslog(LOG_ALERT, "write_device failed for %s\n", path);
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+// Platform Abstraction Layer (PAL) Functions
+int
+pal_get_platform_name(char *name) {
+ strcpy(name, YOSEMITE_PLATFORM_NAME);
+
+ return 0;
+}
+
+int
+pal_get_num_slots(uint8_t *num) {
+ *num = YOSEMITE_MAX_NUM_SLOTS;
+
+ return 0;
+}
+
+int
+pal_is_server_prsnt(uint8_t slot_id, uint8_t *status) {
+ int val;
+ char path[64] = {0};
+
+ if (slot_id < 1 || slot_id > 4) {
+ return -1;
+ }
+
+ sprintf(path, GPIO_VAL, gpio_prsnt[slot_id]);
+
+ if (read_device(path, &val)) {
+ return -1;
+ }
+
+ if (val == 0x0) {
+ *status = 1;
+ } else {
+ *status = 0;
+ }
+
+ return 0;
+}
+
+int
+pal_is_debug_card_prsnt(uint8_t *status) {
+ int val;
+ char path[64] = {0};
+
+ sprintf(path, GPIO_VAL, GPIO_DBG_CARD_PRSNT);
+
+ if (read_device(path, &val)) {
+ return -1;
+ }
+
+ // TODO: Logic is reversed until DVT board with h/w fix
+ if (val == 0x0) {
+ *status = 0;
+ } else {
+ *status = 1;
+ }
+
+ return 0;
+}
+
+int
+pal_get_server_power(uint8_t slot_id, uint8_t *status) {
+ int ret;
+ bic_gpio_t gpio;
+
+ ret = bic_get_gpio(slot_id, &gpio);
+ if (ret) {
+ return ret;
+ }
+
+ if (gpio.pwrgood_cpu) {
+ *status = SERVER_POWER_ON;
+ } else {
+ *status = SERVER_POWER_OFF;
+ }
+
+ return 0;
+}
+
+// Power Off, Power On, or Power Reset the server in given slot
+int
+pal_set_server_power(uint8_t slot_id, uint8_t cmd) {
+ uint8_t status;
+ bool gs_flag = false;
+
+ if (slot_id < 1 || slot_id > 4) {
+ return -1;
+ }
+
+ if (pal_get_server_power(slot_id, &status) < 0) {
+ return -1;
+ }
+
+ switch(cmd) {
+ case SERVER_POWER_ON:
+ if (status == SERVER_POWER_ON)
+ return 1;
+ else
+ return server_power_on(slot_id);
+ break;
+
+ case SERVER_POWER_OFF:
+ if (status == SERVER_POWER_OFF)
+ return 1;
+ else
+ return server_power_off(slot_id, gs_flag);
+ break;
+
+ case SERVER_POWER_CYCLE:
+ if (status == SERVER_POWER_ON)
+ return (server_power_off(slot_id, gs_flag) || server_power_on(slot_id));
+ else if (status == SERVER_POWER_OFF)
+ return (server_power_on(slot_id));
+ break;
+
+ case SERVER_GRACEFUL_SHUTDOWN:
+ if (status == SERVER_POWER_OFF)
+ return 1;
+ else
+ gs_flag = true;
+ return server_power_off(slot_id, gs_flag);
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+pal_sled_cycle(void) {
+ // Remove the adm1275 module as the HSC device is busy
+ system("rmmod adm1275");
+
+ // Send command to HSC power cycle
+ system("i2cset -y 10 0x40 0xd9 c");
+
+ return 0;
+}
+
+// Read the Front Panel Hand Switch and return the position
+int
+pal_get_hand_sw(uint8_t *pos) {
+ char path[64] = {0};
+ int id1, id2, id4, id8;
+ uint8_t loc;
+ // Read 4 GPIOs to read the current position
+ // id1: GPIOR2(138)
+ // id2: GPIOR3(139)
+ // id4: GPIOR4(140)
+ // id8: GPIOR5(141)
+
+ // Read ID1
+ sprintf(path, GPIO_VAL, GPIO_HAND_SW_ID1);
+ if (read_device(path, &id1)) {
+ return -1;
+ }
+
+ // Read ID2
+ sprintf(path, GPIO_VAL, GPIO_HAND_SW_ID2);
+ if (read_device(path, &id2)) {
+ return -1;
+ }
+
+ // Read ID4
+ sprintf(path, GPIO_VAL, GPIO_HAND_SW_ID4);
+ if (read_device(path, &id4)) {
+ return -1;
+ }
+
+ // Read ID8
+ sprintf(path, GPIO_VAL, GPIO_HAND_SW_ID8);
+ if (read_device(path, &id8)) {
+ return -1;
+ }
+
+ loc = ((id8 << 3) | (id4 << 2) | (id2 << 1) | (id1));
+
+ switch(loc) {
+ case 1:
+ case 6:
+ *pos = HAND_SW_SERVER1;
+ break;
+ case 2:
+ case 7:
+ *pos = HAND_SW_SERVER2;
+ break;
+ case 3:
+ case 8:
+ *pos = HAND_SW_SERVER3;
+ break;
+ case 4:
+ case 9:
+ *pos = HAND_SW_SERVER4;
+ break;
+ default:
+ *pos = HAND_SW_BMC;
+ break;
+ }
+
+ return 0;
+}
+
+// Return the Front panel Power Button
+int
+pal_get_pwr_btn(uint8_t *status) {
+ char path[64] = {0};
+ int val;
+
+ sprintf(path, GPIO_VAL, GPIO_PWR_BTN);
+ if (read_device(path, &val)) {
+ return -1;
+ }
+
+ if (val) {
+ *status = 0x0;
+ } else {
+ *status = 0x1;
+ }
+
+ return 0;
+}
+
+// Return the front panel's Reset Button status
+int
+pal_get_rst_btn(uint8_t *status) {
+ char path[64] = {0};
+ int val;
+
+ sprintf(path, GPIO_VAL, GPIO_RST_BTN);
+ if (read_device(path, &val)) {
+ return -1;
+ }
+
+ if (val) {
+ *status = 0x0;
+ } else {
+ *status = 0x1;
+ }
+
+ return 0;
+}
+
+// Update the Reset button input to the server at given slot
+int
+pal_set_rst_btn(uint8_t slot, uint8_t status) {
+ char path[64] = {0};
+ char *val;
+
+ if (slot < 1 || slot > 4) {
+ return -1;
+ }
+
+ if (status) {
+ val = "0";
+ } else {
+ val = "1";
+ }
+
+ sprintf(path, GPIO_VAL, gpio_rst_btn[slot]);
+ if (write_device(path, val)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+// Update the LED for the given slot with the status
+int
+pal_set_led(uint8_t slot, uint8_t status) {
+ char path[64] = {0};
+ char *val;
+
+ if (slot < 1 || slot > 4) {
+ return -1;
+ }
+
+ if (status) {
+ val = "1";
+ } else {
+ val = "0";
+ }
+
+ sprintf(path, GPIO_VAL, gpio_led[slot]);
+ if (write_device(path, val)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+// Update the USB Mux to the server at given slot
+int
+pal_switch_usb_mux(uint8_t slot) {
+ char *gpio_sw0, *gpio_sw1;
+ char path[64] = {0};
+
+ // Based on the USB mux table in Schematics
+ switch(slot) {
+ case 1:
+ gpio_sw0 = "1";
+ gpio_sw1 = "0";
+ break;
+ case 2:
+ gpio_sw0 = "0";
+ gpio_sw1 = "0";
+ break;
+ case 3:
+ gpio_sw0 = "1";
+ gpio_sw1 = "1";
+ break;
+ case 4:
+ gpio_sw0 = "0";
+ gpio_sw1 = "1";
+ break;
+ default:
+ // Default is for BMC itself
+ return 0;
+ }
+
+ sprintf(path, GPIO_VAL, GPIO_USB_SW0);
+ if (write_device(path, gpio_sw0) < 0) {
+ syslog(LOG_ALERT, "write_device failed for %s\n", path);
+ return -1;
+ }
+
+ sprintf(path, GPIO_VAL, GPIO_USB_SW1);
+ if (write_device(path, gpio_sw1) < 0) {
+ syslog(LOG_ALERT, "write_device failed for %s\n", path);
+ return -1;
+ }
+
+ return 0;
+}
+
+// Switch the UART mux to the given slot
+int
+pal_switch_uart_mux(uint8_t slot) {
+ char * gpio_uart_sel0;
+ char * gpio_uart_sel1;
+ char * gpio_uart_sel2;
+ char * gpio_uart_rx;
+ char path[64] = {0};
+ int ret;
+
+ // Refer the UART select table in schematic
+ switch(slot) {
+ case 1:
+ gpio_uart_sel2 = "0";
+ gpio_uart_sel1 = "0";
+ gpio_uart_sel0 = "1";
+ gpio_uart_rx = "0";
+ break;
+ case 2:
+ gpio_uart_sel2 = "0";
+ gpio_uart_sel1 = "0";
+ gpio_uart_sel0 = "0";
+ gpio_uart_rx = "0";
+ break;
+ case 3:
+ gpio_uart_sel2 = "0";
+ gpio_uart_sel1 = "1";
+ gpio_uart_sel0 = "1";
+ gpio_uart_rx = "0";
+ break;
+ case 4:
+ gpio_uart_sel2 = "0";
+ gpio_uart_sel1 = "1";
+ gpio_uart_sel0 = "0";
+ gpio_uart_rx = "0";
+ break;
+ default:
+ // for all other cases, assume BMC
+ gpio_uart_sel2 = "1";
+ gpio_uart_sel1 = "0";
+ gpio_uart_sel0 = "0";
+ gpio_uart_rx = "1";
+ break;
+ }
+
+ // Diable TXD path from BMC to avoid conflict with SoL
+ ret = control_sol_txd(slot);
+ if (ret) {
+ goto uart_exit;
+ }
+
+ // Enable Debug card path
+ sprintf(path, GPIO_VAL, GPIO_UART_SEL2);
+ ret = write_device(path, gpio_uart_sel2);
+ if (ret) {
+ goto uart_exit;
+ }
+
+ sprintf(path, GPIO_VAL, GPIO_UART_SEL1);
+ ret = write_device(path, gpio_uart_sel1);
+ if (ret) {
+ goto uart_exit;
+ }
+
+ sprintf(path, GPIO_VAL, GPIO_UART_SEL0);
+ ret = write_device(path, gpio_uart_sel0);
+ if (ret) {
+ goto uart_exit;
+ }
+
+ sprintf(path, GPIO_VAL, GPIO_UART_RX);
+ ret = write_device(path, gpio_uart_rx);
+ if (ret) {
+ goto uart_exit;
+ }
+
+uart_exit:
+ if (ret) {
+ syslog(LOG_ALERT, "pal_switch_uart_mux: write_device failed: %s\n", path);
+ return ret;
+ } else {
+ return 0;
+ }
+}
+
+// Enable POST buffer for the server in given slot
+int
+pal_post_enable(uint8_t slot) {
+ int ret;
+ int i;
+ bic_config_t config = {0};
+ bic_config_u *t = (bic_config_u *) &config;
+
+ ret = bic_get_config(slot, &config);
+ if (ret) {
+ syslog(LOG_ALERT, "post_enable: bic_get_config failed\n");
+ return ret;
+ }
+
+ t->bits.post = 1;
+
+ ret = bic_set_config(slot, &config);
+ if (ret) {
+ syslog(LOG_ALERT, "post_enable: bic_set_config failed\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+// Disable POST buffer for the server in given slot
+int
+pal_post_disable(uint8_t slot) {
+ int ret;
+ int i;
+ bic_config_t config = {0};
+ bic_config_u *t = (bic_config_u *) &config;
+
+ ret = bic_get_config(slot, &config);
+ if (ret) {
+ return ret;
+ }
+
+ t->bits.post = 0;
+
+ ret = bic_set_config(slot, &config);
+ if (ret) {
+ return ret;
+ }
+
+ return 0;
+}
+
+// Get the last post code of the given slot
+int
+pal_post_get_last(uint8_t slot, uint8_t *status) {
+ int ret;
+ uint8_t buf[MAX_IPMB_RES_LEN] = {0x0};
+ uint8_t len;
+ int i;
+
+ ret = bic_get_post_buf(slot, buf, &len);
+ if (ret) {
+ return ret;
+ }
+
+ // The post buffer is LIFO and the first byte gives the latest post code
+ *status = buf[0];
+
+ return 0;
+}
+
+// Handle the received post code, for now display it on debug card
+int
+pal_post_handle(uint8_t slot, uint8_t status) {
+ uint8_t prsnt, pos;
+ int ret;
+
+ // Check for debug card presence
+ ret = pal_is_debug_card_prsnt(&prsnt);
+ if (ret) {
+ return ret;
+ }
+
+ // No debug card present, return
+ if (!prsnt) {
+ return 0;
+ }
+
+ // Get the hand switch position
+ ret = pal_get_hand_sw(&pos);
+ if (ret) {
+ return ret;
+ }
+
+ // If the give server is not selected, return
+ if (pos != slot) {
+ return 0;
+ }
+
+ // Display the post code in the debug card
+ ret = pal_post_display(status);
+ if (ret) {
+ return ret;
+ }
+
+ return 0;
+}
+
+
+static int
+read_kv(char *key, char *value) {
+
+ FILE *fp;
+ int rc;
+
+ fp = fopen(key, "r");
+ if (!fp) {
+ int err = errno;
+ syslog(LOG_ALERT, "read_kv: failed to open %s", key);
+ return err;
+ }
+
+ rc = (int) fread(value, 1, MAX_VALUE_LEN, fp);
+ fclose(fp);
+ if (rc <= 0) {
+ syslog(LOG_INFO, "read_kv: failed to read %s", key);
+ return ENOENT;
+ } else {
+ return 0;
+ }
+}
+
+static int
+write_kv(char *key, char *value) {
+
+ FILE *fp;
+ int rc;
+
+ fp = fopen(key, "w");
+ if (!fp) {
+ int err = errno;
+ syslog(LOG_ALERT, "write_kv: failed to open %s", key);
+ return err;
+ }
+
+ rc = fwrite(value, 1, strlen(value), fp);
+ fclose(fp);
+
+ if (rc < 0) {
+ syslog(LOG_ALERT, "write_kv: failed to write to %s", key);
+ return ENOENT;
+ } else {
+ return 0;
+ }
+}
+
+int
+pal_get_fru_id(char *str, uint8_t *fru) {
+
+ return yosemite_common_fru_id(str, fru);
+}
+
+int
+pal_get_fru_sensor_list(uint8_t fru, uint8_t **sensor_list, int *cnt) {
+
+ switch(fru) {
+ case FRU_SLOT1:
+ case FRU_SLOT2:
+ case FRU_SLOT3:
+ case FRU_SLOT4:
+ *sensor_list = (uint8_t *) bic_sensor_list;
+ *cnt = bic_sensor_cnt;
+ break;
+ case FRU_SPB:
+ *sensor_list = (uint8_t *) spb_sensor_list;
+ *cnt = spb_sensor_cnt;
+ break;
+ case FRU_NIC:
+ *sensor_list = NULL; // (uint8_t *) nic_sensor_list;
+ *cnt = 0; //nic_sensor_cnt;
+ break;
+ default:
+ syslog(LOG_ALERT, "pal_get_fru_sensor_list: Wrong fru id %u", fru);
+ return -1;
+ }
+ return 0;
+}
+
+int
+pal_sensor_read(uint8_t fru, uint8_t sensor_num, void *value) {
+ return yosemite_sensor_read(fru, sensor_num, value);
+}
+
+int
+pal_get_sensor_name(uint8_t fru, uint8_t sensor_num, char *name) {
+ return yosemite_sensor_name(fru, sensor_num, name);
+}
+
+int
+pal_get_sensor_units(uint8_t fru, uint8_t sensor_num, char *units) {
+ return yosemite_sensor_units(fru, sensor_num, units);
+}
+
+int
+pal_get_fruid_path(uint8_t fru, char *path) {
+ return yosemite_get_fruid_path(fru, path);
+}
+
+int
+pal_get_fruid_name(uint8_t fru, char *name) {
+ return yosemite_get_fruid_name(fru, name);
+}
+
+
+static int
+get_key_value(char* key, char *value) {
+
+ char kpath[64] = {0};
+
+ sprintf(kpath, KV_STORE, key);
+
+ if (access(KV_STORE_PATH, F_OK) == -1) {
+ mkdir(KV_STORE_PATH, 0777);
+ }
+
+ return read_kv(kpath, value);
+}
+
+static int
+set_key_value(char *key, char *value) {
+
+ char kpath[64] = {0};
+
+ sprintf(kpath, KV_STORE, key);
+
+ if (access(KV_STORE_PATH, F_OK) == -1) {
+ mkdir(KV_STORE_PATH, 0777);
+ }
+
+ return write_kv(kpath, value);
+}
+
+int
+pal_get_key_value(char *key, char *value) {
+
+ int ret;
+ int i;
+
+ i = 0;
+ while(strcmp(key_list[i], LAST_KEY)) {
+
+ if (!strcmp(key, key_list[i])) {
+ // Key is valid
+ if ((ret = get_key_value(key, value)) < 0 ) {
+ syslog(LOG_ALERT, "pal_get_key_value: get_key_value failed. %d", ret);
+ return ret;
+ }
+ return ret;
+ }
+ i++;
+ }
+
+ return -1;
+}
+
+int
+pal_set_key_value(char *key, char *value) {
+
+ int ret;
+ int i;
+
+ i = 0;
+ while(strcmp(key_list[i], LAST_KEY)) {
+
+ if (!strcmp(key, key_list[i])) {
+ // Key is valid
+ if ((ret = set_key_value(key, value)) < 0) {
+ syslog(LOG_ALERT, "pal_set_key_value: set_key_value failed. %d", ret);
+ printf("pal_set_key_value: ret = %d\n", ret);
+ return ret;
+ }
+ return ret;
+ }
+ i++;
+ }
+
+ return -1;
+}
+
+int
+pal_get_fru_devtty(uint8_t fru, char *devtty) {
+
+ switch(fru) {
+ case FRU_SLOT1:
+ sprintf(devtty, "/dev/ttyS2");
+ break;
+ case FRU_SLOT2:
+ sprintf(devtty, "/dev/ttyS1");
+ break;
+ case FRU_SLOT3:
+ sprintf(devtty, "/dev/ttyS4");
+ break;
+ case FRU_SLOT4:
+ sprintf(devtty, "/dev/ttyS3");
+ break;
+ default:
+ syslog(LOG_ALERT, "pal_get_fru_devtty: Wrong fru id %u", fru);
+ return -1;
+ }
+ return 0;
+}
+
+void
+pal_dump_key_value(void) {
+ int i;
+ int ret;
+
+ char value[MAX_VALUE_LEN] = {0x0};
+
+ while (strcmp(key_list[i], LAST_KEY)) {
+ printf("%s:", key_list[i]);
+ if (ret = get_key_value(key_list[i], value) < 0) {
+ printf("\n");
+ } else {
+ printf("%s\n", value);
+ }
+ i++;
+ memset(value, 0, MAX_VALUE_LEN);
+ }
+}
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/pal.h b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/pal.h
new file mode 100644
index 0000000..1d9f3b9
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/pal/pal.h
@@ -0,0 +1,98 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ *
+ * 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.
+ */
+
+#ifndef __PAL_H__
+#define __PAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <facebook/bic.h>
+#include <facebook/yosemite_common.h>
+#include <facebook/yosemite_fruid.h>
+#include <facebook/yosemite_sensor.h>
+
+#define MAX_NUM_FRUS 6
+#define MAX_KEY_LEN 64
+#define MAX_VALUE_LEN 64
+
+#define KV_STORE "/mnt/data/kv_store/%s"
+#define KV_STORE_PATH "/mnt/data/kv_store"
+
+extern char * key_list[];
+extern const char pal_fru_list[];
+extern const char pal_server_list[];
+
+enum {
+ LED_STATE_OFF,
+ LED_STATE_ON,
+};
+
+enum {
+ SERVER_POWER_OFF,
+ SERVER_POWER_ON,
+ SERVER_POWER_CYCLE,
+ SERVER_GRACEFUL_SHUTDOWN,
+};
+
+enum {
+ HAND_SW_SERVER1 = 1,
+ HAND_SW_SERVER2,
+ HAND_SW_SERVER3,
+ HAND_SW_SERVER4,
+ HAND_SW_BMC
+};
+
+int pal_get_platform_name(char *name);
+int pal_get_num_slots(uint8_t *num);
+int pal_is_server_prsnt(uint8_t slot_id, uint8_t *status);
+int pal_get_server_power(uint8_t slot_id, uint8_t *status);
+int pal_set_server_power(uint8_t slot_id, uint8_t cmd);
+int pal_sled_cycle(void);
+int pal_is_debug_card_prsnt(uint8_t *status);
+int pal_get_hand_sw(uint8_t *pos);
+int pal_switch_usb_mux(uint8_t slot);
+int pal_switch_uart_mux(uint8_t slot);
+int pal_post_enable(uint8_t slot);
+int pal_post_disable(uint8_t slot);
+int pal_post_get_last(uint8_t slot, uint8_t *post);
+int pal_post_handle(uint8_t slot, uint8_t status);
+int pal_get_pwr_btn(uint8_t *status);
+int pal_get_rst_btn(uint8_t *status);
+int pal_set_rst_btn(uint8_t slot, uint8_t status);
+int pal_set_led(uint8_t slot, uint8_t status);
+int pal_get_fru_id(char *fru_str, uint8_t *fru);
+int pal_get_fruid_path(uint8_t fru, char *path);
+int pal_get_fruid_name(uint8_t fru, char *name);
+int pal_get_sensor_units(uint8_t fru, uint8_t sensor_num, char *units);
+int pal_get_fru_sensor_list(uint8_t fru, uint8_t **sensor_list, int *cnt);
+int pal_sensor_read(uint8_t fru, uint8_t sensor_num, void *value);
+int pal_get_sensor_name(uint8_t fru, uint8_t sensor_num, char *name);
+int pal_get_key_value(char *key, char *value);
+int pal_set_key_value(char *key, char *value);
+void pal_dump_key_value(void);
+int pal_get_fru_devtty(uint8_t fru, char *devtty);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* __PAL_H__ */
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/Makefile b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/Makefile
new file mode 100644
index 0000000..76bf61f
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/Makefile
@@ -0,0 +1,11 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+lib: libyosemite_common.so
+
+libyosemite_common.so: yosemite_common.c
+ $(CC) $(CFLAGS) -fPIC -c -o yosemite_common.o yosemite_common.c
+ $(CC) -shared -o libyosemite_common.so yosemite_common.o -lc
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o libyosemite_common.so
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/yosemite_common.c b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/yosemite_common.c
new file mode 100644
index 0000000..e41690f
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/yosemite_common.c
@@ -0,0 +1,55 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * This file contains code to support IPMI2.0 Specificaton available @
+ * http://www.intel.com/content/www/us/en/servers/ipmi/ipmi-specifications.html
+ *
+ * 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.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <math.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <syslog.h>
+#include "yosemite_common.h"
+
+int
+yosemite_common_fru_id(char *str, uint8_t *fru) {
+
+ if (!strcmp(str, "all")) {
+ *fru = FRU_ALL;
+ } else if (!strcmp(str, "slot1")) {
+ *fru = FRU_SLOT1;
+ } else if (!strcmp(str, "slot2")) {
+ *fru = FRU_SLOT2;
+ } else if (!strcmp(str, "slot3")) {
+ *fru = FRU_SLOT3;
+ } else if (!strcmp(str, "slot4")) {
+ *fru = FRU_SLOT4;
+ } else if (!strcmp(str, "spb")) {
+ *fru = FRU_SPB;
+ } else if (!strcmp(str, "nic")) {
+ *fru = FRU_NIC;
+ } else {
+ syslog(LOG_ALERT, "yosemite_common_fru_id: Wrong fru id");
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/yosemite_common.h b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/yosemite_common.h
new file mode 100644
index 0000000..85d8638
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_common/yosemite_common.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ *
+ * 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.
+ */
+
+#ifndef __YOSEMITE_COMMON_H__
+#define __YOSEMITE_COMMON_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+ FRU_ALL = 0,
+ FRU_SLOT1 = 1,
+ FRU_SLOT2 = 2,
+ FRU_SLOT3 = 3,
+ FRU_SLOT4 = 4,
+ FRU_SPB = 5,
+ FRU_NIC = 6,
+};
+
+int yosemite_common_fru_id(char *str, uint8_t *fru);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* __YOSEMITE_COMMON_H__ */
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/Makefile b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/Makefile
new file mode 100644
index 0000000..eda01dc
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/Makefile
@@ -0,0 +1,27 @@
+# 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
+
+lib: libyosemite_fruid.so
+
+libyosemite_fruid.so: yosemite_fruid.c
+ $(CC) $(CFLAGS) -fPIC -c -o yosemite_fruid.o yosemite_fruid.c
+ $(CC) -lyosemite_common -shared -o libyosemite_fruid.so yosemite_fruid.o -lc
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o libyosemite_fruid.so
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/yosemite_fruid.c b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/yosemite_fruid.c
new file mode 100644
index 0000000..226f2f8
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/yosemite_fruid.c
@@ -0,0 +1,86 @@
+/* Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * This file contains code to support IPMI2.0 Specificaton available @
+ * http://www.intel.com/content/www/us/en/servers/ipmi/ipmi-specifications.html
+ *
+ * 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.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <syslog.h>
+#include "yosemite_fruid.h"
+
+/* Populate char path[] with the path to the fru's fruid binary dump */
+int
+yosemite_get_fruid_path(uint8_t fru, char *path) {
+ char fname[16] = {0};
+
+ switch(fru) {
+ case FRU_SLOT1:
+ sprintf(fname, "slot1");
+ break;
+ case FRU_SLOT2:
+ sprintf(fname, "slot2");
+ break;
+ case FRU_SLOT3:
+ sprintf(fname, "slot3");
+ break;
+ case FRU_SLOT4:
+ sprintf(fname, "slot4");
+ break;
+ case FRU_SPB:
+ sprintf(fname, "spb");
+ break;
+ case FRU_NIC:
+ sprintf(fname, "nic");
+ break;
+ default:
+ syslog(LOG_ALERT, "yosemite_get_fruid_path: wrong fruid");
+ return -1;
+ }
+
+ sprintf(path, YOSEMITE_FRU_PATH, fname);
+ return 0;
+}
+/* Populate char name[] with the path to the fru's name */
+int
+yosemite_get_fruid_name(uint8_t fru, char *name) {
+
+ switch(fru) {
+ case FRU_SLOT1:
+ sprintf(name, "MonoLake Board 1");
+ break;
+ case FRU_SLOT2:
+ sprintf(name, "MonoLake Board 2");
+ break;
+ case FRU_SLOT3:
+ sprintf(name, "MonoLake Board 3");
+ break;
+ case FRU_SLOT4:
+ sprintf(name, "MonoLake Board 4");
+ break;
+ case FRU_SPB:
+ sprintf(name, "Side Plane Board");
+ break;
+ case FRU_NIC:
+ sprintf(name, "CX4 NIC");
+ break;
+ default:
+ syslog(LOG_ALERT, "yosemite_get_fruid_name: wrong fruid");
+ return -1;
+ }
+ return 0;
+}
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/yosemite_fruid.h b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/yosemite_fruid.h
new file mode 100644
index 0000000..5c01267
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_fruid/yosemite_fruid.h
@@ -0,0 +1,37 @@
+/* Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ *
+ * 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.
+ */
+
+#ifndef __YOSEMITE_FRUID_H__
+#define __YOSEMITE_FRUID_H__
+
+#include <facebook/yosemite_common.h>
+
+#define YOSEMITE_FRU_PATH "/tmp/fruid_%s.bin"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int yosemite_get_fruid_path(uint8_t fru, char *path);
+int yosemite_get_fruid_name(uint8_t fru, char *name);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* __YOSEMITE_FRUID_H__ */
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/Makefile b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/Makefile
new file mode 100644
index 0000000..66c0005
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/Makefile
@@ -0,0 +1,27 @@
+# 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
+
+lib: libyosemite_gpio.so
+
+libyosemite_gpio.so: yosemite_gpio.c
+ $(CC) $(CFLAGS) -fPIC -c -o yosemite_gpio.o yosemite_gpio.c
+ $(CC) -shared -o libyosemite_gpio.so yosemite_gpio.o -lc
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o libyosemite_gpio.so
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/yosemite_gpio.c b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/yosemite_gpio.c
new file mode 100644
index 0000000..ac2c820
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/yosemite_gpio.c
@@ -0,0 +1,116 @@
+/* Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * This file contains code to support IPMI2.0 Specificaton available @
+ * http://www.intel.com/content/www/us/en/servers/ipmi/ipmi-specifications.html
+ *
+ * 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.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <syslog.h>
+#include "yosemite_gpio.h"
+
+// List of GPIO pins to be monitored
+const uint8_t gpio_pin_list[] = {
+ PWRGOOD_CPU,
+ PWRGD_PCH_PWROK,
+ PVDDR_VRHOT_N,
+ PVCCIN_VRHOT_N,
+ FM_FAST_PROCHOT_N,
+ PCHHOT_CPU_N,
+ FM_CPLD_CPU_DIMM_EVENT_CO_N,
+ FM_CPLD_BDXDE_THERMTRIP_N,
+ THERMTRIP_PCH_N,
+ FM_CPLD_FIVR_FAULT,
+ FM_BDXDE_CATERR_LVT3_N,
+ FM_BDXDE_ERR2_LVT3_N,
+ FM_BDXDE_ERR1_LVT3_N,
+ FM_BDXDE_ERR0_LVT3_N,
+ //SLP_S4_N,
+ FM_NMI_EVENT_BMC_N,
+ FM_SMI_BMC_N,
+ RST_PLTRST_BMC_N,
+ FP_RST_BTN_BUF_N,
+ BMC_RST_BTN_OUT_N,
+ FM_BDE_POST_CMPLT_N,
+ //FM_BDXDE_SLP3_N,
+ //FM_PWR_LED_N,
+ PWRGD_PVCCIN,
+ //SVR_ID0,
+ //SVR_ID1,
+ //SVR_ID2,
+ //SVR_ID3,
+ //BMC_READY_N,
+ //RESERVED_29,
+ //RESERVED_30,
+ //RESERVED_31,
+};
+
+size_t gpio_pin_cnt = sizeof(gpio_pin_list)/sizeof(uint8_t);
+const uint32_t gpio_ass_val = 0x0 | (1 << FM_CPLD_FIVR_FAULT);
+
+const char *gpio_pin_name[] = {
+ "PWRGOOD_CPU",
+ "PWRGD_PCH_PWROK",
+ "PVDDR_VRHOT_N",
+ "PVCCIN_VRHOT_N",
+ "FM_FAST_PROCHOT_N",
+ "PCHHOT_CPU_N",
+ "FM_CPLD_CPU_DIMM_EVENT_CO_N",
+ "FM_CPLD_BDXDE_THERMTRIP_N",
+ "THERMTRIP_PCH_N",
+ "FM_CPLD_FIVR_FAULT",
+ "FM_BDXDE_CATERR_LVT3_N",
+ "FM_BDXDE_ERR2_LVT3_N",
+ "FM_BDXDE_ERR1_LVT3_N",
+ "FM_BDXDE_ERR0_LVT3_N",
+ "SLP_S4_N",
+ "FM_NMI_EVENT_BMC_N",
+ "FM_SMI_BMC_N",
+ "RST_PLTRST_BMC_N",
+ "FP_RST_BTN_BUF_N",
+ "BMC_RST_BTN_OUT_N",
+ "FM_BDE_POST_CMPLT_N",
+ "FM_BDXDE_SLP3_N",
+ "FM_PWR_LED_N",
+ "PWRGD_PVCCIN",
+ "SVR_ID0",
+ "SVR_ID1",
+ "SVR_ID2",
+ "SVR_ID3",
+ "BMC_READY_N",
+ "RESERVED_29",
+ "RESERVED_30",
+ "RESERVED_31"
+};
+
+int
+yosemite_get_gpio_name(uint8_t fru, uint8_t gpio, char *name) {
+
+ //TODO: Add support for BMC GPIO pins
+ if (fru < 1 || fru > 4) {
+ syslog(LOG_ALERT, "yosemite_get_gpio_name: Wrong fru %u", fru);
+ return -1;
+ }
+
+ if (gpio < 0 || gpio > MAX_GPIO_PINS) {
+ syslog(LOG_ALERT, "yosemite_get_gpio_name: Wrong gpio pin %u", gpio);
+ return -1;
+ }
+
+ sprintf(name, "%s", gpio_pin_name[gpio]);
+ return 0;
+}
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/yosemite_gpio.h b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/yosemite_gpio.h
new file mode 100644
index 0000000..77808a8
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_gpio/yosemite_gpio.h
@@ -0,0 +1,39 @@
+/* Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ *
+ * 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.
+ */
+
+#ifndef __YOSEMITE_GPIO_H__
+#define __YOSEMITE_GPIO_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <facebook/bic.h>
+
+extern const uint8_t gpio_pin_list[];
+extern const char *gpio_pin_name[];
+extern const uint32_t gpio_ass_val;
+extern size_t gpio_pin_cnt;
+
+int yosemite_get_gpio_name(uint8_t fru, uint8_t gpio, char *name);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* __YOSEMITE_GPIO_H__ */
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/Makefile b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/Makefile
new file mode 100644
index 0000000..63b334c
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/Makefile
@@ -0,0 +1,11 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+lib: libyosemite_sensor.so
+
+libyosemite_sensor.so: yosemite_sensor.c
+ $(CC) $(CFLAGS) -fPIC -c -o yosemite_sensor.o yosemite_sensor.c
+ $(CC) -lm -lbic -lsdr -lipmi -lipmb -lyosemite_common -shared -o libyosemite_sensor.so yosemite_sensor.o -lc
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o libyosemite_sensor.so
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/yosemite_sensor.c b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/yosemite_sensor.c
new file mode 100644
index 0000000..0f25e54
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/yosemite_sensor.c
@@ -0,0 +1,778 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * This file contains code to support IPMI2.0 Specificaton available @
+ * http://www.intel.com/content/www/us/en/servers/ipmi/ipmi-specifications.html
+ *
+ * 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.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <math.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <syslog.h>
+#include "yosemite_sensor.h"
+
+#define LARGEST_DEVICE_NAME 120
+
+#define GPIO_VAL "/sys/class/gpio/gpio%d/value"
+
+#define I2C_BUS_9_DIR "/sys/class/i2c-adapter/i2c-9/"
+#define I2C_BUS_10_DIR "/sys/class/i2c-adapter/i2c-10/"
+
+#define TACH_DIR "/sys/devices/platform/ast_pwm_tacho.0"
+#define ADC_DIR "/sys/devices/platform/ast_adc.0"
+
+#define SP_INLET_TEMP_DEVICE I2C_BUS_9_DIR "9-004e"
+#define SP_OUTLET_TEMP_DEVICE I2C_BUS_9_DIR "9-004f"
+#define HSC_DEVICE I2C_BUS_10_DIR "10-0040"
+
+#define FAN_TACH_RPM "tacho%d_rpm"
+#define ADC_VALUE "adc%d_value"
+#define HSC_IN_VOLT "in1_input"
+#define HSC_OUT_CURR "curr1_input"
+#define HSC_TEMP "temp1_input"
+
+#define UNIT_DIV 1000
+
+#define BIC_SENSOR_READ_NA 0x20
+
+#define MAX_SENSOR_NUM 0xFF
+#define ALL_BYTES 0xFF
+#define LAST_REC_ID 0xFFFF
+
+#define YOSEMITE_SDR_PATH "/tmp/sdr_%s.bin"
+
+// List of BIC sensors to be monitored
+const uint8_t bic_sensor_list[] = {
+ /* Threshold sensors */
+ BIC_SENSOR_MB_OUTLET_TEMP,
+ BIC_SENSOR_VCCIN_VR_TEMP,
+ BIC_SENSOR_VCC_GBE_VR_TEMP,
+ BIC_SENSOR_1V05PCH_VR_TEMP,
+ BIC_SENSOR_SOC_TEMP,
+ BIC_SENSOR_MB_INLET_TEMP,
+ BIC_SENSOR_PCH_TEMP,
+ BIC_SENSOR_SOC_THERM_MARGIN,
+ BIC_SENSOR_VDDR_VR_TEMP,
+ BIC_SENSOR_VCC_GBE_VR_CURR,
+ BIC_SENSOR_1V05_PCH_VR_CURR,
+ BIC_SENSOR_VCCIN_VR_POUT,
+ BIC_SENSOR_VCCIN_VR_CURR,
+ BIC_SENSOR_VCCIN_VR_VOL,
+ BIC_SENSOR_INA230_POWER,
+ BIC_SENSOR_SOC_PACKAGE_PWR,
+ BIC_SENSOR_SOC_TJMAX,
+ BIC_SENSOR_VDDR_VR_POUT,
+ BIC_SENSOR_VDDR_VR_CURR,
+ BIC_SENSOR_VDDR_VR_VOL,
+ BIC_SENSOR_VCC_SCSUS_VR_CURR,
+ BIC_SENSOR_VCC_SCSUS_VR_VOL,
+ BIC_SENSOR_VCC_SCSUS_VR_TEMP,
+ BIC_SENSOR_VCC_SCSUS_VR_POUT,
+ BIC_SENSOR_VCC_GBE_VR_POUT,
+ BIC_SENSOR_VCC_GBE_VR_VOL,
+ BIC_SENSOR_1V05_PCH_VR_VOL,
+ BIC_SENSOR_SOC_DIMMA0_TEMP,
+ BIC_SENSOR_SOC_DIMMA1_TEMP,
+ BIC_SENSOR_SOC_DIMMB0_TEMP,
+ BIC_SENSOR_SOC_DIMMB1_TEMP,
+ BIC_SENSOR_P3V3_MB,
+ BIC_SENSOR_P12V_MB,
+ BIC_SENSOR_P1V05_PCH,
+ BIC_SENSOR_P3V3_STBY_MB,
+ BIC_SENSOR_P5V_STBY_MB,
+ BIC_SENSOR_PV_BAT,
+ BIC_SENSOR_PVDDR,
+ BIC_SENSOR_PVCC_GBE,
+ /* Discrete sensors */
+ //BIC_SENSOR_SYSTEM_STATUS,
+ //BIC_SENSOR_SYS_BOOT_STAT,
+ //BIC_SENSOR_CPU_DIMM_HOT,
+ //BIC_SENSOR_PROC_FAIL,
+ //BIC_SENSOR_VR_HOT,
+ /* Event-only sensors */
+ //BIC_SENSOR_POST_ERR,
+ //BIC_SENSOR_SPS_FW_HLTH,
+ //BIC_SENSOR_POWER_THRESH_EVENT,
+ //BIC_SENSOR_MACHINE_CHK_ERR,
+ //BIC_SENSOR_PCIE_ERR,
+ //BIC_SENSOR_OTHER_IIO_ERR,
+ //BIC_SENSOR_PROC_HOT_EXT,
+ //BIC_SENSOR_POWER_ERR,
+ //BIC_SENSOR_CAT_ERR,
+};
+
+// List of SPB sensors to be monitored
+const uint8_t spb_sensor_list[] = {
+ SP_SENSOR_INLET_TEMP,
+ SP_SENSOR_OUTLET_TEMP,
+ //SP_SENSOR_MEZZ_TEMP
+ SP_SENSOR_FAN0_TACH,
+ SP_SENSOR_FAN1_TACH,
+ //SP_SENSOR_AIR_FLOW,
+ SP_SENSOR_P5V,
+ SP_SENSOR_P12V,
+ SP_SENSOR_P3V3_STBY,
+ SP_SENSOR_P12V_SLOT0,
+ SP_SENSOR_P12V_SLOT1,
+ SP_SENSOR_P12V_SLOT2,
+ SP_SENSOR_P12V_SLOT3,
+ SP_SENSOR_P3V3,
+ SP_SENSOR_HSC_IN_VOLT,
+ SP_SENSOR_HSC_OUT_CURR,
+ SP_SENSOR_HSC_TEMP,
+ SP_SENSOR_HSC_IN_POWER,
+};
+
+size_t bic_sensor_cnt = sizeof(bic_sensor_list)/sizeof(uint8_t);
+
+size_t spb_sensor_cnt = sizeof(spb_sensor_list)/sizeof(uint8_t);
+
+enum {
+ FAN0 = 0,
+ FAN1,
+};
+
+enum {
+ ADC_PIN0 = 0,
+ ADC_PIN1,
+ ADC_PIN2,
+ ADC_PIN3,
+ ADC_PIN4,
+ ADC_PIN5,
+ ADC_PIN6,
+ ADC_PIN7,
+};
+
+static sensor_info_t g_sinfo1[MAX_SENSOR_NUM] = {0};
+static sensor_info_t g_sinfo2[MAX_SENSOR_NUM] = {0};
+static sensor_info_t g_sinfo3[MAX_SENSOR_NUM] = {0};
+static sensor_info_t g_sinfo4[MAX_SENSOR_NUM] = {0};
+static sensor_info_t g_sinfo_spb[MAX_SENSOR_NUM] = {0};
+static sensor_info_t g_sinfo_nic[MAX_SENSOR_NUM] = {0};
+
+static int
+read_device(const char *device, int *value) {
+ FILE *fp;
+ int rc;
+
+ fp = fopen(device, "r");
+ if (!fp) {
+ int err = errno;
+
+ syslog(LOG_INFO, "failed to open device %s", device);
+ return err;
+ }
+
+ rc = fscanf(fp, "%d", value);
+ fclose(fp);
+
+ if (rc != 1) {
+ syslog(LOG_INFO, "failed to read device %s", device);
+ return ENOENT;
+ } else {
+ return 0;
+ }
+}
+
+static int
+read_device_float(const char *device, float *value) {
+ FILE *fp;
+ int rc;
+ char tmp[10];
+
+ fp = fopen(device, "r");
+ if (!fp) {
+ int err = errno;
+
+ syslog(LOG_INFO, "failed to open device %s", device);
+ return err;
+ }
+
+ rc = fscanf(fp, "%s", tmp);
+ fclose(fp);
+
+ if (rc != 1) {
+ syslog(LOG_INFO, "failed to read device %s", device);
+ return ENOENT;
+ }
+
+ *value = atof(tmp);
+
+ return 0;
+}
+
+static int
+read_temp(const char *device, float *value) {
+ char full_name[LARGEST_DEVICE_NAME + 1];
+ int tmp;
+
+ snprintf(
+ full_name, LARGEST_DEVICE_NAME, "%s/temp1_input", device);
+ if (read_device(full_name, &tmp)) {
+ return -1;
+ }
+
+ *value = ((float)tmp)/UNIT_DIV;
+
+ return 0;
+}
+
+static int
+read_fan_value(const int fan, const char *device, float *value) {
+ char device_name[LARGEST_DEVICE_NAME];
+ char full_name[LARGEST_DEVICE_NAME];
+
+ snprintf(device_name, LARGEST_DEVICE_NAME, device, fan);
+ snprintf(full_name, LARGEST_DEVICE_NAME, "%s/%s", TACH_DIR, device_name);
+ return read_device_float(full_name, value);
+}
+
+static int
+read_adc_value(const int pin, const char *device, float *value) {
+ char device_name[LARGEST_DEVICE_NAME];
+ char full_name[LARGEST_DEVICE_NAME];
+
+ snprintf(device_name, LARGEST_DEVICE_NAME, device, pin);
+ snprintf(full_name, LARGEST_DEVICE_NAME, "%s/%s", ADC_DIR, device_name);
+ return read_device_float(full_name, value);
+}
+
+static int
+read_hsc_value(const char *device, float *value) {
+ char full_name[LARGEST_DEVICE_NAME];
+ int tmp;
+
+ snprintf(full_name, LARGEST_DEVICE_NAME, "%s/%s", HSC_DEVICE, device);
+ if(read_device(full_name, &tmp)) {
+ return -1;
+ }
+
+ *value = ((float) tmp)/UNIT_DIV;
+
+ return 0;
+}
+
+static int
+bic_read_sensor_wrapper(uint8_t slot_id, uint8_t sensor_num, void *value) {
+ int ret;
+ ipmi_sensor_reading_t sensor;
+
+ ret = bic_read_sensor(slot_id, sensor_num, &sensor);
+ if (ret) {
+ return ret;
+ }
+
+ if (sensor.flags & BIC_SENSOR_READ_NA) {
+ syslog(LOG_ERR, "bic_read_sensor_wrapper: Reading Not Available");
+ syslog(LOG_ERR, "bic_read_sensor_wrapper: sensor_num: 0x%X, flag: 0x%X",
+ sensor_num, sensor.flags);
+ return -1;
+ }
+
+ if (sensor.status) {
+ //printf("bic_read_sensor_wrapper: Status Asserted: 0x%X\n", sensor.status);
+ }
+
+ // Check SDR to convert raw value to actual
+ sdr_full_t *sdr;
+
+ switch (slot_id) {
+ case 1:
+ sdr = &g_sinfo1[sensor_num].sdr;
+ break;
+ case 2:
+ sdr = &g_sinfo2[sensor_num].sdr;
+ break;
+ case 3:
+ sdr = &g_sinfo3[sensor_num].sdr;
+ break;
+ case 4:
+ sdr = &g_sinfo4[sensor_num].sdr;
+ break;
+ default:
+ syslog(LOG_ALERT, "bic_read_sensor_wrapper: Wrong Slot ID\n");
+ return -1;
+ }
+
+ // If the SDR is not type1, no need for conversion
+ if (sdr->type !=1) {
+ *(float *) value = sensor.value;
+ return 0;
+ }
+
+ // y = (mx + b * 10^b_exp) * 10^r_exp
+ uint8_t x;
+ uint8_t m_lsb, m_msb, m;
+ uint8_t b_lsb, b_msb, b;
+ int8_t b_exp, r_exp;
+
+ x = sensor.value;
+
+ m_lsb = sdr->m_val;
+ m_msb = sdr->m_tolerance >> 6;
+ m = (m_msb << 8) | m_lsb;
+
+ b_lsb = sdr->b_val;
+ b_msb = sdr->b_accuracy >> 6;
+ b = (b_msb << 8) | b_lsb;
+
+ // exponents are 2's complement 4-bit number
+ b_exp = sdr->rb_exp & 0xF;
+ if (b_exp > 7) {
+ b_exp = (~b_exp + 1) & 0xF;
+ b_exp = -b_exp;
+ }
+ r_exp = (sdr->rb_exp >> 4) & 0xF;
+ if (r_exp > 7) {
+ r_exp = (~r_exp + 1) & 0xF;
+ r_exp = -r_exp;
+ }
+
+ //printf("m:%d, x:%d, b:%d, b_exp:%d, r_exp:%d\n", m, x, b, b_exp, r_exp);
+
+ * (float *) value = ((m * x) + (b * pow(10, b_exp))) * (pow(10, r_exp));
+
+ return 0;
+}
+
+/* Returns the all the SDRs for the particular fru# */
+static sensor_info_t *
+get_struct_sensor_info(uint8_t fru) {
+ sensor_info_t *sinfo;
+ switch(fru) {
+ case FRU_SLOT1:
+ sinfo = g_sinfo1;
+ break;
+ case FRU_SLOT2:
+ sinfo = g_sinfo2;
+ break;
+ case FRU_SLOT3:
+ sinfo = g_sinfo3;
+ break;
+ case FRU_SLOT4:
+ sinfo = g_sinfo4;
+ break;
+ case FRU_SPB:
+ sinfo = g_sinfo_spb;
+ break;
+ case FRU_NIC:
+ sinfo = g_sinfo_nic;
+ break;
+ default:
+ syslog(LOG_ALERT, "yosemite_sdr_init: Wrong Slot ID\n");
+ return NULL;
+ }
+ return sinfo;
+}
+
+int
+get_fru_sdr_path(uint8_t fru, char *path) {
+
+ char fru_name[16] = {0};
+
+ switch(fru) {
+ case FRU_SLOT1:
+ sprintf(fru_name, "%s", "slot1");
+ break;
+ case FRU_SLOT2:
+ sprintf(fru_name, "%s", "slot2");
+ break;
+ case FRU_SLOT3:
+ sprintf(fru_name, "%s", "slot3");
+ break;
+ case FRU_SLOT4:
+ sprintf(fru_name, "%s", "slot4");
+ break;
+ case FRU_SPB:
+ sprintf(fru_name, "%s", "spb");
+ break;
+ case FRU_NIC:
+ sprintf(fru_name, "%s", "nic");
+ break;
+ default:
+ syslog(LOG_ALERT, "yosemite_sdr_init: Wrong Slot ID\n");
+ return -1;
+ }
+
+ sprintf(path, YOSEMITE_SDR_PATH, fru_name);
+
+ return 0;
+}
+
+static int
+yosemite_sdr_init(uint8_t fru) {
+ int fd;
+ uint8_t buf[MAX_SDR_LEN] = {0};
+ uint8_t bytes_rd = 0;
+ uint8_t sn = 0;
+ char path[64] = {0};
+ sensor_info_t *sinfo;
+
+ if (get_fru_sdr_path(fru, path) < 0) {
+ syslog(LOG_ALERT, "yosemite_sdr_init: get_fru_sdr_path failed\n");
+ return -1;
+ }
+ sinfo = get_struct_sensor_info(fru);
+ if (sinfo == NULL) {
+ syslog(LOG_ALERT, "yosemite_sdr_init: get_struct_sensor_info failed\n");
+ return -1;
+ }
+
+ if (sdr_init(path, sinfo) < 0) {
+ syslog(LOG_ERR, "yosemite_sdr_init: sdr_init failed for FRU %d", fru);
+ }
+
+ return 0;
+}
+
+static bool
+is_server_prsnt(uint8_t slot_id) {
+ uint8_t gpio;
+ int val;
+ char path[64] = {0};
+
+ switch(slot_id) {
+ case 1:
+ gpio = 61;
+ break;
+ case 2:
+ gpio = 60;
+ break;
+ case 3:
+ gpio = 63;
+ break;
+ case 4:
+ gpio = 62;
+ break;
+ default:
+ return 0;
+ }
+
+ sprintf(path, GPIO_VAL, gpio);
+
+ if (read_device(path, &val)) {
+ return -1;
+ }
+
+ if (val == 0x0) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/* Get the units for the sensor */
+int
+yosemite_sensor_units(uint8_t fru, uint8_t sensor_num, char *units) {
+ static bool init_done = false;
+ uint8_t op, modifier;
+ sensor_info_t *sinfo;
+
+ if (!init_done) {
+
+ if (is_server_prsnt(1) && (yosemite_sdr_init(FRU_SLOT1) != 0)) {
+ return -1;
+ }
+ if (is_server_prsnt(2) && (yosemite_sdr_init(FRU_SLOT2) != 0)) {
+ return -1;
+ }
+ if (is_server_prsnt(3) && (yosemite_sdr_init(FRU_SLOT3) != 0)) {
+ return -1;
+ }
+ if (is_server_prsnt(4) && (yosemite_sdr_init(FRU_SLOT4) != 0)) {
+ return -1;
+ }
+ init_done = true;
+ }
+
+ switch(fru) {
+ case FRU_SLOT1:
+ case FRU_SLOT2:
+ case FRU_SLOT3:
+ case FRU_SLOT4:
+ sinfo = get_struct_sensor_info(fru);
+ if (sinfo == NULL) {
+ syslog(LOG_ALERT, "yosemite_sensor_units: get_struct_sensor_info failed\n");
+ return -1;
+ }
+
+ if (sdr_get_sensor_units(&sinfo[sensor_num].sdr, &op, &modifier, units)) {
+ syslog(LOG_ALERT, "yosemite_sensor_units: FRU %d: num 0x%2X: reading units"
+ " from SDR failed.", fru, sensor_num);
+ return -1;
+ }
+ break;
+ case FRU_SPB:
+ switch(sensor_num) {
+ case SP_SENSOR_INLET_TEMP:
+ sprintf(units, "C");
+ break;
+ case SP_SENSOR_OUTLET_TEMP:
+ sprintf(units, "C");
+ break;
+ case SP_SENSOR_MEZZ_TEMP:
+ sprintf(units, "C");
+ break;
+ case SP_SENSOR_FAN0_TACH:
+ sprintf(units, "RPM");
+ break;
+ case SP_SENSOR_FAN1_TACH:
+ sprintf(units, "RPM");
+ break;
+ case SP_SENSOR_AIR_FLOW:
+ sprintf(units, "");
+ break;
+ case SP_SENSOR_P5V:
+ sprintf(units, "Volts");
+ break;
+ case SP_SENSOR_P12V:
+ sprintf(units, "Volts");
+ break;
+ case SP_SENSOR_P3V3_STBY:
+ sprintf(units, "Volts");
+ break;
+ case SP_SENSOR_P12V_SLOT0:
+ sprintf(units, "Volts");
+ break;
+ case SP_SENSOR_P12V_SLOT1:
+ sprintf(units, "Volts");
+ break;
+ case SP_SENSOR_P12V_SLOT2:
+ sprintf(units, "Volts");
+ break;
+ case SP_SENSOR_P12V_SLOT3:
+ sprintf(units, "Volts");
+ break;
+ case SP_SENSOR_P3V3:
+ sprintf(units, "Volts");
+ break;
+ case SP_SENSOR_HSC_IN_VOLT:
+ sprintf(units, "Volts");
+ break;
+ case SP_SENSOR_HSC_OUT_CURR:
+ sprintf(units, "Amps");
+ break;
+ case SP_SENSOR_HSC_TEMP:
+ sprintf(units, "C");
+ break;
+ case SP_SENSOR_HSC_IN_POWER:
+ sprintf(units, "Watts");
+ break;
+ }
+ break;
+ case FRU_NIC:
+ sprintf(units, "");
+ break;
+ }
+ return 0;
+}
+
+/* Get the name for the sensor */
+int
+yosemite_sensor_name(uint8_t fru, uint8_t sensor_num, char *name) {
+ static bool init_done = false;
+ uint8_t op, modifier;
+ sensor_info_t *sinfo;
+
+ if (!init_done) {
+
+ if (is_server_prsnt(1) && (yosemite_sdr_init(FRU_SLOT1) != 0)) {
+ return -1;
+ }
+ if (is_server_prsnt(2) && (yosemite_sdr_init(FRU_SLOT2) != 0)) {
+ return -1;
+ }
+ if (is_server_prsnt(3) && (yosemite_sdr_init(FRU_SLOT3) != 0)) {
+ return -1;
+ }
+ if (is_server_prsnt(4) && (yosemite_sdr_init(FRU_SLOT4) != 0)) {
+ return -1;
+ }
+ init_done = true;
+ }
+
+ switch(fru) {
+ case FRU_SLOT1:
+ case FRU_SLOT2:
+ case FRU_SLOT3:
+ case FRU_SLOT4:
+ sinfo = get_struct_sensor_info(fru);
+ if (sinfo == NULL) {
+ syslog(LOG_ALERT, "yosemite_sensor_name: get_struct_sensor_info failed\n");
+ return -1;
+ }
+
+ if (sdr_get_sensor_name(&sinfo[sensor_num].sdr, name)) {
+ syslog(LOG_ALERT, "yosemite_sensor_name: FRU %d: num 0x%2X: reading units"
+ " from SDR failed.", fru, sensor_num);
+ return -1;
+ }
+
+ break;
+ case FRU_SPB:
+ switch(sensor_num) {
+ case SP_SENSOR_INLET_TEMP:
+ sprintf(name, "SP_SENSOR_INLET_TEMP");
+ break;
+ case SP_SENSOR_OUTLET_TEMP:
+ sprintf(name, "SP_SENSOR_OUTLET_TEMP");
+ break;
+ case SP_SENSOR_MEZZ_TEMP:
+ sprintf(name, "SP_SENSOR_MEZZ_TEMP");
+ break;
+ case SP_SENSOR_FAN0_TACH:
+ sprintf(name, "SP_SENSOR_FAN0_TACH");
+ break;
+ case SP_SENSOR_FAN1_TACH:
+ sprintf(name, "SP_SENSOR_FAN1_TACH");
+ break;
+ case SP_SENSOR_AIR_FLOW:
+ sprintf(name, "SP_SENSOR_AIR_FLOW");
+ break;
+ case SP_SENSOR_P5V:
+ sprintf(name, "SP_SENSOR_P5V");
+ break;
+ case SP_SENSOR_P12V:
+ sprintf(name, "SP_SENSOR_P12V");
+ break;
+ case SP_SENSOR_P3V3_STBY:
+ sprintf(name, "SP_SENSOR_P3V3_STBY");
+ break;
+ case SP_SENSOR_P12V_SLOT0:
+ sprintf(name, "SP_SENSOR_P12V_SLOT0");
+ break;
+ case SP_SENSOR_P12V_SLOT1:
+ sprintf(name, "SP_SENSOR_P12V_SLOT1");
+ break;
+ case SP_SENSOR_P12V_SLOT2:
+ sprintf(name, "SP_SENSOR_P12V_SLOT2");
+ break;
+ case SP_SENSOR_P12V_SLOT3:
+ sprintf(name, "SP_SENSOR_P12V_SLOT3");
+ break;
+ case SP_SENSOR_P3V3:
+ sprintf(name, "SP_SENSOR_P3V3");
+ break;
+ case SP_SENSOR_HSC_IN_VOLT:
+ sprintf(name, "SP_SENSOR_HSC_IN_VOLT");
+ break;
+ case SP_SENSOR_HSC_OUT_CURR:
+ sprintf(name, "SP_SENSOR_HSC_OUT_CURR");
+ break;
+ case SP_SENSOR_HSC_TEMP:
+ sprintf(name, "SP_SENSOR_HSC_TEMP");
+ break;
+ case SP_SENSOR_HSC_IN_POWER:
+ sprintf(name, "SP_SENSOR_HSC_IN_POWER");
+ break;
+ }
+ break;
+ case FRU_NIC:
+ sprintf(name, "");
+ break;
+ }
+ return 0;
+}
+
+
+int
+yosemite_sensor_read(uint8_t slot_id, uint8_t sensor_num, void *value) {
+ static bool init_done = false;
+ float volt;
+ float curr;
+
+ if (!init_done) {
+
+ if (is_server_prsnt(1) && (yosemite_sdr_init(FRU_SLOT1) != 0)) {
+ return -1;
+ }
+
+ if (is_server_prsnt(2) && (yosemite_sdr_init(FRU_SLOT2) != 0)) {
+ return -1;
+ }
+
+ if (is_server_prsnt(3) && (yosemite_sdr_init(FRU_SLOT3) != 0)) {
+ return -1;
+ }
+
+ if (is_server_prsnt(4) && (yosemite_sdr_init(FRU_SLOT4) != 0)) {
+ return -1;
+ }
+
+ init_done = true;
+ }
+
+ switch(sensor_num) {
+ // Inlet, Outlet Temp
+
+ case SP_SENSOR_INLET_TEMP:
+ return read_temp(SP_INLET_TEMP_DEVICE, (float*) value);
+ case SP_SENSOR_OUTLET_TEMP:
+ return read_temp(SP_OUTLET_TEMP_DEVICE, (float*) value);
+
+ // Fan Tach Values
+ case SP_SENSOR_FAN0_TACH:
+ return read_fan_value(FAN0, FAN_TACH_RPM, (float*) value);
+ case SP_SENSOR_FAN1_TACH:
+ return read_fan_value(FAN1, FAN_TACH_RPM, (float*) value);
+
+ // Various Voltages
+ case SP_SENSOR_P5V:
+ return read_adc_value(ADC_PIN0, ADC_VALUE, (float*) value);
+ case SP_SENSOR_P12V:
+ return read_adc_value(ADC_PIN1, ADC_VALUE, (float*) value);
+ case SP_SENSOR_P3V3_STBY:
+ return read_adc_value(ADC_PIN2, ADC_VALUE, (float*) value);
+ case SP_SENSOR_P12V_SLOT0:
+ return read_adc_value(ADC_PIN3, ADC_VALUE, (float*) value);
+ case SP_SENSOR_P12V_SLOT1:
+ return read_adc_value(ADC_PIN4, ADC_VALUE, (float*) value);
+ case SP_SENSOR_P12V_SLOT2:
+ return read_adc_value(ADC_PIN5, ADC_VALUE, (float*) value);
+ case SP_SENSOR_P12V_SLOT3:
+ return read_adc_value(ADC_PIN6, ADC_VALUE, (float*) value);
+ case SP_SENSOR_P3V3:
+ return read_adc_value(ADC_PIN7, ADC_VALUE, (float*) value);
+
+ // Hot Swap Controller
+ case SP_SENSOR_HSC_IN_VOLT:
+ return read_hsc_value(HSC_IN_VOLT, (float*) value);
+ case SP_SENSOR_HSC_OUT_CURR:
+ return read_hsc_value(HSC_OUT_CURR, (float*) value);
+ case SP_SENSOR_HSC_TEMP:
+ return read_hsc_value(HSC_TEMP, (float*) value);
+ case SP_SENSOR_HSC_IN_POWER:
+ if (read_hsc_value(HSC_IN_VOLT, &volt)) {
+ return -1;
+ }
+
+ if (read_hsc_value(HSC_OUT_CURR, &curr)) {
+ return -1;
+ }
+
+ * (float*) value = volt * curr;
+ return 0;
+ default:
+ // For all others we assume the sensors are on Monolake
+ return bic_read_sensor_wrapper(slot_id, sensor_num, value);
+ }
+}
+
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/yosemite_sensor.h b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/yosemite_sensor.h
new file mode 100644
index 0000000..0a33173
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/files/yosemite_sensor/yosemite_sensor.h
@@ -0,0 +1,133 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ *
+ * 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.
+ */
+
+#ifndef __YOSEMITE_SENSOR_H__
+#define __YOSEMITE_SENSOR_H__
+
+#include <stdbool.h>
+#include <openbmc/ipmi.h>
+#include <openbmc/ipmb.h>
+#include <openbmc/sdr.h>
+#include <facebook/bic.h>
+#include <facebook/yosemite_common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Sensors under Bridge IC
+enum {
+ BIC_SENSOR_MB_OUTLET_TEMP = 0x01,
+ BIC_SENSOR_VCCIN_VR_TEMP = 0x02,
+ BIC_SENSOR_VCC_GBE_VR_TEMP = 0x03,
+ BIC_SENSOR_1V05PCH_VR_TEMP = 0x04,
+ BIC_SENSOR_SOC_TEMP = 0x05,
+ BIC_SENSOR_MB_INLET_TEMP = 0x07,
+ BIC_SENSOR_PCH_TEMP = 0x08,
+ BIC_SENSOR_SOC_THERM_MARGIN = 0x09,
+ BIC_SENSOR_VDDR_VR_TEMP = 0x0B,
+ BIC_SENSOR_SYSTEM_STATUS = 0x10, //Discrete
+ BIC_SENSOR_SPS_FW_HLTH = 0x17, //Event-only
+ BIC_SENSOR_VCC_GBE_VR_CURR = 0x20,
+ BIC_SENSOR_1V05_PCH_VR_CURR = 0x21,
+ BIC_SENSOR_VCCIN_VR_POUT = 0x22,
+ BIC_SENSOR_VCCIN_VR_CURR = 0x23,
+ BIC_SENSOR_VCCIN_VR_VOL = 0x24,
+ BIC_SENSOR_INA230_POWER = 0x29,
+ BIC_SENSOR_POST_ERR = 0x2B, //Event-only
+ BIC_SENSOR_SOC_PACKAGE_PWR = 0x2C,
+ BIC_SENSOR_SOC_TJMAX = 0x30,
+ BIC_SENSOR_VDDR_VR_POUT = 0x32,
+ BIC_SENSOR_VDDR_VR_CURR = 0x33,
+ BIC_SENSOR_VDDR_VR_VOL = 0x34,
+ BIC_SENSOR_VCC_SCSUS_VR_CURR = 0x35,
+ BIC_SENSOR_VCC_SCSUS_VR_VOL = 0x36,
+ BIC_SENSOR_VCC_SCSUS_VR_TEMP = 0x37,
+ BIC_SENSOR_VCC_SCSUS_VR_POUT = 0x38,
+ BIC_SENSOR_VCC_GBE_VR_POUT = 0x39,
+ BIC_SENSOR_POWER_THRESH_EVENT = 0x3B, //Event-only
+ //BIC_SENSOR_1V05_PCH_VR_POUT = 0x40,
+ BIC_SENSOR_MACHINE_CHK_ERR = 0x40, //Event-only
+ BIC_SENSOR_PCIE_ERR = 0x41, //Event-only
+ BIC_SENSOR_OTHER_IIO_ERR = 0x43, //Event-only
+ BIC_SENSOR_PROC_HOT_EXT = 0x51, //Event-only
+ BIC_SENSOR_VCC_GBE_VR_VOL = 0x54,
+ BIC_SENSOR_1V05_PCH_VR_VOL = 0x55,
+ BIC_SENSOR_POWER_ERR = 0x56, //Event-only
+ BIC_SENSOR_MEM_ECC_ERR = 0x63, //Event-only
+ BIC_SENSOR_PROC_FAIL = 0x65, //Discrete
+ BIC_SENSOR_SYS_BOOT_STAT = 0x7E, //Discrete
+ BIC_SENSOR_VR_HOT = 0xB2, //Discrete
+ BIC_SENSOR_CPU_DIMM_HOT = 0xB3, //Discrete
+ BIC_SENSOR_SOC_DIMMA0_TEMP = 0xB4,
+ BIC_SENSOR_SOC_DIMMA1_TEMP = 0xB5,
+ BIC_SENSOR_SOC_DIMMB0_TEMP = 0xB6,
+ BIC_SENSOR_SOC_DIMMB1_TEMP = 0xB7,
+ BIC_SENSOR_P3V3_MB = 0xD0,
+ BIC_SENSOR_P12V_MB = 0xD2,
+ BIC_SENSOR_P1V05_PCH = 0xD3,
+ BIC_SENSOR_P3V3_STBY_MB = 0xD5,
+ BIC_SENSOR_P5V_STBY_MB = 0xD6,
+ BIC_SENSOR_PV_BAT = 0xD7,
+ BIC_SENSOR_PVDDR = 0xD8,
+ BIC_SENSOR_PVCC_GBE = 0xD9,
+ BIC_SENSOR_CAT_ERR = 0xEB, //Event-only
+};
+
+// Sensors Under Side Plane
+enum {
+ SP_SENSOR_INLET_TEMP = 0x81,
+ SP_SENSOR_OUTLET_TEMP = 0x80,
+ SP_SENSOR_MEZZ_TEMP = 0x82,
+ SP_SENSOR_FAN0_TACH = 0x46,
+ SP_SENSOR_FAN1_TACH = 0x47,
+ SP_SENSOR_AIR_FLOW = 0x4A,
+ SP_SENSOR_P5V = 0xE0,
+ SP_SENSOR_P12V = 0xE1,
+ SP_SENSOR_P3V3_STBY = 0xE2,
+ SP_SENSOR_P12V_SLOT0 = 0xE3,
+ SP_SENSOR_P12V_SLOT1 = 0xE4,
+ SP_SENSOR_P12V_SLOT2 = 0xE5,
+ SP_SENSOR_P12V_SLOT3 = 0xE6,
+ SP_SENSOR_P3V3 = 0xE7,
+ SP_SENSOR_HSC_IN_VOLT = 0xC0,
+ SP_SENSOR_HSC_OUT_CURR = 0xC1,
+ SP_SENSOR_HSC_TEMP = 0xC2,
+ SP_SENSOR_HSC_IN_POWER = 0xC3,
+};
+
+extern const uint8_t bic_sensor_list[];
+
+extern const uint8_t spb_sensor_list[];
+
+extern size_t bic_sensor_cnt;
+
+extern size_t spb_sensor_cnt;
+
+int yosemite_sensor_read(uint8_t slot_id, uint8_t sensor_num, void *value);
+int yosemite_sensor_name(uint8_t fru, uint8_t sensor_num, char *name);
+int yosemite_sensor_units(uint8_t fru, uint8_t sensor_num, char *units);
+int get_fru_sdr_path(uint8_t fru, char *path);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* __YOSEMITE_SENSOR_H__ */
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/libbic_0.1.bb b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/libbic_0.1.bb
new file mode 100644
index 0000000..6b22366
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/libbic_0.1.bb
@@ -0,0 +1,25 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+SUMMARY = "Bridge IC Library"
+DESCRIPTION = "library for communicating with Bridge IC"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://bic.c;beginline=8;endline=20;md5=da35978751a9d71b73679307c4d296ec"
+
+
+SRC_URI = "file://bic \
+ "
+DEPENDS += "libipmi libipmb"
+
+S = "${WORKDIR}/bic"
+
+do_install() {
+ install -d ${D}${libdir}
+ install -m 0644 libbic.so ${D}${libdir}/libbic.so
+
+ install -d ${D}${includedir}/facebook
+ install -m 0644 bic.h ${D}${includedir}/facebook/bic.h
+}
+
+FILES_${PN} = "${libdir}/libbic.so"
+FILES_${PN}-dev = "${includedir}/facebook/bic.h"
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/libpal_0.1.bb b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/libpal_0.1.bb
new file mode 100644
index 0000000..bcdd420
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/libpal_0.1.bb
@@ -0,0 +1,28 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+SUMMARY = "Platform Abstraction Library"
+DESCRIPTION = "library for communicating with Platform"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://pal.c;beginline=8;endline=20;md5=da35978751a9d71b73679307c4d296ec"
+
+
+SRC_URI = "file://pal \
+ "
+
+DEPENDS += "libbic libyosemite-common libyosemite-fruid libyosemite-sensor "
+
+S = "${WORKDIR}/pal"
+
+do_install() {
+ install -d ${D}${libdir}
+ install -m 0644 libpal.so ${D}${libdir}/libpal.so
+
+ install -d ${D}${includedir}/openbmc
+ install -m 0644 pal.h ${D}${includedir}/openbmc/pal.h
+}
+
+FILES_${PN} = "${libdir}/libpal.so"
+FILES_${PN}-dev = "${includedir}/openbmc/pal.h"
+
+RDEPENDS_${PN} += " libyosemite-common"
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/libyosemite-common_0.1.bb b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/libyosemite-common_0.1.bb
new file mode 100644
index 0000000..bdf8192
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/libyosemite-common_0.1.bb
@@ -0,0 +1,25 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+SUMMARY = "Yosemite Common Library"
+DESCRIPTION = "library for common Yosemite information"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://yosemite_common.c;beginline=8;endline=20;md5=da35978751a9d71b73679307c4d296ec"
+
+
+SRC_URI = "file://yosemite_common \
+ "
+
+S = "${WORKDIR}/yosemite_common"
+
+do_install() {
+ install -d ${D}${libdir}
+ install -m 0644 libyosemite_common.so ${D}${libdir}/libyosemite_common.so
+
+ install -d ${D}${includedir}
+ install -d ${D}${includedir}/facebook
+ install -m 0644 yosemite_common.h ${D}${includedir}/facebook/yosemite_common.h
+}
+
+FILES_${PN} = "${libdir}/libyosemite_common.so"
+FILES_${PN}-dev = "${includedir}/facebook/yosemite_common.h"
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/libyosemite-fruid_0.1.bb b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/libyosemite-fruid_0.1.bb
new file mode 100644
index 0000000..ce9fe7f
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/libyosemite-fruid_0.1.bb
@@ -0,0 +1,43 @@
+# 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
+
+SUMMARY = "Yosemite Fruid Library"
+DESCRIPTION = "library for reading all yosemite fruids"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://yosemite_fruid.c;beginline=6;endline=18;md5=da35978751a9d71b73679307c4d296ec"
+
+
+SRC_URI = "file://yosemite_fruid \
+ "
+
+DEPENDS += " libyosemite-common "
+
+S = "${WORKDIR}/yosemite_fruid"
+
+do_install() {
+ install -d ${D}${libdir}
+ install -m 0644 libyosemite_fruid.so ${D}${libdir}/libyosemite_fruid.so
+
+ install -d ${D}${includedir}
+ install -d ${D}${includedir}/facebook
+ install -m 0644 yosemite_fruid.h ${D}${includedir}/facebook/yosemite_fruid.h
+}
+
+FILES_${PN} = "${libdir}/libyosemite_fruid.so"
+FILES_${PN}-dev = "${includedir}/facebook/yosemite_fruid.h"
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/libyosemite-gpio_0.1.bb b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/libyosemite-gpio_0.1.bb
new file mode 100644
index 0000000..39993d0
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/libyosemite-gpio_0.1.bb
@@ -0,0 +1,43 @@
+# 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
+
+SUMMARY = "Yosemite GPIO Pin Library"
+DESCRIPTION = "library for all gpio pins in yosemite"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://yosemite_gpio.c;beginline=6;endline=18;md5=da35978751a9d71b73679307c4d296ec"
+
+
+SRC_URI = "file://yosemite_gpio \
+ "
+
+DEPENDS += "libbic "
+
+S = "${WORKDIR}/yosemite_gpio"
+
+do_install() {
+ install -d ${D}${libdir}
+ install -m 0644 libyosemite_gpio.so ${D}${libdir}/libyosemite_gpio.so
+
+ install -d ${D}${includedir}
+ install -d ${D}${includedir}/facebook
+ install -m 0644 yosemite_gpio.h ${D}${includedir}/facebook/yosemite_gpio.h
+}
+
+FILES_${PN} = "${libdir}/libyosemite_gpio.so"
+FILES_${PN}-dev = "${includedir}/facebook/yosemite_gpio.h"
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/libyosemite-sensor_0.1.bb b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/libyosemite-sensor_0.1.bb
new file mode 100644
index 0000000..fbb4a15
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fblibs/libyosemite-sensor_0.1.bb
@@ -0,0 +1,25 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+SUMMARY = "Yosemite Sensor Library"
+DESCRIPTION = "library for reading various sensors"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://yosemite_sensor.c;beginline=8;endline=20;md5=da35978751a9d71b73679307c4d296ec"
+
+
+SRC_URI = "file://yosemite_sensor \
+ "
+DEPENDS =+ " libipmi libipmb libbic libsdr libyosemite-common "
+
+S = "${WORKDIR}/yosemite_sensor"
+
+do_install() {
+ install -d ${D}${libdir}
+ install -m 0644 libyosemite_sensor.so ${D}${libdir}/libyosemite_sensor.so
+
+ install -d ${D}${includedir}/facebook
+ install -m 0644 yosemite_sensor.h ${D}${includedir}/facebook/yosemite_sensor.h
+}
+
+FILES_${PN} = "${libdir}/libyosemite_sensor.so"
+FILES_${PN}-dev = "${includedir}/facebook/yosemite_sensor.h"
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/bic-util_0.1.bb b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/bic-util_0.1.bb
new file mode 100644
index 0000000..86679d6
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/bic-util_0.1.bb
@@ -0,0 +1,21 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+SUMMARY = "Bridge IC Utility"
+DESCRIPTION = "Util for checking with Bridge IC on Yosemite"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://bic-util.c;beginline=4;endline=16;md5=b395943ba8a0717a83e62ca123a8d238"
+
+SRC_URI = "file://bic-util \
+ "
+
+S = "${WORKDIR}/bic-util"
+
+do_install() {
+ install -d ${D}${bindir}
+ install -m 0755 bic-util ${D}${bindir}/bic-util
+}
+
+DEPENDS += "libbic"
+
+FILES_${PN} = "${bindir}"
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/fbutils_0.1.bb b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/fbutils_0.1.bb
new file mode 100644
index 0000000..9a9f5fe
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/fbutils_0.1.bb
@@ -0,0 +1,102 @@
+# 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
+SUMMARY = "Utilities"
+DESCRIPTION = "Various utilities"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://COPYING;md5=eb723b61539feef013de476e68b5c50a"
+
+SRC_URI = "file://ast-functions \
+ file://us_console.sh \
+ file://sol-util \
+ file://power_led.sh \
+ file://power_util.py \
+ file://post_led.sh \
+ file://reset_usb.sh \
+ file://setup-gpio.sh \
+ file://setup_rov.sh \
+ file://mdio.py \
+ file://bcm5396.py \
+ file://bcm5396_util.py \
+ file://mount_data0.sh \
+ file://eth0_mac_fixup.sh \
+ file://yosemite_power.sh \
+ file://power-on.sh \
+ file://wedge_us_mac.sh \
+ file://setup_switch.py \
+ file://create_vlan_intf \
+ file://watch-fc.sh \
+ file://fcswitcher.sh \
+ file://rc.early \
+ file://rc.local \
+ file://src \
+ file://COPYING \
+ "
+
+pkgdir = "utils"
+
+S = "${WORKDIR}"
+
+binfiles = "us_console.sh sol-util power_led.sh post_led.sh \
+ reset_usb.sh mdio.py setup_rov.sh yosemite_power.sh wedge_us_mac.sh \
+ bcm5396.py bcm5396_util.py setup_switch.py watch-fc.sh power_util.py"
+
+DEPENDS_append = "update-rc.d-native"
+
+do_install() {
+ dst="${D}/usr/local/fbpackages/${pkgdir}"
+ install -d $dst
+ install -m 644 ast-functions ${dst}/ast-functions
+ localbindir="${D}/usr/local/bin"
+ install -d ${localbindir}
+ for f in ${binfiles}; do
+ install -m 755 $f ${dst}/${f}
+ ln -s ../fbpackages/${pkgdir}/${f} ${localbindir}/${f}
+ done
+
+ # common lib and include files
+ install -d ${D}${includedir}/facebook
+ install -m 0644 src/include/log.h ${D}${includedir}/facebook/log.h
+ install -m 0644 src/include/i2c-dev.h ${D}${includedir}/facebook/i2c-dev.h
+
+ # init
+ install -d ${D}${sysconfdir}/init.d
+ install -d ${D}${sysconfdir}/rcS.d
+ # the script to mount /mnt/data
+ install -m 0755 ${WORKDIR}/mount_data0.sh ${D}${sysconfdir}/init.d/mount_data0.sh
+ update-rc.d -r ${D} mount_data0.sh start 03 S .
+ install -m 0755 ${WORKDIR}/rc.early ${D}${sysconfdir}/init.d/rc.early
+ update-rc.d -r ${D} rc.early start 04 S .
+ install -m 755 setup-gpio.sh ${D}${sysconfdir}/init.d/setup-gpio.sh
+ update-rc.d -r ${D} setup-gpio.sh start 59 S .
+ # create VLAN intf automatically
+ #install -d ${D}/${sysconfdir}/network/if-up.d
+ #install -m 755 create_vlan_intf ${D}${sysconfdir}/network/if-up.d/create_vlan_intf
+ # networking is done after rcS, any start level within rcS
+ # for mac fixup should work
+ #install -m 755 eth0_mac_fixup.sh ${D}${sysconfdir}/init.d/eth0_mac_fixup.sh
+ #update-rc.d -r ${D} eth0_mac_fixup.sh start 70 S .
+ install -m 755 power-on.sh ${D}${sysconfdir}/init.d/power-on.sh
+ update-rc.d -r ${D} power-on.sh start 85 S .
+ #install -m 755 fcswitcher.sh ${D}${sysconfdir}/init.d/fcswitcher.sh
+ #update-rc.d -r ${D} fcswitcher.sh start 90 S .
+ install -m 0755 ${WORKDIR}/rc.local ${D}${sysconfdir}/init.d/rc.local
+ update-rc.d -r ${D} rc.local start 99 2 3 4 5 .
+}
+
+FILES_${PN} += "/usr/local ${sysconfdir}"
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/COPYING b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/COPYING
new file mode 100644
index 0000000..3912109
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/ast-functions b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/ast-functions
new file mode 100644
index 0000000..f29514f
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/ast-functions
@@ -0,0 +1,147 @@
+# Copyright 2014-present Facebook. All Rights Reserved.
+DEVMEM=/sbin/devmem
+
+devmem_set_bit() {
+ local addr
+ local val
+ addr=$1
+ val=$($DEVMEM $addr)
+ val=$((val | (0x1 << $2)))
+ $DEVMEM $addr 32 $val
+}
+
+devmem_clear_bit() {
+ local addr
+ local val
+ addr=$1
+ val=$($DEVMEM $addr)
+ val=$((val & ~(0x1 << $2)))
+ $DEVMEM $addr 32 $val
+}
+
+scu_addr() {
+ echo $((0x1E6E2000 + 0x$1))
+}
+
+GPIODIR="/sys/class/gpio"
+GPIOEXPORT="$GPIODIR/export"
+
+gpio_dir() {
+ echo "$GPIODIR/gpio$1"
+}
+
+gpio_name2value() {
+ local first remaining base val
+ remaining=$1
+ val=0
+ while [ -n "$remaining" ]; do
+ first=${remaining:0:1}
+ case "$first" in
+ [[:lower:]])
+ base=$(printf "%d" "'$first'")
+ base=$((base - 96))
+ val=$((val * 26 + base))
+ ;;
+ [[:upper:]])
+ base=$(printf "%d" "'$first'")
+ base=$((base - 64))
+ val=$((val * 26 + base))
+ ;;
+ *)
+ if [ $val -gt 0 ]; then
+ val=$((val-1))
+ fi
+ val=$((val * 8 + $remaining))
+ break
+ ;;
+ esac
+ remaining=${remaining:1}
+ done
+ echo "$val"
+}
+
+gpio_export() {
+ local gpio
+ gpio=$(gpio_name2value $1)
+ dir=$(gpio_dir $gpio)
+ if [ ! -d ${dir} ]; then
+ echo $gpio > $GPIOEXPORT
+ fi
+}
+
+gpio_set() {
+ local gpio
+ local val
+ gpio=$(gpio_name2value $1)
+ val=$2
+ dir=$(gpio_dir $gpio)
+ if [ ! -d ${dir} ]; then
+ echo $gpio > $GPIOEXPORT
+ fi
+ echo out > ${dir}/direction
+ echo $val > ${dir}/value
+}
+
+gpio_get() {
+ local gpio
+ local val
+ gpio=$(gpio_name2value $1)
+ dir=$(gpio_dir $gpio)
+ if [ ! -d ${dir} ]; then
+ echo $gpio > $GPIOEXPORT
+ fi
+ echo in > ${dir}/direction
+ cat ${dir}/value
+}
+
+# Check to see if BMC power-on-reset
+is_bmc_por() {
+ local val
+ # Read the Watch Dog Counter
+ val=$(devmem 0x1e785010 2>/dev/null)
+ if [ "$((val & 0xff00))" == "0" ]; then
+ # Power ON Reset
+ echo 1
+ else
+ echo 0
+ fi
+}
+
+# Check to see if server is present in given slot or not
+is_server_prsnt() {
+ local prsnt
+
+ case $1 in
+ 1)
+ prsnt=$(gpio_get H5)
+ ;;
+ 2)
+ prsnt=$(gpio_get H4)
+ ;;
+ 3)
+ prsnt=$(gpio_get H7)
+ ;;
+ 4)
+ prsnt=$(gpio_get H6)
+ ;;
+ *)
+ prsnt=$(gpio_get H4)
+ ;;
+ esac
+
+ if [ $prsnt == "0" ]; then
+ echo 1
+ else
+ echo 0
+ fi
+}
+
+yosemite_is_server_on() {
+ local curr_pwr_cpu
+ curr_pwr_cpu=$(python -c 'import sys; sys.path.append("/usr/local/fbpackages/utils"); import power_util; print power_util.get_pwr_cpu()')
+ if [ $curr_pwr_cpu == "1" ]; then
+ echo 1
+ else
+ echo 0
+ fi
+}
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/at93c46.py b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/at93c46.py
new file mode 100644
index 0000000..9fa9f05
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/at93c46.py
@@ -0,0 +1,276 @@
+# 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
+
+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 AT93C46SPI(VerboseLogger):
+ '''The class to access AT93C46 through SPI intf'''
+ SPI_CMD = 'spi-bb'
+
+ def __init__(self, bus_width, gpio_cs, gpio_ck, gpio_do, gpio_di,
+ verbose=False):
+ if bus_width != 8 and bus_width != 16:
+ raise Exception("Invalid bus width for AT93C46!")
+
+ 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 = 6 if self.bus_width == 16 else 7
+ self.addr_mask = 0x3F if self.bus_width == 16 else 0x7F
+
+ 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
+ cmd_loc = 6 if self.bus_width == 16 else 7
+ instruction = addr & self.addr_mask
+ instruction = instruction | ((0x4 | (op & 0x3)) << cmd_loc)
+ 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 - (cmd_loc + 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], cmd_loc + 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 AT93C46(VerboseLogger):
+ '''
+ The class which handles accessing memory on the AT93C46 chip.
+ '''
+ AT93C46_MEMORY_SIZE = 128
+
+ def __init__(self, bus_width, gpio_cs, gpio_ck, gpio_do, gpio_di,
+ byte_swap, verbose=False):
+ self.bus_width = bus_width
+ self.verbose = verbose
+ self.byte_swap = byte_swap
+
+ self.spi = AT93C46SPI(bus_width=bus_width, gpio_cs=gpio_cs,
+ gpio_ck=gpio_ck, gpio_do=gpio_do,
+ gpio_di=gpio_di, 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 erase(self, offset=None, limit=None):
+ '''
+ Erase the chip.
+ '''
+ if offset is None:
+ offset = 0
+ if limit is None:
+ limit = self.AT93C46_MEMORY_SIZE
+
+ if offset < 0 or offset + limit > self.AT93C46_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.AT93C46_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.AT93C46_MEMORY_SIZE
+
+ if offset < 0 or offset + limit > self.AT93C46_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.AT93C46_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-yosemite/recipes-yosemite/fbutils/files/at93c46_util.py b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/at93c46_util.py
new file mode 100755
index 0000000..c10f879
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/at93c46_util.py
@@ -0,0 +1,194 @@
+#!/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
+from at93c46 import AT93C46, AT93C46SPI
+import sys
+
+def get_raw(args):
+ return AT93C46SPI(args.bus_width, args.cs, args.clk, args.mosi, args.miso,
+ args.verbose)
+
+def get_chip(args):
+ return AT93C46(args.bus_width, args.cs, args.clk, args.mosi, args.miso,
+ args.byte_swap, args.verbose)
+
+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: %s)'
+ % SPI_CS_DEFAULT)
+ spi_group.add_argument('--clk', type=int, default=SPI_CLK_DEFAULT,
+ help='The GPIO number for SPI CLK pin (default: %s)'
+ % SPI_CLK_DEFAULT)
+ spi_group.add_argument('--mosi', type=int, default=SPI_MOSI_DEFAULT,
+ help='The GPIO number for SPI MOSI pin (default: %s)'
+ % SPI_MOSI_DEFAULT)
+ spi_group.add_argument('--miso', type=int, default=SPI_MISO_DEFAULT,
+ help='The GPIO number for SPI MISO pin (default: %s)'
+ % SPI_MISO_DEFAULT)
+
+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: %s)'
+ % AT83C46_BUS_WIDTH)
+
+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:
+ fp = open(args.file, "wb")
+ 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(AT93C46.AT93C46_MEMORY_SIZE)
+ else:
+ fp = open(args.file, "rb")
+ data = fp.read(AT93C46.AT93C46_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', action='store_true',
+ help='Byte swap values for 16-bit reads/writes')
+ 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', action='store_true',
+ help='Byte swap values for 16-bit reads/writes')
+ 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')
+
+ # SPI and bus width arguments
+ 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-yosemite/recipes-yosemite/fbutils/files/bcm5396.py b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/bcm5396.py
new file mode 100644
index 0000000..e1aba47
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/bcm5396.py
@@ -0,0 +1,452 @@
+#
+# 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 time
+
+class Bcm5396MDIO:
+ '''The class to access BCM5396 through MDIO intf'''
+ MDIO_CMD = 'mdio-bb'
+
+ PHYADDR = 0x1E
+
+ ACCESS_CTRL_REG = 16
+ IO_CTRL_REG = 17
+ STATUS_REG = 18
+ DATA0_REG = 24
+ DATA1_REG = 25
+ DATA2_REG = 26
+ DATA3_REG = 27
+
+ def __init__(self, mdc, mdio):
+ self.mdc = mdc
+ self.mdio = mdio
+ self.page = -1
+
+ def __io(self, op, reg, val=0):
+ cmd = '%s -p -c %s -d %s %s %s %s' \
+ % (self.MDIO_CMD, self.mdc, self.mdio, op, str(self.PHYADDR),
+ str(reg))
+ if op == 'write':
+ cmd += ' %s' % val
+ out = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)\
+ .communicate()[0]
+ if op == 'write':
+ return val
+ # need to parse the result for read
+ rc = 0
+ for line in out.split('\n'):
+ if not line.startswith('Read:'):
+ continue
+ rc = int(line.split(':')[1], 0)
+ return rc
+
+ def __read_mdio(self, reg):
+ return self.__io('read', reg)
+
+ def __write_mdio(self, reg, val):
+ return self.__io('write', reg, val)
+
+ def __set_page(self, page):
+ if self.page == page:
+ return
+ # Write MII register ACCESS_CTRL_REG:
+ # set bit 0 as "1" to enable MDIO access
+ # set "page number to bit 15:8
+ val = 0x1 | ((page & 0xff) << 8)
+ self.__write_mdio(self.ACCESS_CTRL_REG, val)
+ self.page = page
+
+ def __wait_for_done(self):
+ # Read MII register IO_CTRL_REG:
+ # Check op_code = "00"
+ while (self.__read_mdio(self.IO_CTRL_REG) & 0x3):
+ time.sleep(0.010) # 10ms
+
+ def read(self, page, reg, n_bytes):
+ self.__set_page(page)
+ # Write MII register IO_CTRL_REG:
+ # set "Operation Code as "00"
+ # set "Register Address" to bit 15:8
+ val = 0x00 | ((reg & 0xff) << 8)
+ self.__write_mdio(self.IO_CTRL_REG, val)
+ # Write MII register IO_CTRL_REG:
+ # set "Operation Code as "10"
+ # set "Register Address" to bit 15:8
+ val = 0x2 | ((reg & 0xff) << 8)
+ self.__write_mdio(self.IO_CTRL_REG, val)
+ self.__wait_for_done()
+ # Read MII register DATA0_REG for bit 15:0
+ val = long(self.__read_mdio(self.DATA0_REG))
+ # Read MII register DATA1_REG for bit 31:16
+ val |= self.__read_mdio(self.DATA1_REG) << 16
+ # Read MII register DATA2_REG for bit 47:32
+ val |= self.__read_mdio(self.DATA2_REG) << 32
+ # Read MII register DATA3_REG for bit 63:48
+ val |= self.__read_mdio(self.DATA3_REG) << 48
+ return val
+
+ def write(self, page, reg, val, n_bytes):
+ self.__set_page(page)
+ # Write MII register DATA0_REG for bit 15:0
+ self.__write_mdio(self.DATA0_REG, val & 0xFFFF)
+ # Write MII register DATA1_REG for bit 31:16
+ self.__write_mdio(self.DATA1_REG, (val >> 16) & 0xFFFF)
+ # Write MII register DATA2_REG for bit 47:32
+ self.__write_mdio(self.DATA2_REG, (val >> 32) & 0xFFFF)
+ # Write MII register DATA3_REG for bit 63:48
+ self.__write_mdio(self.DATA3_REG, (val >> 48) & 0xFFFF)
+ # Write MII register IO_CTRL_REG:
+ # set "Operation Code as "00"
+ # set "Register Address" to bit 15:8
+ val = 0x00 | ((reg & 0xff) << 8)
+ self.__write_mdio(self.IO_CTRL_REG, val)
+ # Write MII register IO_CTRL_REG:
+ # set "Operation Code as "01"
+ # set "Register Address" to bit 15:8
+ val = 0x1 | ((reg & 0xff) << 8)
+ self.__write_mdio(self.IO_CTRL_REG, val)
+ self.__wait_for_done()
+
+
+class Bcm5396SPI:
+ '''The class to access BCM5396 through SPI interface'''
+ SPI_CMD = 'spi-bb'
+
+ READ_CMD = 0x60
+ WRITE_CMD = 0x61
+
+ SPI_STS_DIO = 0xF0
+ SPI_STS_REG = 0xFE
+ SPI_STS_REG_RACK = 0x1 << 5
+ SPI_STS_REG_SPIF = 0x1 << 7
+ PAGE_REG = 0xFF
+
+ def __init__(self, cs, clk, mosi, miso):
+ self.cs = cs
+ self.clk = clk
+ self.mosi = mosi
+ self.miso = miso
+ self.page = -1
+
+ def __bytes2val(self, values):
+ # LSB first, MSB last
+ pos = 0
+ result = 0L
+ for byte in values:
+ if type(byte) is str:
+ byte = int(byte, 16)
+ if byte > 255:
+ raise Exception('%s is not a byte in the list %s'\
+ % (byte, values))
+ result |= byte << pos
+ pos += 8
+ return result
+
+ def __val2bytes(self, value, n):
+ result = []
+ for _ in range(n):
+ result.append(value & 0xFF)
+ value >>= 8
+ if value > 0:
+ raise Exception('Value, %s, is too large for %s bytes'
+ % (value, n))
+ return result
+
+ def __io(self, bytes_to_write, to_read=0):
+ # TODO: check parameters
+ cmd = '%s -s %s -S low -c %s -o %s -i %s '\
+ % (self.SPI_CMD, self.cs, self.clk, self.mosi, self.miso)
+ if len(bytes_to_write):
+ write_cmd = '-w %s %s '\
+ % (len(bytes_to_write) * 8,
+ ' '.join([str(byte) for byte in bytes_to_write]))
+ else:
+ write_cmd = ''
+ if to_read:
+ # spi-bb will first return the exact number of bits used for
+ # writing. So, total number of bits to read should also include
+ # the number of bits written.
+ cmd += '-r %s ' % str((len(bytes_to_write) + to_read) * 8)
+ cmd += write_cmd
+ rc = 0L
+ out = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)\
+ .communicate()[0]
+ if to_read:
+ # need to parse the result
+ for line in out.split('\n'):
+ if not line.startswith('Read'):
+ continue
+ res = line.split(':')[1]
+ rc = self.__bytes2val(res.split()[len(bytes_to_write):])
+ break
+ return rc
+
+ def __set_page(self, page):
+ page &= 0xff
+ if self.page == page:
+ return
+ self.__io([self.WRITE_CMD, self.PAGE_REG, page])
+ self.page = page
+
+ def __read_spi_reg(self, reg):
+ reg &= 0xFF
+ return self.__io([self.READ_CMD, reg], 1)
+
+ def __read_spi_sts(self):
+ return self.__read_spi_reg(self.SPI_STS_REG)
+
+ def __read_spi_dio(self):
+ return self.__read_spi_reg(self.SPI_STS_DIO)
+
+ def read(self, page, reg, n_bytes):
+ '''Read a register value from a page.'''
+ if n_bytes > 8:
+ print('TODO to support reading more than 8 bytes')
+ return 0
+ if page > 0xff or reg > 0xff:
+ print('Page and register must be <= 255')
+ return 0
+ try:
+ self.__set_page(page)
+ self.__io([self.READ_CMD, reg], 1)
+ while True:
+ # check sts
+ sts = self.__read_spi_sts()
+ if sts & self.SPI_STS_REG_RACK:
+ break
+ bytes = []
+ for _ in range(n_bytes):
+ bytes.append(self.__read_spi_dio())
+ except Exception as e:
+ print(e)
+ return self.__bytes2val(bytes)
+
+ def write(self, page, reg, val, n_bytes):
+ '''Write a value as n bytes to a register on a page.'''
+ if page > 0xff or reg > 0xff:
+ print('Page and register must be <= 255')
+ return
+ bytes = self.__val2bytes(val, n_bytes)
+ if len(bytes) > 8:
+ print('TODO to support writing more than 8 bytes')
+ return
+ bytes = [self.WRITE_CMD, reg] + bytes
+ try:
+ self.__set_page(page)
+ self.__io(bytes)
+ except Exception as e:
+ print(e)
+
+class Bcm5396:
+ '''The class for BCM5396 Switch'''
+
+ MDIO_ACCESS = 0
+ SPI_ACCESS = 1
+
+ def __init__(self, access, **kwargs):
+ if access == self.MDIO_ACCESS:
+ self.access = Bcm5396MDIO(**kwargs)
+ else:
+ self.access = Bcm5396SPI(**kwargs)
+
+ def write(self, page, reg, value, 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)
+
+ def __add_remove_vlan(self, add, vid, untag, fwd, spt):
+ VLAN_PAGE = 0x5
+ CTRL_ADDR = 0x60
+ CTRL_START_DONE = (0x1 << 7)
+ VID_ADDR = 0x61
+ ENTRY_ADDR = 0x63
+
+ fwd_map = self.__ports2portmap(fwd)
+ untag_map = self.__ports2portmap(untag)
+
+ # mark it as write and stop the previous action
+ ctrl = 0
+ self.write(VLAN_PAGE, CTRL_ADDR, ctrl, 1)
+ # write entry
+ if (add):
+ entry = 0x1L | ((spt & 0x1F) << 1) \
+ | (fwd_map << 6) | (untag_map << 23)
+ else:
+ entry = 0x0L
+ self.write(VLAN_PAGE, ENTRY_ADDR, entry, 8)
+ # write vid as the index
+ self.write(VLAN_PAGE, VID_ADDR, vid & 0xFFF, 2)
+ # start the write
+ ctrl = CTRL_START_DONE
+ self.write(VLAN_PAGE, CTRL_ADDR, ctrl, 1)
+ while True:
+ ctrl = self.read(VLAN_PAGE, CTRL_ADDR, 1)
+ if not (ctrl & CTRL_START_DONE):
+ # done
+ break
+ time.sleep(0.010) # 10ms
+
+ def add_vlan(self, vid, untag, fwd, spt=0):
+ return self.__add_remove_vlan(True, vid, untag, fwd, spt)
+
+ def remove_vlan(self, vid):
+ return self.__add_remove_vlan(False, vid, [], [], 0)
+
+ def get_vlan(self, vid):
+ VLAN_PAGE = 0x5
+ CTRL_ADDR = 0x60
+ CTRL_START_DONE = (0x1 << 7)
+ CTRL_READ = 0x1
+ VID_ADDR = 0x61
+ ENTRY_ADDR = 0x63
+
+ # mark it as read and stop the previous action
+ ctrl = CTRL_READ
+ self.write(VLAN_PAGE, CTRL_ADDR, ctrl, 1)
+ # write the vid as the index
+ self.write(VLAN_PAGE, VID_ADDR, vid & 0xFFF, 2)
+ # start the read
+ ctrl = CTRL_READ|CTRL_START_DONE
+ self.write(VLAN_PAGE, CTRL_ADDR, ctrl, 1)
+ while True:
+ ctrl = self.read(VLAN_PAGE, CTRL_ADDR, 1)
+ if not (ctrl & CTRL_START_DONE):
+ # done
+ break
+ time.sleep(0.010) # 10ms
+ entry = self.read(VLAN_PAGE, ENTRY_ADDR, 8)
+ res = {}
+ res['valid'] = True if entry & 0x1 else False
+ res['spt'] = (entry >> 1) & 0x1f
+ res['fwd'] = self.__portmap2ports((entry >> 6) & 0x1ffff)
+ res['untag'] = self.__portmap2ports((entry >> 23) & 0x1ffff)
+ return res
+
+ def __portmap2ports(self, port_map):
+ return list(set([port if port_map & (0x1 << port) else None
+ for port in range (0, 17)])
+ - set([None]))
+
+ def __ports2portmap(self, ports):
+ port_map = 0
+ for port in ports:
+ port_map |= (0x1 << port)
+ return port_map & 0x1FFFF
+
+ def __parse_arl_result(self, vid, result):
+ is_bitset = lambda bit: True if result & (0x1 << bit) else False
+ if not is_bitset(3):
+ return None
+ res = {}
+ # parse vid first
+ res['vid'] = (vid >> 48) & 0xfff
+ mac_val = vid & 0xffffffffffffL
+ mac_list = []
+ for pos in range(5, -1, -1):
+ mac_list.append('{:02x}'.format((mac_val >> (pos * 8)) & 0xff))
+ res['mac'] = ':'.join(mac_list)
+ if mac_val & (0x1 << 40):
+ res['ports'] = self.__portmap2ports((result >> 6) & 0xffff)
+ else:
+ res['ports'] = [(result >> 6) & 0xf]
+ res['static'] = is_bitset(5)
+ res['age'] = is_bitset(4)
+ res['valid'] = is_bitset(3)
+ res['priority'] = result & 0x7
+ return res
+
+ def get_all_arls(self):
+ ARL_PAGE = 0x5
+ SEARCH_CTRL_ADDR = 0x30
+ SEARCH_CTRL_START_DONE = (0x1 << 7)
+ SEARCH_CTRL_SR_VALID = (0x1)
+
+ VID0_ADDR = 0x33
+ RESULT0_ADDR = 0x3B
+ VID1_ADDR = 0x40
+ RESULT1_ADDR = 0x48
+
+ all = []
+ # write START to search control
+ ctrl = SEARCH_CTRL_START_DONE
+ self.write(ARL_PAGE, SEARCH_CTRL_ADDR, ctrl, 1)
+ while True:
+ ctrl = self.read(ARL_PAGE, SEARCH_CTRL_ADDR, 1)
+ if not (ctrl & SEARCH_CTRL_START_DONE):
+ # Done
+ break
+ if not (ctrl & SEARCH_CTRL_SR_VALID):
+ # result is not ready, sleep and retry
+ time.sleep(0.010) # 10ms
+ continue
+ for vid_addr, result_addr in [[VID1_ADDR, RESULT1_ADDR],
+ [VID0_ADDR, RESULT0_ADDR]]:
+ vid = self.read(ARL_PAGE, vid_addr, 8)
+ result = self.read(ARL_PAGE, result_addr, 4)
+ one = self.__parse_arl_result(vid, result)
+ if one:
+ all.append(one)
+ return all
+
+ def vlan_ctrl(self, enable):
+ VLAN_CTRL_PAGE = 0x34
+ VLAN_CTRL0_REG = 0x0
+ VLAN_CTRL0_B_EN_1QVLAN = 0x1 << 7
+
+ ctrl = self.read(VLAN_CTRL_PAGE, VLAN_CTRL0_REG, 1)
+ need_write = False
+ if enable:
+ if not ctrl & VLAN_CTRL0_B_EN_1QVLAN:
+ need_write = True;
+ ctrl |= VLAN_CTRL0_B_EN_1QVLAN
+ else:
+ if ctrl & VLAN_CTRL0_B_EN_1QVLAN:
+ need_write = True;
+ ctrl &= (~VLAN_CTRL0_B_EN_1QVLAN) & 0xFF
+ if need_write:
+ self.write(VLAN_CTRL_PAGE, VLAN_CTRL0_REG, ctrl, 1)
+
+ def vlan_set_port_default(self, port, vid, pri=0):
+ VLAN_PORT_PAGE = 0x34
+ VLAN_PORT_REG_BASE = 0x10
+
+ if port < 0 or port > 16:
+ raise Exception('Invalid port number %s' % port)
+ if pri < 0 or pri > 7:
+ raise Exception('Invalid priority %s' % pri)
+ if vid < 0 or vid > 0xFFF:
+ raise Exception('Invalid VLAN %s' % vid)
+ reg = VLAN_PORT_REG_BASE + port * 2
+ ctrl = (pri << 13) | vid
+ self.write(VLAN_PORT_PAGE, reg, ctrl, 2)
+
+ def vlan_get_port_default(self, port):
+ VLAN_PORT_PAGE = 0x34
+ VLAN_PORT_REG_BASE = 0x10
+
+ if port < 0 or port > 16:
+ raise Exception('Invalid port number %s' % port)
+ reg = VLAN_PORT_REG_BASE + port * 2
+ val = self.read(VLAN_PORT_PAGE, reg, 2)
+ res = {}
+ res['priority'] = (val >> 13) & 0x7
+ res['vid'] = val & 0xFFF
+ return res
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/bcm5396_util.py b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/bcm5396_util.py
new file mode 100644
index 0000000..1496412
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/bcm5396_util.py
@@ -0,0 +1,260 @@
+#!/usr/bin/python
+# 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
+from bcm5396 import Bcm5396
+
+def auto_long(x):
+ return long(x, 0)
+
+def auto_int(x):
+ return int(x, 0)
+
+def get_bcm(args):
+ if args.spi:
+ return Bcm5396(Bcm5396.SPI_ACCESS, cs=args.cs, clk=args.clk,
+ mosi=args.mosi, miso=args.miso)
+ else:
+ return Bcm5396(Bcm5396.MDIO_ACCESS, mdc=args.mdc, mdio=args.mdio)
+
+
+def read_register(args):
+ bcm = get_bcm(args)
+ val = bcm.read(args.page, args.register, args.size)
+ print('Read from BCM5396 ({}:{}.{}): {}'
+ .format(hex(args.page), hex(args.register), args.size, hex(val)))
+
+def write_register(args):
+ bcm = get_bcm(args)
+ val = bcm.write(args.page, args.register, args.value, args.size)
+ print('Write to BCM5396 ({}.{}): {}'
+ .format(hex(args.page), hex(args.register), hex(args.value)))
+
+def register_parser(subparser):
+ reg_parser = subparser.add_parser('register', help='Register IO')
+ reg_sub = reg_parser.add_subparsers()
+
+ read_parser = reg_sub.add_parser('read', help='read switch register')
+ read_parser.set_defaults(func=read_register)
+ read_parser.add_argument('page', type=auto_int,
+ help='The page of the register')
+ read_parser.add_argument('register', type=auto_int,
+ help='The register to read from')
+ read_parser.add_argument('size', type=auto_int,
+ help='Number of bytes',
+ choices=range(1, 9))
+
+ write_parser = reg_sub.add_parser('write', help='write switch register')
+ write_parser.set_defaults(func=write_register)
+ write_parser.add_argument('page', type=auto_int,
+ help='The page oof the register')
+ write_parser.add_argument('register', type=auto_int,
+ help='The register to write to')
+ write_parser.add_argument('value', type=auto_long,
+ help='The value to write')
+ write_parser.add_argument('size', type=auto_int,
+ help='Number of bytes',
+ choices=range(1, 9))
+
+
+def dump_arl(args):
+ bcm = get_bcm(args)
+ arls = bcm.get_all_arls()
+ print('All ARLs are:')
+ for entry in arls:
+ print(entry)
+
+def arl_parser(subparser):
+ dump_parser = subparser.add_parser('arl', help='dump all ARL entries')
+ dump_parser.set_defaults(func=dump_arl)
+
+
+def __parse_port_list(parm):
+ '''Parse the port numbers to a list'''
+ if len(parm) == 0:
+ return []
+ ports=[]
+ for port in parm.split(','):
+ idx = port.find('-')
+ if idx == -1:
+ p = int(port)
+ if p < 0 or p > 15:
+ raise Exception('Invalid port number %s' % p)
+ # just one port
+ ports.append(p)
+ else:
+ start = int(port[:idx])
+ end = int(port[idx+1:])
+ if start > end or start < 0 or end > 15:
+ raise Exception('Invalid port range %s-%s' % (start, end))
+ ports.extend(range(start, end + 1))
+ return ports
+
+def enable_vlan(args):
+ bcm = get_bcm(args)
+ bcm.vlan_ctrl(True)
+ print('VLAN function is enabled.')
+
+def disable_vlan(args):
+ bcm = get_bcm(args)
+ bcm.vlan_ctrl(False)
+ print('VLAN function is disabled.')
+
+def add_vlan(args):
+ bcm = get_bcm(args)
+ vid = args.vid
+ fwd = sorted(__parse_port_list(args.fwd))
+ untag = sorted(__parse_port_list(args.untag))
+ spt = args.spt
+ # make sure untag is subset of fwd
+ if not set(untag).issubset(set(fwd)):
+ raise Exception('Some untagged ports, %s, are not part of forward ports'
+ % (set(untag) - set(fwd)))
+ bcm.add_vlan(vid, untag, fwd, spt)
+ print('Added VLAN: %s' % vid)
+ print('Ports in VLAN: %s' % sorted(fwd))
+ print('Ports without VLAN tag: %s' % sorted(untag))
+
+def remove_vlan(args):
+ bcm = get_bcm(args)
+ vid = args.vid
+ bcm.remove_vlan(vid)
+ print('Removed VLAN: %s' % vid)
+
+def show_vlan(args):
+ bcm = get_bcm(args)
+ vid = args.vid
+ vlan = bcm.get_vlan(vid)
+ if not vlan['valid']:
+ print('VLAN %s does not exist' % vid)
+ else:
+ print('VLAN: %s' % vid)
+ print('Spanning tree index: %s' % vlan['spt'])
+ print('Ports in VLAN: %s' % sorted(vlan['fwd']))
+ print('Untagged ports in VLAN: %s' % sorted(vlan['untag']))
+
+def set_port_vlan(args):
+ bcm = get_bcm(args)
+ bcm.vlan_set_port_default(args.port, args.vid, args.pri)
+ print('Set VLAN default for port: %s' % args.port)
+ print('Default VLAN: %s' % args.vid)
+ print('Default priority %s' % args.pri)
+
+def get_port_vlan(args):
+ bcm = get_bcm(args)
+ port = bcm.vlan_get_port_default(args.port)
+ print('Get VLAN default for port: %s' % args.port)
+ print('Default VLAN: %s' % port['vid'])
+ print('Default priority: %s' % port['priority'])
+
+def vlan_parser(subparser):
+ UNTAG_DEFAULT = ''
+ SPT_DEFAULT = 0
+ PRI_DEFAULT = 0
+
+ vlan_parser = subparser.add_parser('vlan', help='Manage vlan function')
+ vlan_sub = vlan_parser.add_subparsers()
+
+ add_parser = vlan_sub.add_parser('add', help='Add or modify a VLAN entry')
+ add_parser.add_argument('vid', type=int, help='The VLAN ID')
+ add_parser.add_argument('fwd', type=str,
+ help='Ports belonging to this VLAN. i.e. 1,4,5-8')
+ add_parser.add_argument('untag', type=str, default=UNTAG_DEFAULT, nargs='?',
+ help='Ports that do not add VLAN tag. i.e. 1,4,5-8'
+ ' (default: all ports are tagged)')
+ add_parser.add_argument('spt', type=int, default=SPT_DEFAULT, nargs='?',
+ help='Spanning tree index (default: %s)'
+ % SPT_DEFAULT)
+ add_parser.set_defaults(func=add_vlan)
+
+ remove_parser = vlan_sub.add_parser('remove', help='Remove a VLAN entry')
+ remove_parser.add_argument('vid', type=int, help='The VLAN ID')
+ remove_parser.set_defaults(func=remove_vlan)
+
+ show_parser = vlan_sub.add_parser('show', help='Show a VLAN entry')
+ show_parser.add_argument('vid', type=int, help='The VLAN ID')
+ show_parser.set_defaults(func=show_vlan)
+
+ enable_parser = vlan_sub.add_parser('enable', help='Enable VLAN function')
+ enable_parser.set_defaults(func=enable_vlan)
+
+ disable_parser = vlan_sub.add_parser('disable', help='Enable VLAN function')
+ disable_parser.set_defaults(func=disable_vlan)
+
+ port_parser = vlan_sub.add_parser('port',
+ help='Set/Get VLAN default for a port')
+ port_sub = port_parser.add_subparsers()
+ set_port = port_sub.add_parser('set', help='Set VLAN default for a port')
+ set_port.add_argument('port', type=int, help='The port number (0..16)')
+ set_port.add_argument('vid', type=int,
+ help='The default VLAN for this port')
+ set_port.add_argument('pri', type=int, default=PRI_DEFAULT, nargs='?',
+ help='The default priority for this port '
+ '(default: %s)' % PRI_DEFAULT)
+ set_port.set_defaults(func=set_port_vlan)
+
+ get_port = port_sub.add_parser('get', help='Get VLAN default for a port')
+ get_port.add_argument('port', type=int, help='The port number (0..16)')
+ get_port.set_defaults(func=get_port_vlan)
+
+def access_parser(ap):
+ SPI_CS_DEFAULT = 68
+ SPI_CLK_DEFAULT = 69
+ SPI_MOSI_DEFAULT = 70
+ SPI_MISO_DEFAULT = 71
+
+ MDIO_MDC_DEFAULT = 6
+ MDIO_MDIO_DEFAULT = 7
+
+ spi_group = ap.add_argument_group('SPI Access')
+ spi_group.add_argument('--spi', action='store_true',
+ help='Access through SPI.')
+ spi_group.add_argument('--cs', type=int, default=SPI_CS_DEFAULT,
+ help='The GPIO number for SPI CS pin (default: %s)'
+ % SPI_CS_DEFAULT)
+ spi_group.add_argument('--clk', type=int, default=SPI_CLK_DEFAULT,
+ help='The GPIO number for SPI CLK pin (default: %s)'
+ % SPI_CLK_DEFAULT)
+ spi_group.add_argument('--mosi', type=int, default=SPI_MOSI_DEFAULT,
+ help='The GPIO number for SPI MOSI pin (default: %s)'
+ % SPI_MOSI_DEFAULT)
+ spi_group.add_argument('--miso', type=int, default=SPI_MISO_DEFAULT,
+ help='The GPIO number for SPI MISO pin (default: %s)'
+ % SPI_MISO_DEFAULT)
+ mdio_group = ap.add_argument_group('MDIO Access (default)')
+ mdio_group.add_argument('--mdc', type=int, default=MDIO_MDC_DEFAULT,
+ help='The GPIO number for MDC pin (default: %s)'
+ % MDIO_MDC_DEFAULT)
+ mdio_group.add_argument('--mdio', type=int, default=MDIO_MDIO_DEFAULT,
+ help='The GPIO number for MDIO pin (default: %s)'
+ % MDIO_MDIO_DEFAULT)
+ return ap
+
+
+if __name__ == '__main__':
+ ap = ArgumentParser()
+ access_parser(ap)
+
+ subparsers = ap.add_subparsers()
+ register_parser(subparsers)
+ arl_parser(subparsers)
+ vlan_parser(subparsers)
+ args = ap.parse_args()
+
+ args.func(args)
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/bic-util/Makefile b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/bic-util/Makefile
new file mode 100644
index 0000000..9c046be
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/bic-util/Makefile
@@ -0,0 +1,10 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+all: bic-util
+
+bic-util: bic-util.c
+ $(CC) -pthread -lipmi -lipmb -lbic -std=c99 -o $@ $^ $(LDFLAGS)
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o bic-util
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/bic-util/bic-util.c b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/bic-util/bic-util.c
new file mode 100644
index 0000000..4a8966d
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/bic-util/bic-util.c
@@ -0,0 +1,384 @@
+/*
+ * bic-util
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <syslog.h>
+#include <stdint.h>
+#include <pthread.h>
+#include <facebook/bic.h>
+#include <openbmc/ipmi.h>
+
+#define LAST_RECORD_ID 0xFFFF
+#define MAX_SENSOR_NUM 0xFF
+#define BYTES_ENTIRE_RECORD 0xFF
+
+// Test to Get device ID
+static void
+util_get_device_id(uint8_t slot_id) {
+ int ret;
+ ipmi_dev_id_t id = {0};
+
+ ret = bic_get_dev_id(slot_id, &id);
+ if (ret) {
+ printf("util_get_device_id: bic_get_dev_id returns %d\n", ret);
+ return;
+ }
+
+ // Print response
+ printf("Device ID: 0x%X\n", id.dev_id);
+ printf("Device Revision: 0x%X\n", id.dev_rev);
+ printf("Firmware Revision: 0x%X:0x%X\n", id.fw_rev1, id.fw_rev2);
+ printf("IPMI Version: 0x%X\n", id.ipmi_ver);
+ printf("Device Support: 0x%X\n", id.dev_support);
+ printf("Manufacturer ID: 0x%X:0x%X:0x%X\n", id.mfg_id[2], id.mfg_id[1], id.mfg_id[0]);
+ printf("Product ID: 0x%X:0x%X\n", id.prod_id[1], id.prod_id[0]);
+ printf("Aux. FW Rev: 0x%X:0x%X:0x%X:0x%X\n", id.aux_fw_rev[0], id.aux_fw_rev[1],id.aux_fw_rev[2],id.aux_fw_rev[3]);
+}
+
+// Tests for reading GPIO values and configuration
+static void
+util_get_gpio(uint8_t slot_id) {
+ int ret;
+ bic_gpio_t gpio = {0};
+
+ ret = bic_get_gpio(slot_id, &gpio);
+ if (ret) {
+ printf("util_get_gpio: bic_get_gpio returns %d\n", ret);
+ return;
+ }
+
+ bic_gpio_u *t = (bic_gpio_u*) &gpio;
+
+ // Print response
+ printf("PWRGOOD_CPU: %d\n", t->bits.pwrgood_cpu);
+ printf("PWRGOOD_PCH_PWROK: %d\n", t->bits.pwrgd_pch_pwrok);
+ printf("PVDDR_VRHOT_N: %d\n", t->bits.pvddr_vrhot_n);
+ printf("PVCCIN_VRHOT_N: %d\n", t->bits.pvccin_vrhot_n);
+ printf("FM_FAST_PROCHOT_N: %d\n", t->bits.fm_fast_prochot_n);
+ printf("PCHHOT_CPU_N: %d\n", t->bits.pchhot_cpu_n);
+ printf("FM_CPLD_CPU_DIMM_EVENT_C0_N: %d\n", t->bits.fm_cpld_cpu_dimm_event_c0_n);
+ printf("FM_CPLD_BDXDE_THERMTRIP_N: %d\n", t->bits.fm_cpld_bdxde_thermtrip_n);
+ printf("THERMTRIP_PCH_N: %d\n", t->bits.thermtrip_pch_n);
+ printf("FM_CPLD_FIVR_FAULT: %d\n", t->bits.fm_cpld_fivr_fault);
+ printf("FM_BDXDE_CATERR_LVT3_N: %d\n", t->bits.fm_bdxde_caterr_lvt3_n);
+ printf("FM_BDXDE_ERR_LVT3_N: %d\n", t->bits.fm_bdxde_err_lvt3_n);
+ printf("SLP_S4_N: %d\n", t->bits.slp_s4_n);
+ printf("FM_NMI_EVENT_BMC_N: %d\n", t->bits.fm_nmi_event_bmc_n);
+ printf("FM_SMI_BMC_N: %d\n", t->bits.fm_smi_bmc_n);
+ printf("RST_PLTRST_BMC_N: %d\n", t->bits.rst_pltrst_bmc_n);
+ printf("FP_RST_BTN_BUF_N: %d\n", t->bits.fp_rst_btn_buf_n);
+ printf("BMC_RST_BTN_OUT_N: %d\n", t->bits.bmc_rst_btn_out_n);
+ printf("FM_BDE_POST_CMPLT_N: %d\n", t->bits.fm_bde_post_cmplt_n);
+ printf("FM_BDXDE_SLP3_N: %d\n", t->bits.fm_bdxde_slp3_n);
+ printf("FM_PWR_LED_N: %d\n", t->bits.fm_pwr_led_n);
+ printf("PWRGD_PVCCIN: %d\n", t->bits.pwrgd_pvccin);
+ printf("SVR_ID: %d\n", t->bits.svr_id);
+ printf("BMC_READY_N: %d\n", t->bits.bmc_ready_n);
+ printf("BMC_COM_SW_N: %d\n", t->bits.bmc_com_sw_n);
+ printf("rsvd: %d\n", t->bits.rsvd);
+}
+
+static void
+util_get_gpio_config(uint8_t slot_id) {
+ int ret;
+ int i;
+ bic_gpio_config_t gpio_config = {0};
+ bic_gpio_config_u *t = (bic_gpio_config_u *) &gpio_config;
+
+ // Read configuration of all bits
+ for (i = 0; i < MAX_GPIO_PINS; i++) {
+ ret = bic_get_gpio_config(slot_id, i, &gpio_config);
+ if (ret == -1) {
+ continue;
+ }
+
+ printf("gpio_config for pin#%d:\n", i);
+ printf("Direction: %s", t->bits.dir?"Output":"Input");
+ printf("Interrupt Enabled?: %s", t->bits.ie?"Enabled":"Disabled");
+ printf("Trigger Type: %s", t->bits.edge?"Level":"Edge");
+ if (t->bits.trig == 0x0) {
+ printf("Trigger Edge: %s\n", "Falling Edge");
+ } else if (t->bits.trig == 0x1) {
+ printf("Trigger Edge: %s\n", "Falling Edge");
+ } else if (t->bits.trig == 0x2) {
+ printf("Trigger Edge: %s\n", "Both Edges");
+ } else {
+ printf("Trigger Edge: %s\n", "Reserved");
+ }
+ }
+}
+
+static void
+util_get_config(uint8_t slot_id) {
+ int ret;
+ int i;
+ bic_config_t config = {0};
+ bic_config_u *t = (bic_config_u *) &config;
+
+ ret = bic_get_config(slot_id, &config);
+ if (ret) {
+ printf("util_get_config: bic_get_config failed\n");
+ return;
+ }
+
+ printf("SoL Enabled?: %s", t->bits.sol? "Enabled" : "Disabled");
+ printf("POST Enabled?: %s", t->bits.post? "Enabled" : "Disabled");
+ printf("KCS Enabled?: %s", t->bits.kcs? "Enabled" : "Disabled");
+ printf("IPMB Enabled?: %s", t->bits.ipmb? "Enabled" : "Disabled");
+}
+
+static void
+util_set_config(uint8_t slot_id, uint8_t status) {
+
+}
+
+// Test to get the POST buffer
+static void
+util_get_post_buf(uint8_t slot_id) {
+ int ret;
+ uint8_t buf[MAX_IPMB_RES_LEN] = {0x0};
+ uint8_t len;
+ int i;
+
+ ret = bic_get_post_buf(slot_id, buf, &len);
+ if (ret) {
+ printf("util_get_post_buf: bic_get_post_buf returns %d\n", ret);
+ return;
+ }
+
+ printf("util_get_post_buf: returns %d bytes\n", len);
+ for (i = 0; i < len; i++) {
+ printf("0x%X:", buf[i]);
+ }
+ printf("\n");
+}
+
+// Tests to read FRUID of Monolake Server
+static void
+util_get_fruid_info(uint8_t slot_id) {
+ int ret;
+ int i;
+
+ ipmi_fruid_info_t info = {0};
+
+ ret = bic_get_fruid_info(slot_id, 0, &info);
+ if (ret) {
+ printf("util_get_fruid_info: bic_get_fruid_info returns %d\n", ret);
+ return;
+ }
+
+ printf("FRUID info for 1S Slot..\n");
+
+ printf("FRUID Size: %d\n", (info.size_msb << 8) + (info.size_lsb));
+ printf("Accessed as : %s\n", (info.bytes_words)?"Words":"Bytes");
+}
+
+static void
+util_read_fruid(uint8_t slot_id) {
+ int ret;
+ int i;
+
+ char path[64] = {0};
+ sprintf(path, "/tmp/fruid_slot%d.bin", slot_id);
+
+ ret = bic_read_fruid(slot_id, 0, path);
+ if (ret) {
+ printf("util_read_fruid: bic_read_fruid returns %d\n", ret);
+ return;
+ }
+}
+
+// Tests to read SEL from Monolake Server
+static void
+util_get_sel_info(uint8_t slot_id) {
+ int ret;
+
+ ipmi_sel_sdr_info_t info;
+
+ ret = bic_get_sel_info(slot_id, &info);
+ if (ret) {
+ printf("util_get_sel_info:bic_get_sel_info returns %d\n", ret);
+ return;
+ }
+
+ printf("SEL info for 1S Slot is..\n");
+
+ printf("version: 0x%X\n", info.ver);
+ printf("Record Count: 0x%X\n", info.rec_count);
+ printf("Free Space: 0x%X\n", info.free_space);
+ printf("Recent Add TS: 0x%X:0x%X:0x%X:0x%X\n", info.add_ts[3], info.add_ts[2], info.add_ts[1], info.add_ts[0]);
+ printf("Recent Erase TS: 0x%X:0x%X:0x%X:0x%X\n", info.erase_ts[3], info.erase_ts[2], info.erase_ts[1], info.erase_ts[0]);
+ printf("Operation Support: 0x%X\n", info.oper);
+}
+
+static void
+util_get_sel(uint8_t slot_id) {
+ int ret;
+ int i;
+ uint16_t rsv;
+ uint8_t rlen;
+ uint8_t rbuf[MAX_IPMB_RES_LEN] = {0};
+
+ ipmi_sel_sdr_req_t req;
+ ipmi_sel_sdr_res_t *res = (ipmi_sel_sdr_res_t *) rbuf;
+
+ req.rsv_id = 0;
+ req.rec_id = 0;
+ req.offset = 0;
+ req.nbytes = BYTES_ENTIRE_RECORD;
+
+ while (1) {
+ ret = bic_get_sel(slot_id, &req, res, &rlen);
+ if (ret) {
+ printf("util_get_sel:bic_get_sel returns %d\n", ret);
+ continue;
+ }
+
+ printf("SEL for rec_id %d\n", req.rec_id);
+ printf("Next Record ID is %d\n", res->next_rec_id);
+ printf("Record contents are..\n");
+ for (i = 0; i < rlen-2; i++) { // First 2 bytes are next_rec_id
+ printf("0x%X:", res->data[i]);
+ }
+ printf("\n");
+
+ req.rec_id = res->next_rec_id;
+ if (req.rec_id == LAST_RECORD_ID) {
+ printf("This record is LAST record\n");
+ break;
+ }
+ }
+}
+
+// Tests to read SDR records from Monolake Servers
+static void
+util_get_sdr_info(uint8_t slot_id) {
+ int ret;
+
+ ipmi_sel_sdr_info_t info;
+
+ ret = bic_get_sdr_info(slot_id, &info);
+ if (ret) {
+ printf("util_get_sdr_info:bic_get_sdr_info returns %d\n", ret);
+ return;
+ }
+
+ printf("SDR info for 1S Slot is..\n");
+
+ printf("version: 0x%X\n", info.ver);
+ printf("Record Count: 0x%X\n", info.rec_count);
+ printf("Free Space: 0x%X\n", info.free_space);
+ printf("Recent Add TS: 0x%X:0x%X:0x%X:0x%X\n", info.add_ts[3], info.add_ts[2], info.add_ts[1], info.add_ts[0]);
+ printf("Recent Erase TS: 0x%X:0x%X:0x%X:0x%X\n", info.erase_ts[3], info.erase_ts[2], info.erase_ts[1], info.erase_ts[0]);
+ printf("Operation Support: 0x%X\n", info.oper);
+}
+
+static void
+util_get_sdr(uint8_t slot_id) {
+ int ret;
+ int i;
+ uint16_t rsv;
+ uint8_t rlen;
+ uint8_t rbuf[MAX_IPMB_RES_LEN] = {0};
+
+ ipmi_sel_sdr_req_t req;
+ ipmi_sel_sdr_res_t *res = (ipmi_sel_sdr_res_t *) rbuf;
+
+ req.rsv_id = 0;
+ req.rec_id = 0;
+ req.offset = 0;
+ req.nbytes = BYTES_ENTIRE_RECORD;
+
+ while (1) {
+ ret = bic_get_sdr(slot_id, &req, res, &rlen);
+ if (ret) {
+ printf("util_get_sdr:bic_get_sdr returns %d\n", ret);
+ continue;
+ }
+
+ sdr_full_t *sdr = res->data;
+
+ printf("type: %d, ", sdr->type);
+ printf("sensor_num: %d, ", sdr->sensor_num);
+ printf("sensor_type: %d, ", sdr->sensor_type);
+ printf("evt_read_type: %d, ", sdr->evt_read_type);
+ printf("m_val: %d, ", sdr->m_val);
+ printf("m_tolerance: %d, ", sdr->m_tolerance);
+ printf("b_val: %d, ", sdr->b_val);
+ printf("b_accuracy: %d, ", sdr->b_accuracy);
+ printf("accuracy_dir: %d, ", sdr->accuracy_dir);
+ printf("rb_exp: %d,\n", sdr->rb_exp);
+
+ req.rec_id = res->next_rec_id;
+ if (req.rec_id == LAST_RECORD_ID) {
+ printf("This record is LAST record\n");
+ break;
+ }
+ }
+}
+
+// Test to read all Sensors from Monolake Server
+static void
+util_read_sensor(uint8_t slot_id) {
+ int ret;
+ int i;
+ ipmi_sensor_reading_t sensor;
+
+ for (i = 0; i < MAX_SENSOR_NUM; i++) {
+ ret = bic_read_sensor(slot_id, i, &sensor);
+ if (ret) {
+ continue;
+ }
+
+ printf("sensor#%d: value: 0x%X, flags: 0x%X, status: 0x%X, ext_status: 0x%X\n",
+ i, sensor.value, sensor.flags, sensor.status, sensor.ext_status);
+ }
+}
+
+// TODO: Make it as User selectable tests to run
+int
+main(int argc, char **argv) {
+
+ uint8_t slot_id;
+
+ slot_id = atoi(argv[1]);
+
+ util_get_device_id(slot_id);
+
+ util_get_gpio(slot_id);
+ util_get_gpio_config(slot_id);
+
+ util_get_config(slot_id);
+
+ util_get_post_buf(slot_id);
+
+ util_get_fruid_info(slot_id);
+ util_read_fruid(slot_id);
+
+ util_get_sel_info(slot_id);
+ util_get_sel(slot_id);
+
+ util_get_sdr_info(slot_id);
+ util_get_sdr(slot_id);
+ util_read_sensor(slot_id);
+}
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/create_vlan_intf b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/create_vlan_intf
new file mode 100644
index 0000000..2cf7a9a
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/create_vlan_intf
@@ -0,0 +1,37 @@
+#!/bin/bash
+#
+# 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
+#
+
+# only care about 'eth0' and 'oob' intf
+[ "$IFACE" != "eth0" ] && [ "$IFACE" != "oob" ] && exit 0
+
+. /usr/local/fbpackages/utils/ast-functions
+
+board=$(wedge_board_type)
+
+[ "$board" = "WEDGE" ] && exit 0
+
+vlan=4088
+intf="${IFACE}.${vlan}"
+slot=$(wedge_slot_id $board)
+
+vconfig add $IFACE $vlan
+ifconfig $intf up "fe80::$(printf "%x" $slot):1/64"
+
+exit 0
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/eth0_mac_fixup.sh b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/eth0_mac_fixup.sh
new file mode 100644
index 0000000..1cdbcb6
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/eth0_mac_fixup.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+#
+# 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: eth0_mac_fixup.sh
+# Required-Start:
+# Required-Stop:
+# Default-Start: S
+# Default-Stop:
+# Short-Description: Fixup the MAC address for eth0 based on wedge EEPROM
+### END INIT INFO
+
+PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
+
+mac=$(weutil 2>/dev/null | grep '^Local MAC' 2>/dev/null | cut -d' ' -f3 2>/dev/null)
+
+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
+fi
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/fcswitcher.sh b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/fcswitcher.sh
new file mode 100755
index 0000000..53e24f3
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/fcswitcher.sh
@@ -0,0 +1,83 @@
+#! /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: usbcons
+# Required-Start:
+# Required-Stop:
+# Default-Start: S
+# Default-Stop: 0 6
+# Short-Description: Creates a virtual USB serial device and starts a console
+# on it.
+#
+### END INIT INFO
+
+PATH=/sbin:/bin:/usr/sbin:/usr/bin
+NAME="FC Switcher"
+DESC="FC Failover Daemon"
+
+# source function library
+. /etc/init.d/functions
+
+. /usr/local/fbpackages/utils/ast-functions
+
+STOPPER=
+ACTION="$1"
+
+case "$ACTION" in
+ start)
+ if [ "$(wedge_board_type)" = "LC" ]; then
+ # Ability to prevent this from starting by editing cmdline in u-boot.
+ # Keeping this here until I get gadget switching working properly. (t4906522)
+ /usr/local/bin/watch-fc.sh > /dev/null 2>&1 &
+ echo "$NAME."
+ else
+ echo 'skipping watch-fc.sh: only necessary on six-pack line cards.'
+ fi
+ ;;
+ stop)
+ echo -n "Stopping $DESC: "
+ killall watch-fc.sh
+ echo "$NAME."
+ ;;
+ restart|force-reload)
+ echo -n "Restarting $DESC: "
+ killall watch-fc.sh
+ if [ "$(wedge_board_type)" = "LC" ]; then
+ sleep 1
+ /usr/local/bin/watch-fc.sh > /dev/null 2>&1 &
+ echo "$NAME."
+ else
+ echo 'skipping watch-fc.sh: only necessary on six-pack line cards.'
+ fi
+ ;;
+ status)
+ status watch-fc.sh
+ 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-yosemite/recipes-yosemite/fbutils/files/mdio.py b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/mdio.py
new file mode 100755
index 0000000..aa7d4bf
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/mdio.py
@@ -0,0 +1,124 @@
+#!/usr/bin/python
+#
+# 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
+#
+
+from argparse import ArgumentParser
+import subprocess
+import time
+
+IO_BASE = [ 0x1e660000, 0x1e680000 ]
+PHYCR_REG_OFFSET = 0x60
+PHYCR_READ_BIT = 0x1 << 26
+PHYCR_WRITE_BIT = 0x1 << 27
+phycr_reg = lambda mac: IO_BASE[mac - 1] + PHYCR_REG_OFFSET
+PHYDATA_REG_OFFSET = 0x64
+phydata_reg = lambda mac: IO_BASE[mac - 1] + PHYDATA_REG_OFFSET
+
+
+devmem_read_cmd = lambda reg: [ 'devmem', hex(reg) ]
+devmem_write_cmd = lambda reg, val: [ 'devmem', hex(reg), '32', hex(val)]
+
+
+def devmem_read(reg):
+ cmd = devmem_read_cmd(reg)
+ #print('Cmd: {}'.format(cmd))
+ out = subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]
+ return int(out, 0)
+
+
+def devmem_write(reg, val):
+ cmd = devmem_write_cmd(reg, val)
+ #print('Cmd: {}'.format(cmd))
+ subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]
+
+
+def wait_for_mdio_done(args):
+ reg = phycr_reg(args.mac)
+ while devmem_read(reg) & (PHYCR_READ_BIT|PHYCR_WRITE_BIT):
+ time.sleep(0.010) # 10ms
+
+
+def read_mdio(args):
+ reg = phycr_reg(args.mac)
+ ctrl = devmem_read(reg)
+ ctrl &= 0x3000003f
+ ctrl |= (args.phy & 0x1F) << 16
+ ctrl |= (args.register & 0x1F) << 21
+ ctrl |= PHYCR_READ_BIT
+ devmem_write(reg, ctrl)
+ wait_for_mdio_done(args)
+ val = devmem_read(phydata_reg(args.mac)) >> 16
+ print('Read from PHY ({}.{}): {}'
+ .format(hex(args.phy), hex(args.register), hex(val)))
+
+
+def write_mdio(args):
+ ctrl_reg = phycr_reg(args.mac)
+ ctrl = devmem_read(ctrl_reg)
+ ctrl &= 0x3000003f
+ ctrl |= (args.phy & 0x1F) << 16
+ ctrl |= (args.register & 0x1F) << 21
+ ctrl |= PHYCR_WRITE_BIT
+ data_reg = phydata_reg(args.mac)
+ # write data first
+ devmem_write(data_reg, args.value)
+ # then ctrl
+ devmem_write(ctrl_reg, ctrl)
+ wait_for_mdio_done(args)
+ print('Write to PHY ({}.{}): {}'
+ .format(hex(args.phy), hex(args.register), hex(args.value)))
+
+
+def auto_int(x):
+ return int(x, 0)
+
+if __name__ == '__main__':
+ ap = ArgumentParser()
+ ap.add_argument('--mac', '-m', type=int, default=2,
+ help='The MAC')
+ ap.add_argument('--phy', '-p', type=auto_int, default=0x1f,
+ help='The PHY address')
+
+ subparsers = ap.add_subparsers()
+
+ read_parser = subparsers.add_parser('read',
+ help='read MDIO')
+ read_parser.set_defaults(func=read_mdio)
+ read_parser.add_argument('register', type=auto_int,
+ help='The register to read from')
+
+ write_parser = subparsers.add_parser('write',
+ help='write MDIO')
+ write_parser.set_defaults(func=write_mdio)
+ write_parser.add_argument('register', type=auto_int,
+ help='The register to write to')
+ write_parser.add_argument('value', type=auto_int,
+ help='The value to write to')
+
+ args = ap.parse_args()
+
+ if args.mac != 2 and args.mac != 1:
+ print("MAC can only be either 1 or 2.")
+ exit(-1)
+
+ if args.phy > 0x1f:
+ printf("PHY address must be smaller than 0x1f.")
+ exit(-2)
+
+ args.func(args)
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/mount_data0.sh b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/mount_data0.sh
new file mode 100755
index 0000000..6986be5
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/mount_data0.sh
@@ -0,0 +1,61 @@
+#!/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: mount_data0
+# Required-Start: mountvirtfs
+# Required-Stop:
+# Default-Start: S
+# Default-Stop:
+# Short-Description: Mount data0 partition from flash chip.
+# Description:
+### END INIT INFO
+
+. /etc/default/rcS
+
+# Find out which device maps to 'data0' on mtd
+# Note: /proc/mtd lists partitions using mtdX, where X is a number,
+# but we mount using /dev/mtdblockX. We'll do some magic here
+# to get the mtdX (char device) and mtdblockX (block device)
+# names.
+MOUNT_POINT="/mnt/data"
+DATA_CHAR_DEV=$(cat /proc/mtd | awk '{ if ($4 == "\"data0\"") print $1 }' |
+ cut -d ':' -f 1 | awk '{ print "/dev/" $1 }')
+if [ -z "$DATA_CHAR_DEV" ]
+then
+ echo "No data0 partition found. Not mounting anything to $MOUNT_POINT."
+else
+ DEVICE_ID=$(echo $DATA_CHAR_DEV | tail -c 2)
+ DATA_BLOCK_DEV=${DATA_CHAR_DEV/mtd/mtdblock}
+
+ echo "data0 partition found on $DATA_BLOCK_DEV; mounting to $MOUNT_POINT."
+ mount -t jffs2 $DATA_BLOCK_DEV $MOUNT_POINT
+
+ # if the mount failed, format the partition and remount
+ if [ $? -ne 0 ]
+ then
+ echo "Mount failed; formatting $DATA_BLOCK_DEV and remounting."
+ flash_eraseall $DATA_CHAR_DEV
+ mount -t jffs2 $DATA_BLOCK_DEV $MOUNT_POINT
+ fi
+fi
+
+: exit 0
+
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/post_led.sh b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/post_led.sh
new file mode 100644
index 0000000..c23349f
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/post_led.sh
@@ -0,0 +1,105 @@
+#!/bin/sh
+#
+# 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
+#
+
+usage() {
+ echo "Displays values onto the debug header LEDs."
+ echo "Hex and decimal accepted."
+ echo "Usage: $0 <value>"
+}
+
+. /usr/local/fbpackages/utils/ast-functions
+
+# Function to set the less significant hex digit
+display_lower() {
+ local bit0=$(expr $1 % 2)
+ local bit1=$(expr $1 / 2 % 2)
+ local bit2=$(expr $1 / 4 % 2)
+ local bit3=$(expr $1 / 8 % 2)
+
+ # Set the pins to the correct operating mode.
+ # The relevant pins are GPIOG[0...3].
+ # For GPIO bank G, SCU84[0..3] must be 0.
+ devmem_clear_bit $(scu_addr 84) 0
+ devmem_clear_bit $(scu_addr 84) 1
+ devmem_clear_bit $(scu_addr 84) 2
+ devmem_clear_bit $(scu_addr 84) 3
+
+ # Now set the GPIOs to the right binary values
+ gpio_set 48 $bit0
+ gpio_set 49 $bit1
+ gpio_set 50 $bit2
+ gpio_set 51 $bit3
+}
+
+# Function to set the more significant hex digit
+display_upper() {
+ local bit0=$(expr $1 % 2)
+ local bit1=$(expr $1 / 2 % 2)
+ local bit2=$(expr $1 / 4 % 2)
+ local bit3=$(expr $1 / 8 % 2)
+
+ # Set the pins to the correct operating mode.
+ # The relevant pins are GPIOB[4...7].
+ # GPIOB4: SCU80[12] = 0 and Strap[14] = 0
+ # GPIOB5: SCU80[13] = 0
+ # GPIOB6: SCU80[14] = 0
+ # GPIOB7: SCU80[15] = 0
+ devmem_clear_bit $(scu_addr 70) 14
+ devmem_clear_bit $(scu_addr 80) 12
+ devmem_clear_bit $(scu_addr 80) 13
+ devmem_clear_bit $(scu_addr 80) 14
+ devmem_clear_bit $(scu_addr 80) 15
+
+ gpio_set 12 $bit0
+ gpio_set 13 $bit1
+ gpio_set 14 $bit2
+ gpio_set 15 $bit3
+}
+
+# Check number of parameters
+if [ $# -ne 1 ]
+then
+ usage
+ exit 1
+fi
+
+# Make sure input is actually numeric
+DEC_VALUE=$(printf "%d" $1 2>/dev/null)
+if [ $? -eq 1 ]
+then
+ echo "Unable to parse input as numeric value."
+ exit 1
+fi
+
+# Make sure input is within proper range
+if [ $DEC_VALUE -lt 0 ] || [ $DEC_VALUE -gt 255 ]
+then
+ echo "Value $DEC_VALUE is outside of displayable range 0 - 0xff (255)."
+ exit 1
+fi
+
+# Get upper/lower decimal values
+LOWER_DEC_VALUE=$(expr $DEC_VALUE % 16)
+UPPER_DEC_VALUE=$(expr $DEC_VALUE / 16)
+
+# Display the results
+display_lower $LOWER_DEC_VALUE
+display_upper $UPPER_DEC_VALUE
+
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/power-on.sh b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/power-on.sh
new file mode 100644
index 0000000..3a9ce06
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/power-on.sh
@@ -0,0 +1,99 @@
+#!/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: power-on
+# Required-Start:
+# Required-Stop:
+# Default-Start: S
+# Default-Stop:
+# Short-Description: Power on Server
+### END INIT INFO
+. /usr/local/fbpackages/utils/ast-functions
+
+PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
+
+# Disable Watch Dog Timer
+/usr/local/bin/watchdog_ctrl.sh off
+
+
+KEYDIR=/mnt/data/kv_store
+DEF_PWR_ON=1
+TO_PWR_ON=
+
+check_por_config()
+{
+
+ TO_PWR_ON=-1
+
+ # Check if the file/key doesn't exist
+ if [ ! -f "${KEYDIR}/slot${1}_por_cfg" ]; then
+ TO_PWR_ON=$DEF_PWR_ON
+ else
+ POR=`cat ${KEYDIR}/slot${1}_por_cfg`
+
+ # Case ON
+ if [ $POR == "on" ]; then
+ TO_PWR_ON=1;
+
+ # Case OFF
+ elif [ $POR == "off" ]; then
+ TO_PWR_ON=0;
+
+ # Case LPS
+ elif [ $POR == "lps" ]; then
+
+ # Check if the file/key doesn't exist
+ if [ ! -f "${KEYDIR}/pwr_server${1}_last_state" ]; then
+ TO_PWR_ON=$DEF_PWR_ON
+ else
+ LS=`cat ${KEYDIR}/pwr_server${1}_last_state`
+ if [ $LS == "on" ]; then
+ TO_PWR_ON=1;
+ elif [ $LS == "off" ]; then
+ TO_PWR_ON=0;
+ fi
+ fi
+ fi
+ fi
+}
+
+# Check whether it is fresh power on reset
+if [ $(is_bmc_por) -eq 1 ]; then
+
+ check_por_config 1
+ if [ $TO_PWR_ON -eq 1 ] && [ $(is_server_prsnt 1) == "1" ] ; then
+ power-util slot1 on
+ fi
+
+ check_por_config 2
+ if [ $TO_PWR_ON -eq 1 ] && [ $(is_server_prsnt 2) == "1" ] ; then
+ power-util slot2 on
+ fi
+
+ check_por_config 3
+ if [ $TO_PWR_ON -eq 1 ] && [ $(is_server_prsnt 3) == "1" ] ; then
+ power-util slot3 on
+ fi
+
+ check_por_config 4
+ if [ $TO_PWR_ON -eq 1 ] && [ $(is_server_prsnt 4) == "1" ] ; then
+ power-util slot4 on
+ fi
+fi
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/power_led.sh b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/power_led.sh
new file mode 100755
index 0000000..2f9bb6a
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/power_led.sh
@@ -0,0 +1,58 @@
+#!/bin/bash
+#
+# 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
+#
+
+usage() {
+ echo "Usage: $1 <slot#> <on | off>"
+ exit -1
+}
+
+. /usr/local/fbpackages/utils/ast-functions
+
+PATH=/sbin:/bin:/usr/sbin:/usr/bin
+
+set -e
+
+if [ $# != 2 ]; then
+ usage $0
+fi
+
+# Slot#1: GPIOM1(97),Slot#2: GPIOM0(96),Slot#3: GPIOM3(99),Slot#4: GPIOM2(98)
+if [ $1 = "1" ]; then
+ gpio=M1
+elif [ $1 = "2" ]; then
+ gpio=M0
+elif [ $1 = "3" ]; then
+ gpio=M3
+elif [ $1 = "4" ]; then
+ gpio=M2
+else
+ usage $0
+fi
+
+
+if [ $2 = "on" ]; then
+ val=1
+elif [ $2 = "off" ]; then
+ val=0
+else
+ usage $0
+fi
+
+gpio_set $gpio $val
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/power_util.py b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/power_util.py
new file mode 100644
index 0000000..d1cc60e
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/power_util.py
@@ -0,0 +1,151 @@
+#!/usr/bin/env python
+#
+# 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
+#
+
+import os
+import re
+import time
+import logging
+from ctypes import *
+
+POR_DIR = '/mnt/data/power/por'
+POR_CONFIG = '%s/config' % POR_DIR
+POR_LPS = '%s/last_state' % POR_DIR
+
+logging.basicConfig(level=logging.INFO)
+log = logging.getLogger(__name__)
+
+class PORConfig():
+ on = "1" # Default ON
+ off = "2" # Default OFF
+ lps = "3" # Default is to use the Last Power State
+
+# Handler for Bridge IC libraries
+bic = CDLL("libbic.so")
+
+class BIC_GPIO(Structure):
+ _fields_ = [ ("bic_gpio_data", c_char * 4) ]
+
+# Get 32-bit GPIO data
+def get_bic_gpio():
+ gpio = BIC_GPIO()
+ p_gpio = pointer(gpio)
+ bic.bic_get_gpio(p_gpio)
+ return gpio
+
+# Get the CPU power status
+def get_pwr_cpu():
+ gpio = get_bic_gpio()
+ pwrgood_cpu = (ord(gpio.bic_gpio_data[0]) & 0x01)
+ return pwrgood_cpu
+
+# Initilize the POR configuration files in /mnt/data
+def init_por():
+
+ por = PORConfig()
+
+ # For the Power On Reset Config
+ if not os.path.isfile(POR_CONFIG):
+ try:
+ os.makedirs(POR_DIR)
+ except OSERROR as err:
+ pass
+
+ por_cnfg = open(POR_CONFIG, 'w')
+ por_cnfg.write('%s\n' % por.on)
+ por_cnfg.close()
+
+ # For the Last Power State info
+ if not os.path.isfile(POR_LPS):
+ curr_time = int(time.time())
+ lps = 'on %s' % str(curr_time)
+
+ f_lps = open(POR_LPS, 'w')
+ f_lps.write('%s\n' % lps)
+ f_lps.close()
+
+# Get the POR config [ ON | OFF | LPS ]
+def get_por_config():
+
+ por = PORConfig()
+
+ if os.path.isfile(POR_CONFIG):
+ por_cnfg = open(POR_CONFIG, 'r')
+ cnfg = por_cnfg.read(1)
+
+ if cnfg in [por.on, por.off, por.lps]:
+ return cnfg
+ else:
+ return 0
+ else:
+ return -1
+
+# To check whether the last power state was on or off
+def get_por_lps():
+
+ if os.path.isfile(POR_LPS):
+ f_lps = open(POR_LPS, 'r')
+ lps = f_lps.readline()
+ if re.search(r'on', lps):
+ return 1
+ elif re.search(r'off', lps):
+ return 0
+ else:
+ return -1
+
+# This tells whether to Power ON or not on POR
+# 1 - Power ON
+# 0 - Do not Power ON
+def por_policy():
+
+ por = PORConfig()
+ cnfg = get_por_config()
+ if cnfg < 1:
+ log.error("power_util: Error getting the POR config.")
+ exit(-1)
+
+ if (cnfg == por.on):
+ # cpu power ON
+ log.debug('ON: Powering ON')
+ return 1
+
+ elif (cnfg == por.off):
+ # cpu power OFF
+ log.debug('OFF: Powering OFF')
+ return 0
+
+ elif (cnfg == por.lps):
+ lps = get_por_lps()
+ if lps < 0:
+ log.error("power_util: Error getting the POR Last State.")
+ exit(-1)
+
+ if lps == 1:
+ # cpu power ON
+ log.debug('LPS: Powering ON')
+ return 1
+
+ elif lps == 0:
+ # cpu power OFF
+ log.debug('LPS: Powering OFF')
+ return 0
+
+
+if __name__ == "__main__":
+ main()
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/rc.early b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/rc.early
new file mode 100644
index 0000000..0f47c72
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/rc.early
@@ -0,0 +1,25 @@
+#!/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
+#
+# This script will be executed at rcS S04 level, which is right after mount /mnt/data
+# and before almost anything else.
+
+if [ -x /mnt/data/etc/rc.early ]; then
+ /mnt/data/etc/rc.early
+fi
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/rc.local b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/rc.local
new file mode 100644
index 0000000..36fa0f1
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/rc.local
@@ -0,0 +1,26 @@
+#!/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
+#
+
+#
+# This script will be executed *after* all the other init scripts.
+
+if [ -x /mnt/data/etc/rc.local ]; then
+ /mnt/data/etc/rc.local
+fi
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/reset_usb.sh b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/reset_usb.sh
new file mode 100644
index 0000000..a7936b1
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/reset_usb.sh
@@ -0,0 +1,55 @@
+#!/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
+#
+
+. /usr/local/fbpackages/utils/ast-functions
+
+#TODO: Add logic to control mux based on front panel switch
+echo -n "Set USB Mux to given slot ... "
+
+# USB_MUX_SEL signals: GPIOE4(36), GPIOE5(37)
+slot=$1
+
+case $slot in
+ 1)
+ gpio_set E4 1
+ gpio_set E5 0
+ ;;
+ 2)
+ gpio_set E4 0
+ gpio_set E5 0
+ ;;
+ 3)
+ gpio_set E4 1
+ gpio_set E5 1
+ ;;
+ 4)
+ gpio_set E4 0
+ gpio_set E5 1
+ ;;
+ *)
+ gpio_set E4 0
+ gpio_set E5 0
+ ;;
+esac
+
+# Enable the USB MUX GPIOS3(147)
+gpio_set S3 0
+
+echo "Done"
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/setup-gpio.sh b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/setup-gpio.sh
new file mode 100755
index 0000000..91797c5
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/setup-gpio.sh
@@ -0,0 +1,307 @@
+#!/bin/bash
+#
+# 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: gpio-setup
+# Required-Start:
+# Required-Stop:
+# Default-Start: S
+# Default-Stop:
+# Short-Description: Set up GPIO pins as appropriate
+### END INIT INFO
+
+# This file contains definitions for the GPIO pins that were not otherwise
+# defined in other files. We should probably move some more of the
+# definitions to this file at some point.
+
+# The commented-out sections are generally already defined elsewhere,
+# and defining them twice generates errors.
+
+# The exception to this is the definition of the GPIO H0, H1, and H2
+# pins, which seem to adversely affect the rebooting of the system.
+# When defined, the system doesn't reboot cleanly. We're still
+# investigating this.
+
+. /usr/local/fbpackages/utils/ast-functions
+
+# Set up to read the board revision pins, Y0, Y1, Y2
+devmem_set_bit $(scu_addr 70) 19
+devmem_clear_bit $(scu_addr a4) 8
+devmem_clear_bit $(scu_addr a4) 9
+devmem_clear_bit $(scu_addr a4) 10
+
+gpio_export Y0
+gpio_export Y1
+gpio_export Y2
+
+# SLOT1_PRSNT_N, GPIOH5 (61)
+# GPIOH5(61): SCU90[6], SCU90[7] shall be 0
+devmem_clear_bit $(scu_addr 90) 6
+devmem_clear_bit $(scu_addr 90) 7
+
+gpio_export H5
+
+# SLOT2_PRSNT_N, GPIOH4 (60)
+# GPIOH4(60): SCU90[6], SCU90[7] shall be 0
+gpio_export H4
+
+# SLOT3_PRSNT_N, GPIOH7 (63)
+# GPIOH7(63): SCU90[6], SCU90[7] shall be 0
+gpio_export H7
+
+# SLOT4_PRSNT_N, GPIOH6 (62)
+# GPIOH6(62): SCU90[6], SCU90[7] shall be 0
+gpio_export H6
+
+# BMC_PWR_BTN_IN_N, uServer power button in, on GPIO D0(24)
+gpio_export D0
+
+# PWR_SLOT1_BTN_N, 1S Server power out, on GPIO D3
+# GPIOD3(27): SCU90[1], SCU8C[9], and SCU70[21] shall be 0
+devmem_clear_bit $(scu_addr 90) 1
+devmem_clear_bit $(scu_addr 8c) 9
+devmem_clear_bit $(scu_addr 70) 21
+
+gpio_set D3 1
+
+# PWR_SLOT2_BTN_N, 1S Server power out, on GPIO D1
+# Make sure the Power Control Pin is Set properly
+# GPIOD1(25): SCU90[1], SCU8C[8], and SCU70[21] shall be 0
+
+devmem_clear_bit $(scu_addr 8c) 8
+
+gpio_set D1 1
+
+# PWR_SLOT3_BTN_N, 1S Server power out, on GPIO D7
+# GPIOD7(31): SCU90[1], SCU8C[11], and SCU70[21] shall be 0
+devmem_clear_bit $(scu_addr 8c) 11
+
+gpio_set D7 1
+
+# PWR_SLOT4_BTN_N, 1S Server power out, on GPIO D5
+# GPIOD5(29): SCU90[1], SCU8C[10], and SCU70[21] shall be 0
+devmem_clear_bit $(scu_addr 8c) 10
+
+gpio_set D5 1
+
+# SMB_SLOT0_NIC_ALERT_N, alert for 1S Server NIC I2C, GPIO B0
+devmem_clear_bit $(scu_addr 80) 8
+
+gpio_export B0
+
+# Setup GPIOs to Mux Enable: GPIOS3(147), Channel Select: GPIOE4(36), GPIOE5(37)
+
+# To use GPIOS3 (147), SCU8C[3], SCU94[0], and SCU94[1] must be 0
+devmem_clear_bit $(scu_addr 8C) 3
+devmem_clear_bit $(scu_addr 94) 0
+devmem_clear_bit $(scu_addr 94) 1
+
+# To use GPIOE4 (36), SCU80[20], SCU8C[14], and SCU70[22] must be 0
+devmem_clear_bit $(scu_addr 80) 20
+devmem_clear_bit $(scu_addr 8C) 14
+devmem_clear_bit $(scu_addr 70) 22
+
+# To use GPIOE5 (37), SCU80[21], SCU8C[14], and SCU70[22] must be 0
+devmem_clear_bit $(scu_addr 80) 21
+devmem_clear_bit $(scu_addr 8C) 14
+devmem_clear_bit $(scu_addr 70) 22
+
+gpio_export S3
+gpio_export E4
+gpio_export E5
+
+# BMC_HEARTBEAT_N, heartbeat LED, GPIO Q7
+devmem_clear_bit $(scu_addr 90) 28
+
+gpio_export Q7
+
+# USB_OC_N, resettable fuse tripped, GPIO Q6
+devmem_clear_bit $(scu_addr 90) 28
+
+gpio_export Q6
+
+# System SPI
+# Strap 12 must be 0 and Strape 13 must be 1
+devmem_clear_bit $(scu_addr 70) 12
+devmem_set_bit $(scu_addr 70) 13
+
+# DEBUG_PORT_UART_SEL_BMC_N: GPIOR1(137)
+# To use GPIOR1, SCU88[25] must be 0
+devmem_clear_bit $(scu_addr 88) 25
+
+gpio_export R1
+
+# DEBUG UART Controls
+# 4 signals: DEBUG_UART_SEL_0/1/2 and DEBUG_UART_RX_SEL_N
+# GPIOE0 (32), GPIOE1 (33), GPIOE2 (34) and GPIOE3 (35)
+
+# To enable GPIOE0, SCU80[16], SCU8C[12], and SCU70[22] must be 0
+devmem_clear_bit $(scu_addr 80) 16
+devmem_clear_bit $(scu_addr 8C) 12
+devmem_clear_bit $(scu_addr 70) 22
+
+gpio_set E0 0
+
+# To enable GPIOE1, SCU80[17], SCU8C[12], and SCU70[22] must be 0
+devmem_clear_bit $(scu_addr 80) 17
+
+gpio_set E1 0
+
+# To enable GPIOE2, SCU80[18], SCU8C[13], and SCU70[22] must be 0
+devmem_clear_bit $(scu_addr 80) 18
+devmem_clear_bit $(scu_addr 8C) 13
+
+gpio_set E2 1
+
+# To enable GPIOE3, SCU80[19], SCU8C[13], and SCU70[22] must be 0
+devmem_clear_bit $(scu_addr 80) 19
+
+gpio_set E3 1
+
+# Enable GPIOY3: BoardId(Yosemite or Test system)
+devmem_clear_bit $(scu_addr a4) 11
+
+# Power LED for Slot#2:
+# To use GPIOM0 (96), SCU90[4], SCU90[5], and SCU84[24] must be 0
+devmem_clear_bit $(scu_addr 90) 4
+devmem_clear_bit $(scu_addr 90) 5
+devmem_clear_bit $(scu_addr 84) 24
+
+gpio_set M0 1
+
+# Power LED for Slot#1:
+# To use GPIOM1 (97), SCU90[4], SCU90[5], and SCU84[25] must be 0
+devmem_clear_bit $(scu_addr 84) 25
+
+gpio_set M1 1
+
+# Power LED for Slot#4:
+# To use GPIOM2 (98), SCU90[4], SCU90[5], and SCU84[26] must be 0
+devmem_clear_bit $(scu_addr 84) 26
+
+gpio_set M2 1
+
+# Power LED for Slot#3:
+# To use GPIOM3 (99), SCU90[4], SCU90[5], and SCU84[27] must be 0
+devmem_clear_bit $(scu_addr 84) 27
+
+gpio_set M3 1
+
+# Front Panel Hand Switch GPIO setup
+# HAND_SW_ID1: GPIOR2(138)
+# To use GPIOR2, SCU88[26] must be 0
+devmem_clear_bit $(scu_addr 88) 26
+
+gpio_export R2
+
+# HAND_SW_ID2: GPIOR3(139)
+# To use GPIOR3, SCU88[27] must be 0
+devmem_clear_bit $(scu_addr 88) 27
+
+gpio_export R3
+
+# HAND_SW_ID4: GPIOR4(140)
+# To use GPIOR4, SCU88[28] must be 0
+devmem_clear_bit $(scu_addr 88) 28
+
+gpio_export R4
+
+
+# HAND_SW_ID8: GPIOR5(141)
+# To use GPIOR5, SCU88[29] must be 0
+devmem_clear_bit $(scu_addr 88) 29
+
+gpio_export R5
+
+# LED POST CODES: 8 GPIO signals
+
+# LED_POSTCODE_0: GPIOG0 (48)
+# To use GPIOG0, SCU84[0] must be 0
+devmem_clear_bit $(scu_addr 84) 0
+
+gpio_set G0 0
+
+# LED_POSTCODE_1: GPIOG1 (49)
+# To use GPIOG1, SCU84[1] must be 0
+devmem_clear_bit $(scu_addr 84) 1
+
+gpio_set G1 0
+
+# LED_POSTCODE_2: GPIOG2 (50)
+# To use GPIOG2, SCU84[2] must be 0
+devmem_clear_bit $(scu_addr 84) 2
+
+gpio_set G2 0
+
+# LED_POSTCODE_3: GPIOG3 (51)
+# To use GPIOG3, SCU84[3] must be 0
+devmem_clear_bit $(scu_addr 84) 3
+
+gpio_set G3 0
+
+# LED_POSTCODE_4: GPIOP4 (124)
+gpio_set P4 0
+
+# LED_POSTCODE_5: GPIOP5 (125)
+gpio_set P5 0
+
+# LED_POSTCODE_6: GPIOP6 (126)
+# To use GPIOP6, SCU88[22] must be 0
+devmem_clear_bit $(scu_addr 88) 22
+
+gpio_set P6 0
+
+# LED_POSTCODE_7: GPIOP7 (127)
+# To use GPIOP7, SCU88[23] must be 0
+devmem_clear_bit $(scu_addr 88) 23
+
+gpio_set P7 0
+
+# BMC_READY_N: GPIOG6 (54)
+# To use GPIOG6, SCU84[6] must be 0
+devmem_clear_bit $(scu_addr 84) 6
+
+gpio_set G6 0
+
+# BMC_RST_BTN_IN_N: GPIOS0 (144)
+# To use GPIOS0, SCU8C[0]
+devmem_clear_bit $(scu_addr 8c) 0
+
+gpio_export S0
+
+# RESET for all Slots
+# RST_SLOT1_SYS_RESET_N: GPIOH1 (57)
+# To use GPIOH1, SCU90[6], SCU90[7] must be 0
+devmem_clear_bit $(scu_addr 90) 6
+devmem_clear_bit $(scu_addr 90) 7
+
+gpio_set H1 1
+
+# RST_SLOT2_SYS_RESET_N: GPIOH0 (56)
+# To use GPIOH0, SCU90[6], SCU90[7] must be 0
+gpio_set H0 1
+
+# RST_SLOT3_SYS_RESET_N: GPIOH3 (59)
+# To use GPIOH3, SCU90[6], SCU90[7] must be 0
+gpio_set H3 1
+
+# RST_SLOT4_SYS_RESET_N: GPIOH2 (58)
+# To use GPIOH2, SCU90[6], SCU90[7] must be 0
+gpio_set H2 1
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/setup_rov.sh b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/setup_rov.sh
new file mode 100755
index 0000000..749fe65
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/setup_rov.sh
@@ -0,0 +1,99 @@
+#!/bin/bash
+#
+# 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
+#
+
+# The T2 chip can prefer different input voltages, depending, presumably
+# of manufacturing variations. We need to determine whether it wants
+# 0.95V or 1.025V, reset the T2 to reduce total power usage, set the
+# outgoing voltage on the first buck converter, and bring T2 up out of
+# reset.
+
+. /usr/local/fbpackages/utils/ast-functions
+
+# read the T2 ROV after the GPIOs are enabled
+t2_rov() {
+ local val0 val1 val2
+ # Note that the values are *not* read in order.
+ val0=$(cat /sys/class/gpio/gpio58/value 2>/dev/null)
+ val1=$(cat /sys/class/gpio/gpio56/value 2>/dev/null)
+ val2=$(cat /sys/class/gpio/gpio57/value 2>/dev/null)
+ echo $((val0 | (val1 << 1) | (val2 << 2)))
+}
+
+rov=$(t2_rov)
+
+# target_volts come from the data sheet and 18mV of loss and
+# some fudging based on actual measurements to get either 1.025V
+# or 0.95V at T2
+if [ $rov -eq 1 ]; then
+ target_volts=0x5a
+elif [ $rov -eq 2 ]; then
+ target_volts=0x65
+else
+ echo "Unrecognized T2 ROV value $rov, setting failed."
+ exit 1
+fi
+target_volts=$(( $target_volts * 1 )) # normalize to decimal
+
+# We shouldn't have to rmmod pmbus, because it hasn't been loaded yet,
+# but if the script is rerun after the system is up, it may be necessary.
+rmmod pmbus
+reload=$?
+
+# Get current voltage value
+cur_volts=$(i2cget -y 1 0x60 0x8b w)
+cur_volts=$(( $cur_volts * 1 )) # normalize to decimal
+
+# Only bounce the T2 if we actually need to modify the voltage
+if [ $cur_volts -ne $target_volts ]; then
+ # Set values before turning out output; we're using "PCIE, then MCS"
+ echo 1 > /sys/class/gpio/gpio42/value
+ echo 1 > /sys/class/gpio/gpio43/value
+ echo out > /sys/class/gpio/gpio42/direction
+ echo out > /sys/class/gpio/gpio43/direction
+ echo 0 > /sys/class/gpio/gpio16/value
+ echo out > /sys/class/gpio/gpio16/direction
+ # T2 is in reset; note that this may cause NMI messages on the uServer,
+ # which shouldn't be up anyway when this is first run.
+
+ # Set the requested value to the current value to avoid rapid shifts
+ i2cset -y 1 0x60 0x21 $cur_volts w
+ # Enable the requested voltage
+ i2cset -y 1 0x60 0xd2 0x5a
+ i2cset -y 1 0x60 0xd3 0x5a
+ sleep 1
+
+ # Set the target voltage
+ i2cset -y 1 0x60 0x21 $target_volts w
+
+ sleep 1
+
+ # Let T2 come out of reset
+ echo 1 > /sys/class/gpio/gpio16/value
+ echo "T2 ROV value set based on $rov."
+ sleep 2
+ echo 0 > /sys/class/gpio/gpio42/value
+ echo 0 > /sys/class/gpio/gpio43/value
+else
+ echo "T2 ROV already correctly set."
+fi
+# Bring back pmbus if necessary
+if [ $reload -eq 0 ]; then
+ modprobe pmbus
+fi
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/setup_switch.py b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/setup_switch.py
new file mode 100644
index 0000000..995cec8
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/setup_switch.py
@@ -0,0 +1,49 @@
+#!/usr/bin/python
+#
+# 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
+#
+# This script combines multiple switch configuration into one python script.
+# All such configuration can be done directly through bcm5396_util.py.
+# But, it turns out it took several seconds to just start the python script.
+# Involking the script 16 times (2 to create vlan, 13 to set port vlan default,
+# and 1 to enable vlan function) contributes 1 minute delay.
+
+from bcm5396 import Bcm5396
+
+MDC_GPIO = 6
+MDIO_GPIO = 7
+
+INTERNAL_VLAN = 4088
+DEFAULT_VLAN=4090
+
+INTERNAL_PORTS = [3, 10, 1, 11, 0, 8, 2, 9, 4, 12, 14, 13]
+FRONT_PORT=5
+
+if __name__ == '__main__':
+ bcm = Bcm5396(Bcm5396.MDIO_ACCESS, mdc=MDC_GPIO, mdio=MDIO_GPIO)
+ # create default VLAN including internal ports and front panel
+ # port (un-tagged)
+ bcm.add_vlan(DEFAULT_VLAN, INTERNAL_PORTS + [FRONT_PORT],
+ INTERNAL_PORTS + [FRONT_PORT], 0)
+ # set ingress vlan for internal ports and front panel port to default vlan
+ for port in INTERNAL_PORTS + [FRONT_PORT]:
+ bcm.vlan_set_port_default(port, DEFAULT_VLAN, 0)
+ # create internal vlan including internal ports only (tagged)
+ bcm.add_vlan(INTERNAL_VLAN, [], INTERNAL_PORTS, 0)
+ # enable vlan
+ bcm.vlan_ctrl(True)
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/sol-util b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/sol-util
new file mode 100755
index 0000000..3769a5b
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/sol-util
@@ -0,0 +1,74 @@
+#!/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
+#
+
+BIN_CONSOLED="/usr/local/bin/consoled"
+LOGFILE1="/tmp/consoled_$1_log-old"
+LOGFILE2="/tmp/consoled_$1_log"
+
+
+if [ "$1" == "slot1" ] || [ "$1" == "slot2" ] || [ "$1" == "slot3" ] || [ "$1" == "slot4" ]
+then
+ SLOT=$1
+else
+ echo "Usage: sol-util [ slot1 | slot2 | slot3 | slot4 ]"
+ echo " sol-util [ slot1 | slot2 | slot3 | slot4 ] --force"
+ echo " sol-util [ slot1 | slot2 | slot3 | slot4 ] --history"
+ exit -1
+fi
+
+if [ $# -gt 1 ]; then
+ if [[ "$2" == "--history" ]]; then
+ cat $LOGFILE1 2>/dev/null
+ cat $LOGFILE2 2>/dev/null
+ exit 0
+ fi
+fi
+
+PS=$(ps | grep -e $BIN_CONSOLED | grep -e $SLOT)
+
+PID=$(ps | grep -e $BIN_CONSOLED | grep -e $SLOT | awk '{print $1}')
+
+
+if [[ $PS =~ "term" ]] && [[ "$2" != "--force" ]]; then
+ echo "Another SOL session is running."
+ echo "Please use the \"--force\" option"
+ exit -1
+fi
+
+echo "You are in SOL session."
+echo "Use ctrl-x to quit."
+echo "-----------------------"
+echo
+
+kill -9 -s TERM $PID 2>/dev/null
+
+if [[ "$2" == "--force" ]]; then
+ PID=$(ps | grep -e $BIN_CONSOLED | grep -e $SLOT | awk '{print $1}')
+ kill -9 -s TERM $PID 2>/dev/null
+fi
+
+$BIN_CONSOLED $SLOT --term
+
+$BIN_CONSOLED $SLOT --buffer
+
+echo
+echo
+echo "-----------------------"
+echo "Exit from SOL session."
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/src/include/i2c-dev.h b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/src/include/i2c-dev.h
new file mode 100644
index 0000000..3b67afc
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/src/include/i2c-dev.h
@@ -0,0 +1,364 @@
+/*
+ i2c-dev.h - i2c-bus driver, char device interface
+
+ Copyright (C) 1995-97 Simon G. Vogl
+ Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>
+
+ 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., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301 USA.
+*/
+
+#ifndef _LINUX_I2C_DEV_H
+#define _LINUX_I2C_DEV_H
+
+#include <linux/types.h>
+#include <sys/ioctl.h>
+#include <stddef.h>
+#include <string.h>
+
+
+/* -- i2c.h -- */
+
+#define _I2C_MIN(a, b) (((a) <= (b)) ? (a) : (b))
+
+/*
+ * I2C Message - used for pure i2c transaction, also from /dev interface
+ */
+struct i2c_msg {
+ __u16 addr; /* slave address */
+ unsigned short flags;
+#define I2C_CLIENT_PEC 0x04 /* Use Packet Error Checking */
+#define I2C_M_TEN 0x0010 /* this is a ten bit chip address */
+#define I2C_M_RD 0x0001 /* read data, from slave to master */
+#define I2C_S_EN 0x0002 /* read data, from slave to master */
+#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */
+#define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */
+#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
+#define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */
+#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */
+ short len; /* msg length */
+ char *buf; /* pointer to msg data */
+};
+
+/* 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_PEC 0x00000008
+#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_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)
+
+/* Old name, for compatibility */
+#define I2C_FUNC_SMBUS_HWPEC_CALC I2C_FUNC_SMBUS_PEC
+
+/*
+ * 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 + 2]; /* block[0] is used for length */
+ /* and one more for PEC */
+};
+
+#define I2C_SMBUS_BLOCK_LARGE_MAX 240
+union i2c_smbus_large_data {
+ union i2c_smbus_data data;
+ __u8 block[I2C_SMBUS_BLOCK_LARGE_MAX + 2]; /* block[0] is used for length */
+ /* 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_BROKEN 6
+#define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */
+#define I2C_SMBUS_I2C_BLOCK_DATA 8
+#define I2C_SMBUS_BLOCK_LARGE_DATA 9
+
+
+/* /dev/i2c-X ioctl commands. The ioctl's parameter is always an
+ * unsigned long, except for:
+ * - I2C_FUNCS, takes pointer to an unsigned long
+ * - I2C_RDWR, takes pointer to struct i2c_rdwr_ioctl_data
+ * - I2C_SMBUS, takes pointer to struct i2c_smbus_ioctl_data
+ */
+#define I2C_RETRIES 0x0701 /* number of times a device address should
+ be polled when not acknowledging */
+#define I2C_TIMEOUT 0x0702 /* set timeout in units of 10 ms */
+
+/* NOTE: Slave address is 7 or 10 bits, but 10-bit addresses
+ * are NOT supported! (due to code brokenness)
+ */
+#define I2C_SLAVE 0x0703 /* Use this slave address */
+#define I2C_SLAVE_FORCE 0x0706 /* Use this slave address, even if it
+ is already in use by a driver! */
+#define I2C_TENBIT 0x0704 /* 0 for 7 bit addrs, != 0 for 10 bit */
+
+#define I2C_FUNCS 0x0705 /* Get the adapter functionality mask */
+
+#define I2C_RDWR 0x0707 /* Combined R/W transfer (one STOP only) */
+#define I2C_SLAVE_RDWR 0x0709 /* Slave Read/Write */
+
+#define I2C_PEC 0x0708 /* != 0 to use PEC with SMBus */
+#define I2C_SMBUS 0x0720 /* SMBus transfer */
+
+
+/* This is the structure as used in the I2C_SMBUS ioctl call */
+struct i2c_smbus_ioctl_data {
+ __u8 read_write;
+ __u8 command;
+ __u32 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 */
+ __u32 nmsgs; /* number of i2c_msgs */
+};
+
+#define I2C_RDRW_IOCTL_MAX_MSGS 42
+
+
+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;
+ if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
+ I2C_SMBUS_BLOCK_DATA,&data))
+ return -1;
+ else {
+ memcpy(values, &data.block[1], _I2C_MIN(data.block[0], I2C_SMBUS_BLOCK_MAX));
+ return data.block[0];
+ }
+}
+
+static inline __s32 i2c_smbus_write_block_data(int file, __u8 command,
+ __u8 length, const __u8 *values)
+{
+ union i2c_smbus_data data;
+ if (length > 32)
+ length = 32;
+ memcpy(&data.block[1], values, length);
+ data.block[0] = length;
+ return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
+ I2C_SMBUS_BLOCK_DATA, &data);
+}
+
+static inline __s32 i2c_smbus_read_block_large_data(int file, __u8 command,
+ __u8 *values)
+{
+ union i2c_smbus_large_data data;
+ if (i2c_smbus_access(file, I2C_SMBUS_READ, command,
+ I2C_SMBUS_BLOCK_LARGE_DATA,
+ (union i2c_smbus_data *)&data)) {
+ return -1;
+ } else {
+ /* the first byte is the length which is not copied */
+ memcpy(values, &data.block[1], _I2C_MIN(data.block[0], I2C_SMBUS_BLOCK_LARGE_MAX));
+ return data.block[0];
+ }
+}
+
+static inline __s32 i2c_smbus_write_block_large_data(int file, __u8 command,
+ __u8 length,
+ const __u8 *values)
+{
+ union i2c_smbus_large_data data;
+ if (length > I2C_SMBUS_BLOCK_LARGE_MAX) {
+ length = I2C_SMBUS_BLOCK_LARGE_MAX;
+ }
+ data.block[0] = length;
+ memcpy(&data.block[1], values, length);
+ return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
+ I2C_SMBUS_BLOCK_LARGE_DATA,
+ (union i2c_smbus_data *)&data);
+}
+
+/* Returns the number of read bytes */
+/* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you
+ ask for less than 32 bytes, your code will only work with kernels
+ 2.6.23 and later. */
+static inline __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command,
+ __u8 length, __u8 *values)
+{
+ union i2c_smbus_data data;
+
+ if (length > 32)
+ length = 32;
+ data.block[0] = length;
+ if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
+ length == 32 ? I2C_SMBUS_I2C_BLOCK_BROKEN :
+ I2C_SMBUS_I2C_BLOCK_DATA,&data))
+ return -1;
+ else {
+ memcpy(values, &data.block[1], _I2C_MIN(data.block[0], I2C_SMBUS_BLOCK_MAX));
+ return data.block[0];
+ }
+}
+
+static inline __s32 i2c_smbus_write_i2c_block_data(int file, __u8 command,
+ __u8 length,
+ const __u8 *values)
+{
+ union i2c_smbus_data data;
+ if (length > 32)
+ length = 32;
+ memcpy(&data.block[1], values, length);
+ data.block[0] = length;
+ return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
+ I2C_SMBUS_I2C_BLOCK_BROKEN, &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;
+ if (length > 32)
+ length = 32;
+ memcpy(&data.block[1], values, length);
+ data.block[0] = length;
+ if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
+ I2C_SMBUS_BLOCK_PROC_CALL,&data))
+ return -1;
+ else {
+ memcpy(values, &data.block[1], _I2C_MIN(data.block[0], I2C_SMBUS_BLOCK_MAX));
+ return data.block[0];
+ }
+}
+
+#undef _I2C_MIN
+
+#endif /* _LINUX_I2C_DEV_H */
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/src/include/log.h b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/src/include/log.h
new file mode 100644
index 0000000..a69d69e
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/src/include/log.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+#ifndef LOG_H
+#define LOG_H
+
+#include <stdio.h>
+#include <string.h>
+
+//#define DEBUG
+//#define VERBOSE
+
+#define _LOG(dst, fmt, ...) do { \
+ fprintf(dst, "%s:%d " fmt "\n", \
+ __FUNCTION__, __LINE__, ##__VA_ARGS__); \
+ fflush(dst); \
+} while(0)
+
+#define LOG_ERR(err, fmt, ...) do { \
+ char buf[128]; \
+ strerror_r(err, buf, sizeof(buf)); \
+ _LOG(stderr, "ERROR " fmt ": %s", ##__VA_ARGS__, buf); \
+} while(0)
+
+#define LOG_INFO(fmt, ...) do { \
+ _LOG(stdout, fmt, ##__VA_ARGS__); \
+} while(0)
+
+#ifdef DEBUG
+#define LOG_DBG(fmt, ...) do { \
+ _LOG(stdout, fmt, ##__VA_ARGS__); \
+} while(0)
+#else
+#define LOG_DBG(fmt, ...)
+#endif
+
+#ifdef VERBOSE
+#define LOG_VER(fmt, ...) do { \
+ _LOG(stdout, fmt, ##__VA_ARGS__); \
+} while(0)
+#else
+#define LOG_VER(fmt, ...)
+#endif
+
+#endif
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/us_console.sh b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/us_console.sh
new file mode 100755
index 0000000..1672acd
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/us_console.sh
@@ -0,0 +1,41 @@
+#!/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
+#
+
+usage() {
+ echo "$0 <connect | disconnect>"
+}
+
+. /usr/local/fbpackages/utils/ast-functions
+
+if [ $# -ne 1 ]; then
+ usage
+ exit 1
+fi
+
+if [ "$1" == "connect" ]; then
+ VALUE=1
+elif [ "$1" == "disconnect" ]; then
+ VALUE=0
+else
+ usage
+ exit 1
+fi
+
+gpio_set 32 $VALUE
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/watch-fc.sh b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/watch-fc.sh
new file mode 100755
index 0000000..d04b7cd
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/watch-fc.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+#
+# 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
+#
+
+. /usr/local/fbpackages/utils/ast-functions
+
+MAC1LINK=0 # GPIOA0
+FAB0_PRES=20 # GPIOC4
+FAB1_PRES=21 # GPIOC5
+while true; do
+ # fabN_pres: active low.
+ if [ $(gpio_get $FAB0_PRES) = 0 ]; then
+ gpio_set $MAC1LINK 0
+ elif [ $(gpio_get $FAB1_PRES) = 0 ]; then
+ gpio_set $MAC1LINK 1
+ fi
+ sleep 1
+done
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/wedge_us_mac.sh b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/wedge_us_mac.sh
new file mode 100644
index 0000000..34b8e59
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/wedge_us_mac.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+#
+# 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
+#
+
+PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
+
+mac=$(i2cdump -y 0x0 0x49 s 0xd4 | grep '^00: d4'| awk '{ print $3":"$4":"$5":"$6":"$7":"$8 }') 2>/dev/null
+
+if [ -n "$mac" ]; then
+ echo $mac
+else
+ echo "Cannot find out the microserver MAC" 1>&2
+fi
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/yosemite-sensors/Makefile b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/yosemite-sensors/Makefile
new file mode 100644
index 0000000..2bc9721
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/yosemite-sensors/Makefile
@@ -0,0 +1,10 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+all: yosemite-sensors
+
+yosemite-sensors: yosemite-sensors.c
+ $(CC) -lyosemite_sensor -std=c99 -o $@ $^ $(LDFLAGS)
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o yosemite-sensors
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/yosemite-sensors/yosemite-sensors.c b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/yosemite-sensors/yosemite-sensors.c
new file mode 100644
index 0000000..aa921db
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/yosemite-sensors/yosemite-sensors.c
@@ -0,0 +1,405 @@
+/*
+ * yosemite-sensors
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <syslog.h>
+#include <stdint.h>
+#include <pthread.h>
+#include <facebook/bic.h>
+#include <openbmc/ipmi.h>
+#include <facebook/yosemite_sensor.h>
+
+int
+main(int argc, char **argv) {
+ int value;
+ float fvalue;
+ uint8_t slot_id;
+
+ slot_id = atoi(argv[1]);
+
+ if (yosemite_sensor_read(slot_id, SP_SENSOR_INLET_TEMP, &fvalue)) {
+ printf("yosemite_sensor_read failed: SP_SENSOR_INLET_TEMP\n");
+ } else {
+ printf("SP_SENSOR_INLET_TEMP: %.2f C\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, SP_SENSOR_OUTLET_TEMP, &fvalue)) {
+ printf("yosemite_sensor_read failed: SP_SENSOR_OUTLET_TEMP\n");
+ } else {
+ printf("SP_SENSOR_OUTLET_TEMP: %.2f C\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, SP_SENSOR_FAN0_TACH, &value)) {
+ printf("yosemite_sensor_read failed: SP_SENSOR_FAN0_TACH\n");
+ } else {
+ printf("SP_SENSOR_FAN0_TACH: %d rpm\n", value);
+ }
+
+ if (yosemite_sensor_read(slot_id, SP_SENSOR_FAN1_TACH, &value)) {
+ printf("yosemite_sensor_read failed: SP_SENSOR_FAN1_TACH\n");
+ } else {
+ printf("SP_SENSOR_FAN1_TACH: %d rpm\n", value);
+ }
+
+ if (yosemite_sensor_read(slot_id, SP_SENSOR_P5V, &fvalue)) {
+ printf("yosemite_sensor_read failed: SP_SENSOR_P5V\n");
+ } else {
+ printf("SP_SENSOR_P5V: %.2f Volts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, SP_SENSOR_P12V, &fvalue)) {
+ printf("yosemite_sensor_read failed: SP_SENSOR_P12V\n");
+ } else {
+ printf("SP_SENSOR_P12V: %.2f Volts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, SP_SENSOR_P3V3_STBY, &fvalue)) {
+ printf("yosemite_sensor_read failed: SP_SENSOR_P3V3_STBY\n");
+ } else {
+ printf("SP_SENSOR_P3V3_STBY: %.2f Volts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, SP_SENSOR_P12V_SLOT0, &fvalue)) {
+ printf("yosemite_sensor_read failed: SP_SENSOR_P12V_SLOT0\n");
+ } else {
+ printf("SP_SENSOR_P12V_SLOT0: %.2f Volts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, SP_SENSOR_P12V_SLOT1, &fvalue)) {
+ printf("yosemite_sensor_read failed: SP_SENSOR_P12V_SLOT1\n");
+ } else {
+ printf("SP_SENSOR_P12V_SLOT1: %.2f Volts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, SP_SENSOR_P12V_SLOT2, &fvalue)) {
+ printf("yosemite_sensor_read failed: SP_SENSOR_P12V_SLOT2\n");
+ } else {
+ printf("SP_SENSOR_P12V_SLOT2: %.2f Volts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, SP_SENSOR_P12V_SLOT3, &fvalue)) {
+ printf("yosemite_sensor_read failed: SP_SENSOR_P12V_SLOT3\n");
+ } else {
+ printf("SP_SENSOR_P12V_SLOT3: %.2f Volts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, SP_SENSOR_P3V3, &fvalue)) {
+ printf("yosemite_sensor_read failed: SP_SENSOR_P3V3\n");
+ } else {
+ printf("SP_SENSOR_P3V3: %.2f Volts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, SP_SENSOR_HSC_IN_VOLT, &fvalue)) {
+ printf("yosemite_sensor_read failed: SP_SENSOR_HSC_IN_VOLT\n");
+ } else {
+ printf("SP_SENSOR_HSC_IN_VOLT: %.2f Volts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, SP_SENSOR_HSC_OUT_CURR, &fvalue)) {
+ printf("yosemite_sensor_read failed: SP_SENSOR_HSC_OUT_CURR\n");
+ } else {
+ printf("SP_SENSOR_HSC_OUT_CURR: %.2f Amps\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, SP_SENSOR_HSC_TEMP, &fvalue)) {
+ printf("yosemite_sensor_read failed: SP_SENSOR_HSC_TEMP\n");
+ } else {
+ printf("SP_SENSOR_P3V3: %.2f C\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, SP_SENSOR_HSC_IN_POWER, &fvalue)) {
+ printf("yosemite_sensor_read failed: SP_SENSOR_HSC_IN_POWER\n");
+ } else {
+ printf("SP_SENSOR_HSC_IN_POWER: %.2f Watts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_MB_OUTLET_TEMP, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_MB_OUTLET_TEMP\n");
+ } else {
+ printf("BIC_SENSOR_MB_OUTLET_TEMP: %.2f C\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_VCCIN_VR_TEMP, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_VCCIN_VR_TEMP\n");
+ } else {
+ printf("BIC_SENSOR_VCCIN_VR_TEMP: %.2f C\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_VCC_GBE_VR_TEMP, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_VCC_GBE_VR_TEMP\n");
+ } else {
+ printf("BIC_SENSOR_VCC_GBE_VR_TEMP: %.2f C\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_1V05PCH_VR_TEMP, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_1V05PCH_VR_TEMP\n");
+ } else {
+ printf("BIC_SENSOR_1V05PCH_VR_TEMP: %.2f C\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_SOC_TEMP, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_SOC_TEMP\n");
+ } else {
+ printf("BIC_SENSOR_SOC_TEMP: %.2f C\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_MB_INLET_TEMP, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_MB_INLET_TEMP\n");
+ } else {
+ printf("BIC_SENSOR_MB_INLET_TEMP: %.2f C\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_PCH_TEMP, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_PCH_TEMP\n");
+ } else {
+ printf("BIC_SENSOR_PCH_TEMP: %.2f C\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_SOC_THERM_MARGIN, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_SOC_THERM_MARGIN\n");
+ } else {
+ printf("BIC_SENSOR_SOC_THERM_MARGIN: %.2f C\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_VDDR_VR_TEMP, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_VDDR_VR_TEMP\n");
+ } else {
+ printf("BIC_SENSOR_VDDR_VR_TEMP: %.2f C\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_SOC_TJMAX, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_SOC_TJMAX\n");
+ } else {
+ printf("BIC_SENSOR_SOC_TJMAX: %.2f C\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_VCC_SCSUS_VR_TEMP, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_VCC_SCSUS_VR_TEMP\n");
+ } else {
+ printf("BIC_SENSOR_VCC_SCSUS_VR_TEMP: %.2f C\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_SOC_DIMMA0_TEMP, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_SOC_DIMMA0_TEMP\n");
+ } else {
+ printf("BIC_SENSOR_SOC_DIMMA0_TEMP: %.2f C\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_SOC_DIMMA1_TEMP, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_SOC_DIMMA1_TEMP\n");
+ } else {
+ printf("BIC_SENSOR_SOC_DIMMA1_TEMP: %.2f C\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_SOC_DIMMB0_TEMP, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_SOC_DIMMB0_TEMP\n");
+ } else {
+ printf("BIC_SENSOR_SOC_DIMMB0_TEMP: %.2f C\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_SOC_DIMMB1_TEMP, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_SOC_DIMMB1_TEMP\n");
+ } else {
+ printf("BIC_SENSOR_SOC_DIMMB1_TEMP: %.2f C\n", fvalue);
+ }
+
+ // Monolake Current Sensors
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_VCC_GBE_VR_CURR, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_VCC_GBE_VR_CURR\n");
+ } else {
+ printf("BIC_SENSOR_VCC_GBE_VR_CURR: %.2f Amps\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_1V05_PCH_VR_CURR, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_1V05_PCH_VR_CURR\n");
+ } else {
+ printf("BIC_SENSOR_1V05_PCH_VR_CURR: %.2f Amps\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_VCCIN_VR_CURR, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_VCCIN_VR_CURR\n");
+ } else {
+ printf("BIC_SENSOR_VCCIN_VR_CURR: %.2f Amps\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_VDDR_VR_CURR, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_VDDR_VR_CURR\n");
+ } else {
+ printf("BIC_SENSOR_VDDR_VR_CURR: %.2f Amps\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_VCC_SCSUS_VR_CURR, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_VCC_SCSUS_VR_CURR\n");
+ } else {
+ printf("BIC_SENSOR_VCC_SCSUS_VR_CURR: %.2f Amps\n", fvalue);
+ }
+
+ // Monolake Voltage Sensors
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_VCCIN_VR_VOL, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_VCCIN_VR_VOL\n");
+ } else {
+ printf("BIC_SENSOR_VCCIN_VR_VOL: %.2f Volts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_VDDR_VR_VOL, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_VDDR_VR_VOL\n");
+ } else {
+ printf("BIC_SENSOR_VDDR_VR_VOL: %.2f Volts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_VCC_SCSUS_VR_VOL, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_VCC_SCSUS_VR_VOL\n");
+ } else {
+ printf("BIC_SENSOR_VCC_SCSUS_VR_VOL: %.2f Volts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_VCC_GBE_VR_VOL, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_VCC_GBE_VR_VOL\n");
+ } else {
+ printf("BIC_SENSOR_VCC_GBE_VR_VOL: %.2f Volts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_1V05_PCH_VR_VOL, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_1V05_PCH_VR_VOL\n");
+ } else {
+ printf("BIC_SENSOR_1V05_PCH_VR_VOL: %.2f Volts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_P3V3_MB, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_P3V3_MB\n");
+ } else {
+ printf("BIC_SENSOR_P3V3_MB: %.2f Volts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_P12V_MB, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_P12V_MB\n");
+ } else {
+ printf("BIC_SENSOR_P12V_MB: %.2f Volts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_P1V05_PCH, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_P1V05_PCH\n");
+ } else {
+ printf("BIC_SENSOR_P1V05_PCH: %.2f Volts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_P3V3_STBY_MB, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_P3V3_STBY_MB\n");
+ } else {
+ printf("BIC_SENSOR_P3V3_STBY_MB: %.2f Volts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_P5V_STBY_MB, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_P5V_STBY_MB\n");
+ } else {
+ printf("BIC_SENSOR_P5V_STBY_MB: %.2f Volts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_PV_BAT, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_PV_BAT\n");
+ } else {
+ printf("BIC_SENSOR_PV_BAT: %.2f Volts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_PVDDR, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_PVDDR\n");
+ } else {
+ printf("BIC_SENSOR_PVDDR: %.2f Volts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_PVCC_GBE, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_PVCC_GBE\n");
+ } else {
+ printf("BIC_SENSOR_PVCC_GBE: %.2f Volts\n", fvalue);
+ }
+
+ // Monolake Power Sensors
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_VCCIN_VR_POUT, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_VCCIN_VR_POUT\n");
+ } else {
+ printf("BIC_SENSOR_VCCIN_VR_POUT: %.2f Watts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_INA230_POWER, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_INA230_POWER\n");
+ } else {
+ printf("BIC_SENSOR_INA230_POWER: %.2f Watts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_SOC_PACKAGE_PWR, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_SOC_PACKAGE_PWR\n");
+ } else {
+ printf("BIC_SENSOR_SOC_PACKAGE_PWR: %.2f Watts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_VDDR_VR_POUT, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_VDDR_VR_POUT\n");
+ } else {
+ printf("BIC_SENSOR_VDDR_VR_POUT: %.2f Watts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_VCC_SCSUS_VR_POUT, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_VCC_SCSUS_VR_POUT\n");
+ } else {
+ printf("BIC_SENSOR_VCC_SCSUS_VR_POUT: %.2f Watts\n", fvalue);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_VCC_GBE_VR_POUT, &fvalue)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_VCC_GBE_VR_POUT\n");
+ } else {
+ printf("BIC_SENSOR_VCC_GBE_VR_POUT: %.2f Watts\n", fvalue);
+ }
+
+ // Discrete Sensors
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_SYSTEM_STATUS, &value)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_SYSTEM_STATUS\n");
+ } else {
+ printf("BIC_SENSOR_SYSTEM_STATUS: 0x%X\n", value);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_PROC_FAIL, &value)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_PROC_FAIL\n");
+ } else {
+ printf("BIC_SENSOR_PROC_FAIL: 0x%X\n", value);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_SYS_BOOT_STAT, &value)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_SYS_BOOT_STAT\n");
+ } else {
+ printf("BIC_SENSOR_SYS_BOOT_STAT: 0x%X\n", value);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_VR_HOT, &value)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_VR_HOT\n");
+ } else {
+ printf("BIC_SENSOR_VR_HOT: 0x%X\n", value);
+ }
+
+ if (yosemite_sensor_read(slot_id, BIC_SENSOR_CPU_DIMM_HOT, &value)) {
+ printf("yosemite_sensor_read failed: BIC_SENSOR_CPU_DIMM_HOT\n");
+ } else {
+ printf("BIC_SENSOR_CPU_DIMM_HOT: 0x%X\n", value);
+ }
+
+ return 0;
+}
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/yosemite_power.sh b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/yosemite_power.sh
new file mode 100644
index 0000000..3a2aaf7
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/files/yosemite_power.sh
@@ -0,0 +1,169 @@
+#!/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/fbpackages/utils/ast-functions
+
+PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
+
+LPS_PATH=/mnt/data/power/por/last_state
+
+prog="$0"
+
+usage() {
+ echo "Usage: $prog <slot#> <command> [command options]"
+ echo
+ echo "Commands:"
+ echo " status: Get the current 1S server power status"
+ echo
+ echo " on: Power on 1S server if not powered on already"
+ echo " options:"
+ echo " -f: Re-do power on sequence no matter if 1S server has "
+ echo " been powered on or not."
+ echo
+ echo " off: Power off 1S server ungracefully"
+ echo
+ echo
+}
+
+do_status() {
+ if [ $(is_server_prsnt $slot) == "0" ]; then
+ echo "The given slot is Empty"
+ return 0
+ fi
+
+ echo -n "1S Server power for slot#$slot is "
+ if [ $(yosemite_is_server_on $slot) -eq 1 ] ; then
+ echo "on"
+ else
+ echo "off"
+ fi
+ return 0
+}
+
+do_on() {
+
+ if [ $(is_server_prsnt $slot) == "0" ]; then
+ echo "The given slot is Empty"
+ return 0
+ fi
+
+ local force opt
+ force=0
+ while getopts "f" opt; do
+ case $opt in
+ f)
+ force=1
+ ;;
+ *)
+ usage
+ exit -1
+ ;;
+
+ esac
+ done
+ echo -n "Power on slot#$slot server ..."
+ if [ $force -eq 0 ]; then
+ # need to check if 1S Server is on or not
+ if [ $(yosemite_is_server_on $slot) -eq 1 ]; then
+ echo " Already on. Skip!"
+ return 1
+ fi
+ fi
+
+ # TODO: State the power state change
+ echo "on $(date +%s)" > $LPS_PATH
+
+ # first make sure, GPIO is high
+ gpio_set $gpio 1
+ # generate the power on pulse
+ gpio_set $gpio 0
+ sleep 1
+ gpio_set $gpio 1
+ sleep 1
+ # Turn on the power LED
+ /usr/local/bin/power_led.sh $slot on
+ echo " Done"
+ return 0
+}
+
+do_off() {
+ if [ $(is_server_prsnt $slot) == "0" ]; then
+ echo "The given slot is Empty"
+ return 0
+ fi
+ echo -n "Power off slot#$slot server ..."
+
+ #TODO: State the power state change
+ echo "off $(date +%s)" > $LPS_PATH
+
+ # first make sure, GPIO is high
+ gpio_set $gpio 1
+ sleep 1
+ gpio_set $gpio 0
+ sleep 5
+ gpio_set $gpio 1
+ # Turn off the power LED
+ /usr/local/bin/power_led.sh $slot off
+ echo " Done"
+ return 0
+}
+
+# Slot1: GPIOD3(27), Slot2: GPIOD1(25), Slot3: GPIOD7(31), Slot4: GPIOD5(29)
+slot=$1
+
+case $slot in
+ 1)
+ gpio=D3
+ ;;
+ 2)
+ gpio=D1
+ ;;
+ 3)
+ gpio=D7
+ ;;
+ 4)
+ gpio=D5
+ ;;
+ *)
+ gpio=D3
+ ;;
+esac
+
+command="$2"
+shift
+shift
+
+case "$command" in
+ status)
+ do_status $@
+ ;;
+ on)
+ do_on $@
+ ;;
+ off)
+ do_off $@
+ ;;
+ *)
+ usage
+ exit -1
+ ;;
+esac
+
+exit $?
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/yosemite-sensors_0.1.bb b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/yosemite-sensors_0.1.bb
new file mode 100644
index 0000000..245f05d
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fbutils/yosemite-sensors_0.1.bb
@@ -0,0 +1,21 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+SUMMARY = "Yosemite Sensor Utility"
+DESCRIPTION = "Util for reading various sensors on Yosemite"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://yosemite-sensors.c;beginline=4;endline=16;md5=b395943ba8a0717a83e62ca123a8d238"
+
+SRC_URI = "file://yosemite-sensors \
+ "
+
+S = "${WORKDIR}/yosemite-sensors"
+
+do_install() {
+ install -d ${D}${bindir}
+ install -m 0755 yosemite-sensors ${D}${bindir}/yosemite-sensors
+}
+
+DEPENDS += "libyosemite-sensor"
+
+FILES_${PN} = "${bindir}"
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/front-paneld/files/Makefile b/meta-facebook/meta-yosemite/recipes-yosemite/front-paneld/files/Makefile
new file mode 100644
index 0000000..c542230
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/front-paneld/files/Makefile
@@ -0,0 +1,10 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+all: front-paneld
+
+front-paneld: front-paneld.c
+ $(CC) -pthread -lpal -lbic -std=c99 -o $@ $^ $(LDFLAGS)
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o front-paneld
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/front-paneld/files/front-paneld.c b/meta-facebook/meta-yosemite/recipes-yosemite/front-paneld/files/front-paneld.c
new file mode 100644
index 0000000..03849cd
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/front-paneld/files/front-paneld.c
@@ -0,0 +1,460 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <syslog.h>
+#include <string.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <time.h>
+#include <openbmc/ipmi.h>
+#include <openbmc/ipmb.h>
+#include <openbmc/pal.h>
+
+#define BTN_MAX_SAMPLES 200
+#define MAX_NUM_SLOTS 4
+
+// Helper function for msleep
+void
+msleep(int msec) {
+ struct timespec req;
+
+ req.tv_sec = 0;
+ req.tv_nsec = msec * 1000 * 1000;
+
+ while(nanosleep(&req, &req) == -1 && errno == EINTR) {
+ continue;
+ }
+}
+
+// Thread for monitoring debug card hotswap
+static void *
+debug_card_handler() {
+ int curr = -1;
+ int prev = -1;
+ uint8_t prsnt;
+ uint8_t pos;
+ uint8_t lpc;
+ int i, ret;
+
+ while (1) {
+ // Check if debug card present or not
+ ret = pal_is_debug_card_prsnt(&prsnt);
+ if (ret) {
+ goto debug_card_out;
+ }
+
+ curr = prsnt;
+ if (curr == prev) {
+ // No state change, continue
+ goto debug_card_out;
+ }
+
+ if (curr) {
+ syslog(LOG_ALERT, "Debug Card Insertion\n");
+ // Get current position of hand switch
+ ret = pal_get_hand_sw(&pos);
+ if (ret) {
+ goto debug_card_out;
+ }
+
+ // Switch USB mux based on hand switch
+ ret = pal_switch_usb_mux(pos);
+ if (ret) {
+ goto debug_card_out;
+ }
+ // Switch UART mux based on hand switch
+ ret = pal_switch_uart_mux(pos);
+ if (ret) {
+ goto debug_card_out;
+ }
+
+ // Enable POST code based on hand switch
+ if (pos == HAND_SW_BMC) {
+ // For BMC, there is no need to have POST specific code
+ goto debug_card_done;
+ }
+
+ // Make sure the server at selected position is present
+ ret = pal_is_server_prsnt(pos, &prsnt);
+ if (ret || !prsnt) {
+ goto debug_card_done;
+ }
+
+ // Enable POST codes for all slots
+ ret = pal_post_enable(pos);
+ if (ret) {
+ goto debug_card_out;
+ }
+
+ // Get last post code and display it
+ ret = pal_post_get_last(pos, &lpc);
+ if (ret) {
+ goto debug_card_out;
+ }
+
+ ret = pal_post_handle(pos, lpc);
+ if (ret) {
+ goto debug_card_out;
+ }
+ } else {
+ syslog(LOG_ALERT, "Debug Card Extraction\n");
+ // Switch UART mux to BMC
+ ret = pal_switch_uart_mux(HAND_SW_BMC);
+ if (ret) {
+ goto debug_card_out;
+ }
+ }
+debug_card_done:
+ prev = curr;
+debug_card_out:
+ sleep(1);
+ }
+}
+
+// Thread to monitor the hand switch
+static void *
+hand_sw_handler() {
+ int curr = -1;
+ int prev = -1;
+ int ret;
+ uint8_t pos;
+ uint8_t prsnt;
+ uint8_t lpc;
+
+ while (1) {
+ // Get the current hand switch position
+ ret = pal_get_hand_sw(&pos);
+ if (ret) {
+ goto hand_sw_out;
+ }
+ curr = pos;
+ if (curr == prev) {
+ // No state change, continue;
+ goto hand_sw_out;
+ }
+
+ // Switch USB Mux to selected server
+ ret = pal_switch_usb_mux(pos);
+ if (ret) {
+ goto hand_sw_out;
+ }
+
+ // If Debug Card is present, update UART MUX
+ ret = pal_is_debug_card_prsnt(&prsnt);
+ if (ret) {
+ goto hand_sw_out;
+ }
+
+ if (prsnt) {
+ // Switch UART mux based on position
+ ret = pal_switch_uart_mux(pos);
+ if (ret) {
+ goto hand_sw_out;
+ }
+
+ if (pos == HAND_SW_BMC) {
+ // For BMC, there is no need for POST enable/disable code
+ goto hand_sw_done;
+ }
+
+ ret = pal_is_server_prsnt(pos, &prsnt);
+ if (ret || !prsnt) {
+ // Server at chosen position is not present
+ goto hand_sw_done;
+ }
+
+ // Enable post for the chosen server
+ ret = pal_post_enable(pos);
+ if (ret) {
+ goto hand_sw_out;
+ }
+
+ // Get last post code and display it
+ ret = pal_post_get_last(pos, &lpc);
+ if (ret) {
+ goto hand_sw_out;
+ }
+
+ ret = pal_post_handle(pos, lpc);
+ if (ret) {
+ goto hand_sw_out;
+ }
+ }
+hand_sw_done:
+ prev = curr;
+hand_sw_out:
+ sleep(1);
+ continue;
+ }
+}
+
+// Thread to monitor Reset Button and propagate to selected server
+static void *
+rst_btn_handler() {
+ int ret;
+ uint8_t pos;
+ int i;
+ uint8_t btn;
+
+ while (1) {
+ // Check the position of hand switch
+ ret = pal_get_hand_sw(&pos);
+ if (ret || pos == HAND_SW_BMC) {
+ // For BMC, no need to handle Reset Button
+ sleep (1);
+ continue;
+ }
+
+ // Check if reset button is pressed
+ ret = pal_get_rst_btn(&btn);
+ if (ret || !btn) {
+ goto rst_btn_out;
+ }
+
+ // Pass the reset button to the selected slot
+ syslog(LOG_ALERT, "reset button pressed\n");
+ ret = pal_set_rst_btn(pos, 0);
+ if (ret) {
+ goto rst_btn_out;
+ }
+
+ // Wait for the button to be released
+ for (i = 0; i < BTN_MAX_SAMPLES; i++) {
+ ret = pal_get_rst_btn(&btn);
+ if (ret || btn) {
+ msleep(100);
+ continue;
+ }
+ syslog(LOG_ALERT, "Reset button released\n");
+ ret = pal_set_rst_btn(pos, 1);
+ goto rst_btn_out;
+ }
+
+ // handle error case
+ if (i == BTN_MAX_SAMPLES) {
+ syslog(LOG_ALERT, "Reset button seems to stuck for long time\n");
+ goto rst_btn_out;
+ }
+rst_btn_out:
+ msleep(100);
+ }
+}
+
+// Thread to handle Power Button and power on/off the selected server
+static void *
+pwr_btn_handler() {
+ int ret;
+ uint8_t pos, btn;
+ int i;
+ uint8_t power;
+
+ while (1) {
+ // Check the position of hand switch
+ ret = pal_get_hand_sw(&pos);
+ if (ret || pos == HAND_SW_BMC) {
+ sleep(1);
+ continue;
+ }
+
+ // Check if power button is pressed
+ ret = pal_get_pwr_btn(&btn);
+ if (ret || !btn) {
+ goto pwr_btn_out;
+ }
+
+ syslog(LOG_ALERT, "power button pressed\n");
+
+ // Wait for the button to be released
+ for (i = 0; i < BTN_MAX_SAMPLES; i++) {
+ ret = pal_get_pwr_btn(&btn);
+ if (ret || btn ) {
+ msleep(100);
+ continue;
+ }
+ syslog(LOG_ALERT, "power button released\n");
+ break;
+ }
+
+ // handle error case
+ if (i == BTN_MAX_SAMPLES) {
+ syslog(LOG_ALERT, "Power button seems to stuck for long time\n");
+ goto pwr_btn_out;
+ }
+
+ // Get the current power state (power on vs. power off)
+ ret = pal_get_server_power(pos, &power);
+ if (ret) {
+ goto pwr_btn_out;
+ }
+
+ // Reverse the power state of the given server
+ ret = pal_set_server_power(pos, !power);
+pwr_btn_out:
+ msleep(100);
+ }
+}
+
+// Thread to handle LED state of the server at given slot
+static void *
+led_handler(void *num) {
+ int ret;
+ uint8_t prsnt;
+ uint8_t power;
+ uint8_t pos;
+ uint8_t ident;
+ uint8_t led_blink;
+ int led_on_time, led_off_time;
+
+ uint8_t slot = (*(int*) num) + 1;
+
+ syslog(LOG_INFO, "led_handler for slot %d\n", slot);
+
+ ret = pal_is_server_prsnt(slot, &prsnt);
+ if (ret || !prsnt) {
+ // Turn off led and exit
+ ret = pal_set_led(slot, 0);
+ goto led_handler_exit;
+ }
+
+ while (1) {
+ // Get power status for this slot
+ ret = pal_get_server_power(slot, &power);
+ if (ret) {
+ sleep(1);
+ continue;
+ }
+
+ // Get hand switch position to see if this is selected server
+ ret = pal_get_hand_sw(&pos);
+ if (ret) {
+ sleep(1);
+ continue;
+ }
+
+ if (pos == slot) {
+ // This server is selcted one, set ident flag
+ ident = 1;
+ } else {
+ ident = 0;
+ }
+
+ // Update LED based on current state
+ if (ident) {
+ // If this is selected server the blink flag is one
+ led_blink = 1;
+ // update the blink rate based on power state
+ if (power) {
+ led_on_time = 900;
+ led_off_time = 100;
+ } else {
+ led_on_time = 100;
+ led_off_time = 900;
+ }
+ } else {
+ // This server is not selected one
+ led_blink = 0;
+ }
+
+ if (!led_blink) {
+ // Set the led state based on power state
+ ret = pal_set_led(slot, power);
+ goto led_handler_out;
+ }
+
+ // Since this is selected slot, start blinking the LED
+ ret = pal_set_led(slot, 1);
+ if (ret) {
+ goto led_handler_out;
+ }
+
+ msleep(led_on_time);
+
+ ret = pal_set_led(slot, 0);
+ if (ret) {
+ goto led_handler_out;
+ }
+
+ msleep(led_off_time);
+led_handler_out:
+ msleep(100);
+ }
+
+led_handler_exit:
+ free(num);
+}
+
+int
+main (int argc, char * const argv[]) {
+ pthread_t tid_hand_sw;
+ pthread_t tid_debug_card;
+ pthread_t tid_rst_btn;
+ pthread_t tid_pwr_btn;
+ pthread_t tid_leds[MAX_NUM_SLOTS];
+ int i;
+ int *ip;
+
+ daemon(1, 0);
+ openlog("front-paneld", LOG_CONS, LOG_DAEMON);
+
+ if (pthread_create(&tid_debug_card, NULL, debug_card_handler, NULL) < 0) {
+ syslog(LOG_ALERT, "pthread_create for debug card error\n");
+ exit(1);
+ }
+
+ if (pthread_create(&tid_hand_sw, NULL, hand_sw_handler, NULL) < 0) {
+ syslog(LOG_ALERT, "pthread_create for hand switch error\n");
+ exit(1);
+ }
+
+ if (pthread_create(&tid_rst_btn, NULL, rst_btn_handler, NULL) < 0) {
+ syslog(LOG_ALERT, "pthread_create for reset button error\n");
+ exit(1);
+ }
+
+ if (pthread_create(&tid_pwr_btn, NULL, pwr_btn_handler, NULL) < 0) {
+ syslog(LOG_ALERT, "pthread_create for power button error\n");
+ exit(1);
+ }
+
+ for (i = 0; i < MAX_NUM_SLOTS; i++) {
+ ip = malloc(sizeof(int));
+ *ip = i;
+ if (pthread_create(&tid_leds[i], NULL, led_handler, (void*)ip) < 0) {
+ syslog(LOG_ALERT, "pthread_create for hand switch error\n");
+ exit(1);
+ }
+ }
+
+ pthread_join(tid_debug_card, NULL);
+ pthread_join(tid_hand_sw, NULL);
+ pthread_join(tid_rst_btn, NULL);
+ pthread_join(tid_pwr_btn, NULL);
+ for (i = 0; i < MAX_NUM_SLOTS; i++) {
+ pthread_join(tid_leds[i], NULL);
+ }
+
+ return 0;
+}
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/front-paneld/files/setup-front-paneld.sh b/meta-facebook/meta-yosemite/recipes-yosemite/front-paneld/files/setup-front-paneld.sh
new file mode 100644
index 0000000..7055cc0
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/front-paneld/files/setup-front-paneld.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+#
+# Copyright 2015-present Facebook. All Rights Reserved.
+#
+### BEGIN INIT INFO
+# Provides: setup-front-paneld
+# Required-Start:
+# Required-Stop:
+# Default-Start: S
+# Default-Stop:
+# Short-Description: Start front panel control daemon
+### END INIT INFO
+
+echo -n "Setup Front Panel Daemon.."
+ /usr/local/bin/front-paneld > /dev/null 2>&1 &
+echo "done."
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/front-paneld/front-paneld_0.1.bb b/meta-facebook/meta-yosemite/recipes-yosemite/front-paneld/front-paneld_0.1.bb
new file mode 100644
index 0000000..26db659
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/front-paneld/front-paneld_0.1.bb
@@ -0,0 +1,44 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+
+SUMMARY = "Front Panel Control Daemon"
+DESCRIPTION = "Daemon to monitor and control the front panel "
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://front-paneld.c;beginline=5;endline=17;md5=da35978751a9d71b73679307c4d296ec"
+
+
+DEPENDS_append = "libpal libbic update-rc.d-native"
+
+SRC_URI = "file://Makefile \
+ file://setup-front-paneld.sh \
+ file://front-paneld.c \
+ "
+
+S = "${WORKDIR}"
+
+binfiles = "front-paneld"
+
+pkgdir = "front-paneld"
+
+do_install() {
+ dst="${D}/usr/local/fbpackages/${pkgdir}"
+ bin="${D}/usr/local/bin"
+ install -d $dst
+ install -d $bin
+ install -m 755 front-paneld ${dst}/front-paneld
+ ln -snf ../fbpackages/${pkgdir}/front-paneld ${bin}/front-paneld
+ install -d ${D}${sysconfdir}/init.d
+ install -d ${D}${sysconfdir}/rcS.d
+ install -m 755 setup-front-paneld.sh ${D}${sysconfdir}/init.d/setup-front-paneld.sh
+ update-rc.d -r ${D} setup-front-paneld.sh start 67 S .
+}
+
+FBPACKAGEDIR = "${prefix}/local/fbpackages"
+
+FILES_${PN} = "${FBPACKAGEDIR}/front-paneld ${prefix}/local/bin ${sysconfdir} "
+
+# Inhibit complaints about .debug directories:
+
+INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
+INHIBIT_PACKAGE_STRIP = "1"
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/fruid/fruid_0.1.bbappend b/meta-facebook/meta-yosemite/recipes-yosemite/fruid/fruid_0.1.bbappend
new file mode 100644
index 0000000..c87f2a7
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/fruid/fruid_0.1.bbappend
@@ -0,0 +1,24 @@
+# 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
+
+
+S = "${WORKDIR}"
+
+CFLAGS_prepend = " -DCONFIG_YOSEMITE"
+LDFLAGS_append = " -lyosemite_fruid"
+
+DEPENDS_prepend = "libyosemite-fruid"
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/gpiod/files/Makefile b/meta-facebook/meta-yosemite/recipes-yosemite/gpiod/files/Makefile
new file mode 100644
index 0000000..68e9453
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/gpiod/files/Makefile
@@ -0,0 +1,26 @@
+# 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
+
+all: gpiod
+
+sensord: gpiod.c
+ $(CC) $(CFLAGS) -D _XOPEN_SOURCE -pthread -lm -std=c99 -o $@ $^ $(LDFLAGS)
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o gpiod
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/gpiod/files/gpiod.c b/meta-facebook/meta-yosemite/recipes-yosemite/gpiod/files/gpiod.c
new file mode 100644
index 0000000..9282e00
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/gpiod/files/gpiod.c
@@ -0,0 +1,353 @@
+/*
+ * sensord
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <errno.h>
+#include <syslog.h>
+#include <stdint.h>
+#include <math.h>
+#include <string.h>
+#include <pthread.h>
+#include <sys/un.h>
+#include <sys/file.h>
+#include <openbmc/ipmi.h>
+#include <openbmc/pal.h>
+#include <facebook/bic.h>
+#include <facebook/yosemite_gpio.h>
+
+#define SETBIT(x, y) (x | (1 << y))
+#define GETBIT(x, y) ((x & (1 << y)) > y)
+#define CLEARBIT(x, y) (x & (~(1 << y)))
+#define GETMASK(y) (1 << y)
+
+#define MAX_NUM_SLOTS 4
+#define GPIOD_READ_DELAY 1
+#define SOCK_PATH_GPIO "/tmp/gpio_socket"
+
+/* To hold the gpio info and status */
+typedef struct {
+ uint8_t flag;
+ uint8_t status;
+ uint8_t ass_val;
+ char name[32];
+} gpio_pin_t;
+
+static gpio_pin_t gpio_slot1[MAX_GPIO_PINS] = {0};
+static gpio_pin_t gpio_slot2[MAX_GPIO_PINS] = {0};
+static gpio_pin_t gpio_slot3[MAX_GPIO_PINS] = {0};
+static gpio_pin_t gpio_slot4[MAX_GPIO_PINS] = {0};
+
+/* Returns the pointer to the struct holding all gpio info for the fru#. */
+static gpio_pin_t *
+get_struct_gpio_pin(uint8_t fru) {
+
+ gpio_pin_t *gpios;
+
+ switch (fru) {
+ case FRU_SLOT1:
+ gpios = gpio_slot1;
+ break;
+ case FRU_SLOT2:
+ gpios = gpio_slot2;
+ break;
+ case FRU_SLOT3:
+ gpios = gpio_slot3;
+ break;
+ case FRU_SLOT4:
+ gpios = gpio_slot4;
+ break;
+ default:
+ syslog(LOG_ALERT, "get_struct_gpio_pin: Wrong SLOT ID %d\n", fru);
+ return NULL;
+ }
+
+ return gpios;
+}
+
+int
+enable_gpio_intr_config(uint8_t fru, uint8_t gpio) {
+ int ret;
+
+ bic_gpio_config_t cfg = {0};
+ bic_gpio_config_t verify_cfg = {0};
+
+
+ ret = bic_get_gpio_config(fru, gpio, &cfg);
+ if (ret < 0) {
+ syslog(LOG_ERR, "enable_gpio_intr_config: bic_get_gpio_config failed"
+ "for slot_id: %u, gpio pin: %u", fru, gpio);
+ return -1;
+ }
+
+ cfg.ie = 1;
+
+ ret = bic_set_gpio_config(fru, gpio, &cfg);
+ if (ret < 0) {
+ syslog(LOG_ERR, "enable_gpio_intr_config: bic_set_gpio_config failed"
+ "for slot_id: %u, gpio pin: %u", fru, gpio);
+ return -1;
+ }
+
+ ret = bic_get_gpio_config(fru, gpio, &verify_cfg);
+ if (ret < 0) {
+ syslog(LOG_ERR, "enable_gpio_intr_config: verification bic_get_gpio_config"
+ "for slot_id: %u, gpio pin: %u", fru, gpio);
+ return -1;
+ }
+
+ if (verify_cfg.ie != cfg.ie) {
+ syslog(LOG_ALERT, "Slot_id: %u,Interrupt enabling FAILED for GPIO pin# %d",
+ fru, gpio);
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Enable the interrupt mode for all the gpio sensors */
+static void
+enable_gpio_intr(uint8_t fru) {
+
+ int i, ret;
+ gpio_pin_t *gpios;
+
+ gpios = get_struct_gpio_pin(fru);
+ if (gpios == NULL) {
+ syslog(LOG_ALERT, "enable_gpio_intr: get_struct_gpio_pin failed.");
+ return;
+ }
+
+ for (i = 0; i < gpio_pin_cnt; i++) {
+ ret = enable_gpio_intr_config(fru, gpio_pin_list[i]);
+ if (ret < 0) {
+ gpios[i].flag = 0;
+ syslog(LOG_ALERT, "enable_gpio_intr: Slot: %d, Pin %d interrupt enabling"
+ " failed", fru, gpio_pin_list[i]);
+ syslog(LOG_ALERT, "enable_gpio_intr: Disable check for Slot %d, Pin %d",
+ fru, gpio_pin_list[i]);
+ } else {
+ gpios[i].flag = 1;
+#ifdef DEBUG
+ syslog(LOG_ALERT, "enable_gpio_intr: Enabled check for Slot: %d, Pin %d",
+ fru, gpio_pin_list[i]);
+#endif /* DEBUG */
+ }
+ }
+}
+
+static void
+populate_gpio_pins(uint8_t fru) {
+
+ int i, ret;
+
+ gpio_pin_t *gpios;
+
+ gpios = get_struct_gpio_pin(fru);
+ if (gpios == NULL) {
+ syslog(LOG_ALERT, "populate_gpio_pins: get_struct_gpio_pin failed.");
+ return;
+ }
+
+ for(i = 0; i < gpio_pin_cnt; i++) {
+ gpios[gpio_pin_list[i]].flag = 1;
+ }
+
+
+ for(i = 0; i < MAX_GPIO_PINS; i++) {
+ if (gpios[i].flag) {
+ gpios[i].ass_val = GETBIT(gpio_ass_val, i);
+ ret = yosemite_get_gpio_name(fru, i, gpios[i].name);
+ if (ret < 0)
+ continue;
+ }
+ }
+}
+
+/* Wrapper function to configure and get all gpio info */
+static void
+init_gpio_pins() {
+ int fru;
+
+ for (fru = FRU_SLOT1; fru < (FRU_SLOT1 + MAX_NUM_SLOTS); fru++) {
+ populate_gpio_pins(fru);
+ }
+}
+
+/* Monitor the gpio pins */
+static int
+gpio_monitor_poll(uint8_t fru_flag) {
+ int i, ret;
+ uint8_t fru;
+ uint32_t revised_pins, n_pin_val, o_pin_val[MAX_NUM_SLOTS + 1] = {0};
+ gpio_pin_t *gpios;
+
+ uint32_t status;
+ bic_gpio_t gpio = {0};
+
+ /* Check for initial Asserts */
+ for (fru = 1; fru <= MAX_NUM_SLOTS; fru++) {
+ if (GETBIT(fru_flag, fru) == 0)
+ continue;
+
+ ret = bic_get_gpio(fru, &gpio);
+ if (ret) {
+ syslog(LOG_ALERT, "populate_gpio_pins: bic_get_gpio failed for "
+ " fru %u", fru);
+ continue;
+ }
+
+ gpios = get_struct_gpio_pin(fru);
+ if (gpios == NULL) {
+ syslog(LOG_ALERT, "gpio_monitor_poll: get_struct_gpio_pin failed for"
+ " fru %u", fru);
+ continue;
+ }
+
+ memcpy(&status, (uint8_t *) &gpio, sizeof(status));
+
+ o_pin_val[fru] = 0;
+
+ for (i = 0; i <= MAX_GPIO_PINS; i++) {
+
+ if (gpios[i].flag == 0)
+ continue;
+
+ gpios[i].status = GETBIT(status, i);
+
+ if (gpios[i].status)
+ o_pin_val[fru] = SETBIT(o_pin_val[fru], i);
+
+ if (gpios[i].status == gpios[i].ass_val) {
+ syslog(LOG_CRIT, "ASSERT: fru: %u, gpio pin: %-20s, num: %d",
+ fru, gpios[i].name, i);
+ }
+ }
+ }
+
+ /* Keep monitoring each fru's gpio pins every 4 * GPIOD_READ_DELAY seconds */
+ while(1) {
+ for (fru = 1; fru <= MAX_NUM_SLOTS; fru++) {
+ if (!(GETBIT(fru_flag, fru))) {
+ sleep(GPIOD_READ_DELAY);
+ continue;
+ }
+
+ gpios = get_struct_gpio_pin(fru);
+ if (gpios == NULL) {
+ syslog(LOG_ALERT, "gpio_monitor_poll: get_struct_gpio_pin failed for"
+ " fru %u", fru);
+ continue;
+ }
+
+ if ((ret = bic_get_gpio(fru, (bic_gpio_t *) &n_pin_val)) < 0) {
+ syslog(LOG_ALERT, "gpio_monitor_poll: bic_get_gpio failed for "
+ " fru %u", fru);
+ continue;
+ }
+
+ if (o_pin_val[fru] == n_pin_val) {
+ o_pin_val[fru] = n_pin_val;
+ sleep(GPIOD_READ_DELAY);
+ continue;
+ }
+
+ revised_pins = (n_pin_val ^ o_pin_val[fru]);
+
+ for (i = 0; i < MAX_GPIO_PINS; i++) {
+ if (GETBIT(revised_pins, i) & gpios[i].flag) {
+ gpios[i].status = GETBIT(n_pin_val, i);
+
+ // Check if the new GPIO val is ASSERT
+ if (gpios[i].status == gpios[i].ass_val) {
+ syslog(LOG_CRIT, "ASSERT: fru: %u, gpio pin: %-20s, num: %d",
+ fru, gpios[i].name, i);
+ } else {
+ syslog(LOG_CRIT, "DEASSERT: fru: %u, gpio pin: %-20s, num: %d",
+ fru, gpios[i].name, i);
+ }
+ }
+ }
+
+ o_pin_val[fru] = n_pin_val;
+ sleep(GPIOD_READ_DELAY);
+
+ } /* For Loop for each fru */
+ } /* while loop */
+} /* function definition*/
+
+static void
+print_usage() {
+ printf("Usage: gpiod [ %s ]\n", "slot1, slot2, slot3, slot4");
+}
+
+/* Spawns a pthread for each fru to monitor all the sensors on it */
+static void
+run_gpiod(int argc, void **argv) {
+
+ //gpio_monitor();
+
+ int i, ret;
+ uint8_t fru_flag, fru;
+
+ /* Check for which fru do we need to monitor the gpio pins */
+ fru_flag = 0;
+ for (i = 1; i < argc; i++) {
+ ret = pal_get_fru_id(argv[i], &fru);
+ if (ret < 0) {
+ print_usage();
+ exit(-1);
+ }
+ fru_flag = SETBIT(fru_flag, fru);
+ }
+
+ gpio_monitor_poll(fru_flag);
+}
+
+int
+main(int argc, void **argv) {
+ int dev, rc, pid_file;
+
+ if (argc < 2) {
+ print_usage();
+ exit(-1);
+ }
+
+ pid_file = open("/var/run/gpiod.pid", O_CREAT | O_RDWR, 0666);
+ rc = flock(pid_file, LOCK_EX | LOCK_NB);
+ if(rc) {
+ if(EWOULDBLOCK == errno) {
+ printf("Another gpiod instance is running...\n");
+ exit(-1);
+ }
+ } else {
+
+ init_gpio_pins();
+
+ daemon(0,1);
+ openlog("gpiod", LOG_CONS, LOG_DAEMON);
+ syslog(LOG_INFO, "gpiod: daemon started");
+ run_gpiod(argc, argv);
+ }
+
+ return 0;
+}
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/gpiod/files/setup-gpiod.sh b/meta-facebook/meta-yosemite/recipes-yosemite/gpiod/files/setup-gpiod.sh
new file mode 100644
index 0000000..9e532f2
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/gpiod/files/setup-gpiod.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+#
+# 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
+#
+
+### BEGIN INIT INFO
+# Provides: setup-sensord
+# Required-Start:
+# Required-Stop:
+# Default-Start: S
+# Default-Stop:
+# Short-Description: Setup sensor monitoring
+### END INIT INFO
+
+# TODO: check for the if slot/server is present before starting the daemon
+echo -n "Setup gpio monitoring for yosemite... "
+/usr/local/bin/gpiod slot1 slot2 slot3 slot4
+echo "done."
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/gpiod/gpiod_0.1.bb b/meta-facebook/meta-yosemite/recipes-yosemite/gpiod/gpiod_0.1.bb
new file mode 100644
index 0000000..2193a92
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/gpiod/gpiod_0.1.bb
@@ -0,0 +1,62 @@
+# 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
+
+SUMMARY = "GPIO Sensor Monitoring Daemon"
+DESCRIPTION = "Daemon for monitoring the gpio sensors"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://gpiod.c;beginline=4;endline=16;md5=b395943ba8a0717a83e62ca123a8d238"
+
+SRC_URI = "file://Makefile \
+ file://gpiod.c \
+ file://setup-gpiod.sh \
+ "
+
+S = "${WORKDIR}"
+
+binfiles = "gpiod \
+ "
+
+CFLAGS += " -lbic -lyosemite_gpio -lpal "
+
+DEPENDS += " libbic libyosemite-gpio libpal "
+
+pkgdir = "gpiod"
+
+do_install() {
+ dst="${D}/usr/local/fbpackages/${pkgdir}"
+ bin="${D}/usr/local/bin"
+ install -d $dst
+ install -d $bin
+ for f in ${binfiles}; do
+ install -m 755 $f ${dst}/$f
+ ln -snf ../fbpackages/${pkgdir}/$f ${bin}/$f
+ done
+ install -d ${D}${sysconfdir}/init.d
+ install -d ${D}${sysconfdir}/rcS.d
+ install -m 755 setup-gpiod.sh ${D}${sysconfdir}/init.d/setup-gpiod.sh
+ update-rc.d -r ${D} setup-gpiod.sh start 91 S .
+}
+
+FBPACKAGEDIR = "${prefix}/local/fbpackages"
+
+FILES_${PN} = "${FBPACKAGEDIR}/gpiod ${prefix}/local/bin ${sysconfdir} "
+
+
+INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
+INHIBIT_PACKAGE_STRIP = "1"
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/ipmbd/files/setup-ipmbd.sh b/meta-facebook/meta-yosemite/recipes-yosemite/ipmbd/files/setup-ipmbd.sh
new file mode 100644
index 0000000..b37d8fa
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/ipmbd/files/setup-ipmbd.sh
@@ -0,0 +1,104 @@
+#! /bin/sh
+#
+# 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
+#
+
+### BEGIN INIT INFO
+# Provides: ipmbd
+# Required-Start:
+# Required-Stop:
+# Default-Start: S
+# Default-Stop: 0 6
+# Short-Description: Provides ipmb message tx/rx service
+#
+### END INIT INFO
+
+. /usr/local/fbpackages/utils/ast-functions
+
+PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
+DAEMON=/usr/local/bin/ipmbd
+NAME=ipmbd
+DESC="IPMB Rx/Tx Daemon"
+
+test -f $DAEMON || exit 0
+
+STOPPER=
+ACTION="$1"
+
+case "$ACTION" in
+ start)
+ echo -n "Starting $DESC: "
+
+ if [ $(is_server_prsnt 1) == "1" ]; then
+ $DAEMON 3 > /dev/null 2>&1 &
+ fi
+
+ if [ $(is_server_prsnt 2) == "1" ]; then
+ $DAEMON 1 > /dev/null 2>&1 &
+ fi
+
+ if [ $(is_server_prsnt 3) == "1" ]; then
+ $DAEMON 7 > /dev/null 2>&1 &
+ fi
+
+ if [ $(is_server_prsnt 4) == "1" ]; then
+ $DAEMON 5 > /dev/null 2>&1 &
+ fi
+
+ echo "$NAME."
+ ;;
+ stop)
+ echo -n "Stopping $DESC: "
+ start-stop-daemon --stop --quiet --exec $DAEMON
+ echo "$NAME."
+ ;;
+ restart|force-reload)
+ echo -n "Restarting $DESC: "
+ start-stop-daemon --stop --quiet --exec $DAEMON
+ sleep 1
+ if [ $(is_server_prsnt 1) == "1" ]; then
+ $DAEMON 3 > /dev/null 2>&1 &
+ fi
+
+ if [ $(is_server_prsnt 2) == "1" ]; then
+ $DAEMON 1 > /dev/null 2>&1 &
+ fi
+
+ if [ $(is_server_prsnt 3) == "1" ]; then
+ $DAEMON 7 > /dev/null 2>&1 &
+ fi
+
+ if [ $(is_server_prsnt 4) == "1" ]; then
+ $DAEMON 5 > /dev/null 2>&1 &
+ fi
+
+ 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-yosemite/recipes-yosemite/ipmbd/ipmbd_0.1.bbappend b/meta-facebook/meta-yosemite/recipes-yosemite/ipmbd/ipmbd_0.1.bbappend
new file mode 100644
index 0000000..bf2af1e
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/ipmbd/ipmbd_0.1.bbappend
@@ -0,0 +1,27 @@
+# Copyright 2015-present Facebook. All Rights Reserved.
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+SRC_URI += " file://setup-ipmbd.sh \
+ "
+
+CFLAGS_prepend = " -DCONFIG_YOSEMITE"
+
+do_install() {
+ dst="${D}/usr/local/fbpackages/${pkgdir}"
+ bin="${D}/usr/local/bin"
+ install -d $dst
+ install -d $bin
+ install -m 755 ipmbd ${dst}/ipmbd
+ ln -snf ../fbpackages/${pkgdir}/ipmbd ${bin}/ipmbd
+ install -d ${D}${sysconfdir}/init.d
+ install -d ${D}${sysconfdir}/rcS.d
+ install -m 755 setup-ipmbd.sh ${D}${sysconfdir}/init.d/setup-ipmbd.sh
+ update-rc.d -r ${D} setup-ipmbd.sh start 65 S .
+}
+
+FBPACKAGEDIR = "${prefix}/local/fbpackages"
+
+FILES_${PN} = "${FBPACKAGEDIR}/ipmbd ${prefix}/local/bin ${sysconfdir} "
+
+INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
+INHIBIT_PACKAGE_STRIP = "1"
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/ipmid/files/bic.c b/meta-facebook/meta-yosemite/recipes-yosemite/ipmid/files/bic.c
new file mode 100644
index 0000000..5af03ce
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/ipmid/files/bic.c
@@ -0,0 +1,78 @@
+/* Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * This file contains code to support IPMI2.0 Specificaton available @
+ * http://www.intel.com/content/www/us/en/servers/ipmi/ipmi-specifications.html
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <openbmc/ipmi.h>
+
+#define MAX_IPMI_RES_LEN 100
+
+/*
+ * Function to handle GPIO interrupt
+ */
+void
+lib_gpio_intr_handle(unsigned char *request, unsigned char req_len,
+ unsigned char *response, unsigned char *res_len) {
+
+ int sockfd, t, len;
+ struct sockaddr_un remote;
+
+ // TODO: Need to update to reuse the socket instead of creating new
+ if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+ syslog(LOG_ALERT, "lib_gpio_intr_handle: socket() failed\n");
+ return;
+ }
+
+ remote.sun_family = AF_UNIX;
+ strcpy(remote.sun_path, SOCK_PATH_GPIO);
+ len = strlen(remote.sun_path) + sizeof(remote.sun_family);
+
+ if (connect(sockfd, (struct sockaddr *)&remote, len) == -1) {
+ syslog(LOG_ALERT, "lib_gpio_intr_handle: connect() failed\n");
+ return;
+ }
+
+ if (send(sockfd, request, req_len, 0) == -1) {
+ syslog(LOG_ALERT, "lib_gpio_intr_handle: send() failed\n");
+ return;
+ }
+
+ if ((t=recv(sockfd, response, MAX_IPMI_RES_LEN, 0)) > 0) {
+ *res_len = t;
+ } else {
+ if (t < 0) {
+ syslog(LOG_ALERT, "lib_gpio_intr_handle: recv() failed\n");
+ } else {
+ printf("Server closed connection");
+ }
+
+ return;
+ }
+
+ close(sockfd);
+
+ return;
+}
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/ipmid/files/bic.h b/meta-facebook/meta-yosemite/recipes-yosemite/ipmid/files/bic.h
new file mode 100644
index 0000000..c0fcfbb
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/ipmid/files/bic.h
@@ -0,0 +1,29 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ *
+ * 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.
+ */
+
+#ifndef __BIC_H__
+#define __BIC_H__
+
+#define SOCK_PATH_GPIO "/tmp/gpio_socket"
+
+void lib_gpio_intr_handle(unsigned char *request, unsigned char req_len,
+ unsigned char *response, unsigned char *res_len);
+
+#endif /* __BIC_H__ */
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/ipmid/files/fruid.c b/meta-facebook/meta-yosemite/recipes-yosemite/ipmid/files/fruid.c
new file mode 100644
index 0000000..04772d7
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/ipmid/files/fruid.c
@@ -0,0 +1,111 @@
+/*
+ *
+ * Copyright 2015-present Facebook. All Rights Reserved.
+ *
+ * This file provides platform specific implementation of FRUID information
+ *
+ * FRUID specification can be found at
+ * www.intel.com/content/dam/www/public/us/en/documents/product-briefs/platform-management-fru-document-rev-1-2-feb-2013.pdf
+ *
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <syslog.h>
+#include <string.h>
+#include <stdint.h>
+#include "fruid.h"
+
+#define EEPROM_SPB "/sys/class/i2c-adapter/i2c-8/8-0051/eeprom"
+
+#define BIN_SPB "/tmp/fruid_spb.bin"
+
+#define NAME_SPB "Side Plane Board"
+
+#define BUF_SIZE 1024
+
+/*
+ * copy_eeprom_to_bin - copy the eeprom to binary file im /tmp directory
+ *
+ * @eeprom_file : path for the eeprom of the device
+ * @bin_file : path for the binary file
+ *
+ * returns 0 on successful copy
+ * returns non-zero on file operation errors
+ */
+int copy_eeprom_to_bin(const char * eeprom_file, const char * bin_file) {
+
+ int eeprom;
+ int bin;
+ uint64_t tmp[BUF_SIZE];
+ ssize_t bytes_rd, bytes_wr;
+
+ errno = 0;
+
+ if (access(eeprom_file, F_OK) != -1) {
+
+ eeprom = open(eeprom_file, O_RDONLY);
+ if (eeprom == -1) {
+ syslog(LOG_ERR, "copy_eeprom_to_bin: unable to open the %s file: %s",
+ eeprom_file, strerror(errno));
+ return errno;
+ }
+
+ bin = open(bin_file, O_WRONLY | O_CREAT, 0644);
+ if (bin == -1) {
+ syslog(LOG_ERR, "copy_eeprom_to_bin: unable to create %s file: %s",
+ bin_file, strerror(errno));
+ return errno;
+ }
+
+ while ((bytes_rd = read(eeprom, tmp, BUF_SIZE)) > 0) {
+ bytes_wr = write(bin, tmp, bytes_rd);
+ if (bytes_wr != bytes_rd) {
+ syslog(LOG_ERR, "copy_eeprom_to_bin: write to %s file failed: %s",
+ bin_file, strerror(errno));
+ return errno;
+ }
+ }
+
+ close(bin);
+ close(eeprom);
+ }
+
+ return 0;
+}
+
+/* Populate the platform specific eeprom for fruid info */
+int plat_fruid_init(void) {
+
+ int ret;
+
+ ret = copy_eeprom_to_bin(EEPROM_SPB, BIN_SPB);
+
+ return ret;
+}
+
+int plat_fruid_size(void) {
+ /* TODO: Not supported yet */
+ return 0;
+}
+int plat_fruid_data(int offset, int count, unsigned char *data) {
+ /* TODO: Not supported yet */
+ return 0;
+}
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/ipmid/files/sensor.c b/meta-facebook/meta-yosemite/recipes-yosemite/ipmid/files/sensor.c
new file mode 100644
index 0000000..16cf98e
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/ipmid/files/sensor.c
@@ -0,0 +1,371 @@
+/*
+ *
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * This file provides platform specific implementation of sensor information
+ *
+ *
+ * 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.
+ */
+#include "sensor.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <syslog.h>
+#include <string.h>
+
+#define SENSOR_MGMT_MAX 1
+#define SENSOR_DISC_MAX 8
+#define SENSOR_THRESH_MAX 1
+#define SENSOR_OEM_MAX 1
+
+#define BMC_SLAVE_ADDR 0x20
+
+typedef struct {
+ unsigned char num;
+ sensor_mgmt_t sensor[SENSOR_MGMT_MAX];
+} sensor_mgmt_info_t;
+
+typedef struct {
+ unsigned char num;
+ sensor_disc_t sensor[SENSOR_DISC_MAX];
+} sensor_disc_info_t;
+
+typedef struct {
+ unsigned char num;
+ sensor_thresh_t sensor[SENSOR_THRESH_MAX];
+} sensor_thresh_info_t;
+
+typedef struct {
+ unsigned char num;
+ sensor_oem_t sensor[SENSOR_OEM_MAX];
+} sensor_oem_info_t;
+
+// Global structures
+static sensor_mgmt_info_t g_sensor_mgmt = {0};
+static sensor_disc_info_t g_sensor_disc = {0};
+static sensor_thresh_info_t g_sensor_thresh = {0};
+static sensor_oem_info_t g_sensor_oem = {0};
+
+static void
+populate_mgmt_sensors(void) {
+ sensor_mgmt_t sensor = {0};
+
+ // Add record for the AST2100 BMC
+ sensor.slave_addr = BMC_SLAVE_ADDR;
+ sensor.chan_no = 0x0; // Primary BMC controller
+
+ // Init Agent = false
+ sensor.pwr_state_init = 0x00;
+
+ // FRUID = true, SEL = true, SDR = true, Sensor = true
+ sensor.dev_caps = 0x0F;
+
+ // Device ID string
+ // Type - 0xC0: ASCII, Length - 0x09
+ sensor.str_type_len = 0xC0 + 0x09;
+ strncpy(sensor.str, "Yosemite-BMC", 0x09);
+
+ // Add this sensor to the global table
+ if (g_sensor_mgmt.num >= SENSOR_MGMT_MAX) {
+ syslog(LOG_ALERT, "populate_mgmt_sensors: num exceeded\n");
+ return;
+ }
+
+ memcpy(&g_sensor_mgmt.sensor[g_sensor_mgmt.num], &sensor, sizeof(sensor_mgmt_t));
+
+ g_sensor_mgmt.num++;
+
+ return;
+}
+
+static void
+populate_disc_sensors(void) {
+
+ sensor_disc_t sensor = {0};
+
+ // Sensor uS Status
+ // Sensor# 0x10
+ // EntitiyId# 0xD0, EntityInst# 0x00
+ // Sensor Type# Chassis 0x18
+ // Event Read/Type# OEM 0x70
+ sensor.owner= BMC_SLAVE_ADDR;
+ sensor.lun = 0x00;
+ sensor.sensor_num = 0x10;
+
+ sensor.ent_id = 0xD0;
+ sensor.ent_inst = 0x00;
+ // Enable Scanning, Enable Events
+ sensor.sensor_init = 0x63;
+ // Supports Auto Re-Arm
+ sensor.sensor_caps = 0x40;
+ sensor.sensor_type = 0x18;
+ sensor.evt_read_type = 0x70;
+ // 1-bit for CPU0 Thermal Trip
+ sensor.assert_evt_mask[0] = 0x04;
+ sensor.deassert_evt_mask[0] = 0x00;
+ sensor.read_evt_mask[0] = 0x04;
+
+ // Device ID string
+ // Type - 0xC0: ASCII, Length - 12
+ sensor.str_type_len = 0xC0 + 9;
+ strncpy(sensor.str, "uS-Status", 9);
+
+ // Add this sensor to the global table
+ if (g_sensor_disc.num >= SENSOR_DISC_MAX) {
+ syslog(LOG_ALERT, "populate_disc_sensors: num exceeded\n");
+ return;
+ }
+
+ memcpy(&g_sensor_disc.sensor[g_sensor_disc.num], &sensor, sizeof(sensor_disc_t));
+
+ g_sensor_disc.num++;
+
+ // Sensor SEL Status
+ // Sensor# 0x5F
+ // EntitiyId# 0xD0, EntityInst# 0x02
+ // Sensor Type# OEM: 0xC0
+ // Event Read/Type# Sensor Specific: 0x6F
+ sensor.owner= BMC_SLAVE_ADDR;
+ sensor.lun = 0x00;
+ sensor.sensor_num = 0x5F;
+
+ sensor.ent_id = 0xD0;
+ sensor.ent_inst = 0x02;
+ // Enable Scanning, Enable Events
+ sensor.sensor_init = 0x63;
+ // Supports Auto Re-Arm
+ sensor.sensor_caps = 0x40;
+ sensor.sensor_type = 0xC0;
+ sensor.evt_read_type = 0x6F;
+ // SEL Clear(bit1), SEL Rollover(bit8)
+ sensor.assert_evt_mask[0] = 0x02;
+ sensor.assert_evt_mask[1] = 0x01;
+ sensor.deassert_evt_mask[0] = 0x00;
+ sensor.deassert_evt_mask[1] = 0x00;
+ sensor.read_evt_mask[0] = 0x02;
+ sensor.read_evt_mask[1] = 0x01;
+
+ // Device ID string
+ // Type - 0xC0: ASCII, Length - 12
+ sensor.str_type_len = 0xC0 + 10;
+ strncpy(sensor.str, "SEL-Status", 10);
+
+ // Add this sensor to the global table
+ if (g_sensor_disc.num >= SENSOR_DISC_MAX) {
+ syslog(LOG_ALERT, "populate_disc_sensors: num exceeded\n");
+ return;
+ }
+
+ memcpy(&g_sensor_disc.sensor[g_sensor_disc.num], &sensor, sizeof(sensor_disc_t));
+
+ g_sensor_disc.num++;
+
+
+ // Sensor WDT
+ // Sensor# 0x60
+ // EntitiyId# 0xD0, EntityInst# 0x03
+ // Sensor Type# WDT2: 0x23
+ // Event Read/Type# Sensor Specific: 0x6F
+ sensor.owner= BMC_SLAVE_ADDR;
+ sensor.lun = 0x00;
+ sensor.sensor_num = 0x60;
+
+ sensor.ent_id = 0xD0;
+ sensor.ent_inst = 0x03;
+ // Enable Scanning, Enable Events
+ sensor.sensor_init = 0x63;
+ // Supports Auto Re-Arm
+ sensor.sensor_caps = 0x40;
+ sensor.sensor_type = 0x23;
+ sensor.evt_read_type = 0x6F;
+ // 5 bits for expiry, reset, pwrdown, pwrcycle, timer
+ sensor.assert_evt_mask[0] = 0x0F;
+ sensor.assert_evt_mask[1] = 0x01;
+ sensor.deassert_evt_mask[0] = 0x00;
+ sensor.deassert_evt_mask[1] = 0x00;
+ sensor.read_evt_mask[0] = 0x0F;
+ sensor.read_evt_mask[1] = 0x01;
+
+ // Device ID string
+ // Type - 0xC0: ASCII, Length - 12
+ sensor.str_type_len = 0xC0 + 3;
+ strncpy(sensor.str, "WDT", 3);
+
+ // Add this sensor to the global table
+ if (g_sensor_disc.num >= SENSOR_DISC_MAX) {
+ syslog(LOG_ALERT, "populate_disc_sensors: num exceeded\n");
+ return;
+ }
+
+ memcpy(&g_sensor_disc.sensor[g_sensor_disc.num], &sensor, sizeof(sensor_disc_t));
+
+ g_sensor_disc.num++;
+
+
+ // Sensor Chassis Pwr Sts
+ // Sensor# 0x70
+ // EntitiyId# 0x15, EntityInst# 0x00
+ // Sensor Type# OEM: 0xC8
+ // Event Read/Type# Sensor Specific: 0x6F
+ sensor.owner= BMC_SLAVE_ADDR;
+ sensor.lun = 0x00;
+ sensor.sensor_num = 0x70;
+
+ sensor.ent_id = 0x15;
+ sensor.ent_inst = 0x00;
+ // Enable Scanning, Enable Events
+ sensor.sensor_init = 0x63;
+ // Supports Auto Re-Arm
+ sensor.sensor_caps = 0x40;
+ sensor.sensor_type = 0xC8;
+ sensor.evt_read_type = 0x6F;
+ // 6 bits for pwroff, pwrcycle, pwron, softdown, ac-lost, hard-reset
+ sensor.assert_evt_mask[0] = 0x3F;
+ sensor.deassert_evt_mask[0] = 0x00;
+ sensor.read_evt_mask[0] = 0x3F;
+
+ // Device ID string
+ // Type - 0xC0: ASCII, Length - 12
+ sensor.str_type_len = 0xC0 + 13;
+ strncpy(sensor.str, "CH-Pwr-Status", 13);
+
+ // Add this sensor to the global table
+ if (g_sensor_disc.num >= SENSOR_DISC_MAX) {
+ syslog(LOG_ALERT, "populate_disc_sensors: num exceeded\n");
+ return;
+ }
+
+ memcpy(&g_sensor_disc.sensor[g_sensor_disc.num], &sensor, sizeof(sensor_disc_t));
+
+ g_sensor_disc.num++;
+
+ // Sensor CPU DIMM Hot
+ // Sensor# 0xB3
+ // EntitiyId# 0xD0, EntityInst# 0x05
+ // Sensor Type# OEM 0xC6
+ // Event Read/Type# Sensor Specific 6Fh
+ sensor.owner= BMC_SLAVE_ADDR;
+ sensor.lun = 0x00;
+ sensor.sensor_num = 0xB3;
+
+ sensor.ent_id = 0xD0;
+ sensor.ent_inst = 0x05;
+ // Enable Scanning, Enable Events
+ sensor.sensor_init = 0x63;
+ // Supports Auto Re-Arm
+ sensor.sensor_caps = 0x40;
+ sensor.sensor_type = 0xC6;
+ sensor.evt_read_type = 0x6F;
+ // Two bits for CPU Hot, DIMM Hot
+ sensor.assert_evt_mask[0] = 0x05;
+ sensor.deassert_evt_mask[0] = 0x05;
+ sensor.read_evt_mask[0] = 0x05;
+
+ // Device ID string
+ // Type - 0xC0: ASCII, Length - 12
+ sensor.str_type_len = 0xC0 + 12;
+ strncpy(sensor.str, "CPU_DIMM_HOT", 12);
+
+ // Add this sensor to the global table
+ if (g_sensor_disc.num >= SENSOR_DISC_MAX) {
+ syslog(LOG_ALERT, "populate_disc_sensors: num exceeded\n");
+ return;
+ }
+
+ memcpy(&g_sensor_disc.sensor[g_sensor_disc.num], &sensor, sizeof(sensor_disc_t));
+
+ g_sensor_disc.num++;
+
+ // Sensor PMBus Status Word Low
+ // Sensor PMBus Status Word High
+ // Sensor PMBus Status MFR
+ // Sensor PMBus Status Input
+ // Sensor NTP Status
+ // Sensor# 0xED
+ // EntitiyId# 0x35, EntityInst# 0x00
+ // Sensor Type# OEM 0xC7
+ // Event Read/Type# Sensor Specific 6Fh
+ sensor.owner= BMC_SLAVE_ADDR;
+ sensor.lun = 0x00;
+ sensor.sensor_num = 0xED;
+
+ sensor.ent_id = 0x35;
+ sensor.ent_inst = 0x00;
+ // Enable Scanning, Enable Events
+ sensor.sensor_init = 0x63;
+ // Supports Auto Re-Arm
+ sensor.sensor_caps = 0x40;
+ sensor.sensor_type = 0xC7;
+ sensor.evt_read_type = 0x6F;
+ // 1-bit for date/time sync failed
+ sensor.assert_evt_mask[0] = 0x01;
+ sensor.deassert_evt_mask[0] = 0x00;
+ sensor.read_evt_mask[0] = 0x01;
+
+ // Device ID string
+ // Type - 0xC0: ASCII, Length - 10
+ sensor.str_type_len = 0xC0 + 12;
+ strncpy(sensor.str, "NTP-Status", 10);
+
+ // Add this sensor to the global table
+ if (g_sensor_disc.num >= SENSOR_DISC_MAX) {
+ syslog(LOG_ALERT, "populate_disc_sensors: num exceeded\n");
+ return;
+ }
+
+ memcpy(&g_sensor_disc.sensor[g_sensor_disc.num], &sensor, sizeof(sensor_disc_t));
+
+ g_sensor_disc.num++;
+
+ return;
+}
+
+// Access functions for Sensor Table
+void
+plat_sensor_mgmt_info(int *p_num, sensor_mgmt_t **p_sensor) {
+ *p_num = g_sensor_mgmt.num;
+ *p_sensor = g_sensor_mgmt.sensor;
+}
+
+void
+plat_sensor_disc_info(int *p_num, sensor_disc_t **p_sensor) {
+ *p_num = g_sensor_disc.num;
+ *p_sensor = g_sensor_disc.sensor;
+}
+
+void
+plat_sensor_thresh_info(int *p_num, sensor_thresh_t **p_sensor) {
+ *p_num = g_sensor_thresh.num;
+ *p_sensor = g_sensor_thresh.sensor;
+}
+
+void
+plat_sensor_oem_info(int *p_num, sensor_oem_t **p_sensor) {
+ *p_num = g_sensor_oem.num;
+ *p_sensor = g_sensor_oem.sensor;
+}
+
+// Initialize Sensor Table
+int
+plat_sensor_init(void) {
+
+ // Populate all Sensors
+ populate_mgmt_sensors();
+ populate_disc_sensors();
+
+ return 0;
+}
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/ipmid/files/setup-ipmid.sh b/meta-facebook/meta-yosemite/recipes-yosemite/ipmid/files/setup-ipmid.sh
new file mode 100644
index 0000000..b724d70
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/ipmid/files/setup-ipmid.sh
@@ -0,0 +1,32 @@
+#!/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: setup-ipmid
+# Required-Start:
+# Required-Stop:
+# Default-Start: S
+# Default-Stop:
+# Short-Description: Set IPMI Message handler
+### END INIT INFO
+
+echo -n "Setup IPMI message handler... "
+/usr/local/bin/ipmid
+echo "done."
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/ipmid/ipmid_0.2.bbappend b/meta-facebook/meta-yosemite/recipes-yosemite/ipmid/ipmid_0.2.bbappend
new file mode 100644
index 0000000..4a92e78
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/ipmid/ipmid_0.2.bbappend
@@ -0,0 +1,46 @@
+# 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
+
+DEPENDS_append = "libipmi libfruid update-rc.d-native"
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+SRC_URI += "file://setup-ipmid.sh \
+ file://sensor.c \
+ file://fruid.c \
+ "
+
+S = "${WORKDIR}"
+
+do_install() {
+ dst="${D}/usr/local/fbpackages/${pkgdir}"
+ bin="${D}/usr/local/bin"
+ install -d $dst
+ install -d $bin
+ install -m 755 ipmid ${dst}/ipmid
+ ln -snf ../fbpackages/${pkgdir}/ipmid ${bin}/ipmid
+ install -d ${D}${sysconfdir}/init.d
+ install -d ${D}${sysconfdir}/rcS.d
+ install -m 755 setup-ipmid.sh ${D}${sysconfdir}/init.d/setup-ipmid.sh
+ update-rc.d -r ${D} setup-ipmid.sh start 64 S .
+}
+
+FBPACKAGEDIR = "${prefix}/local/fbpackages"
+
+FILES_${PN} = "${FBPACKAGEDIR}/ipmid ${prefix}/local/bin ${sysconfdir} "
+
+INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
+INHIBIT_PACKAGE_STRIP = "1"
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/lm_sensors/files/yosemite.conf b/meta-facebook/meta-yosemite/recipes-yosemite/lm_sensors/files/yosemite.conf
new file mode 100644
index 0000000..b05ec3a
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/lm_sensors/files/yosemite.conf
@@ -0,0 +1,44 @@
+
+bus "i2c-9" "ast_i2c.9"
+
+chip "tmp75-i2c-9-4e"
+ label temp1 "Inlet Temp"
+
+chip "tmp75-i2c-9-4f"
+ label temp1 "Outlet Temp"
+
+chip "ast_pwm-*"
+ label fan1 "Fan 1"
+ label fan2 "Fan 2"
+ ignore fan3
+ ignore fan4
+ ignore fan5
+ ignore fan6
+ ignore fan7
+ ignore fan8
+ ignore fan9
+ ignore fan10
+ ignore fan11
+ ignore fan12
+ ignore fan13
+ ignore fan14
+ ignore fan15
+ ignore fan16
+
+chip "ast_adc-isa-0000"
+ label in0 "P5V_STBY Voltage"
+ label in1 "P12V_STBY Voltage"
+ label in2 "P3V3_STBY Voltage"
+ label in3 "P12V_STBY_SLOT0 Voltage"
+ label in4 "P12V_STBY_SLOT1 Voltage"
+ label in5 "P12V_STBY_SLOT2 Voltage"
+ label in6 "P12V_STBY_SLOT3 Voltage"
+ label in7 "P3V3 Voltage"
+ ignore in8
+ ignore in9
+ ignore in10
+ ignore in11
+ ignore in12
+ ignore in13
+ ignore in14
+ ignore in15
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/lm_sensors/lmsensors_%.bbappend b/meta-facebook/meta-yosemite/recipes-yosemite/lm_sensors/lmsensors_%.bbappend
new file mode 100644
index 0000000..c33761e
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/lm_sensors/lmsensors_%.bbappend
@@ -0,0 +1,10 @@
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+SRC_URI += "file://yosemite.conf \
+ "
+
+do_install_append() {
+ install -d ${D}${sysconfdir}/sensors.d
+ install -m 644 ../yosemite.conf ${D}${sysconfdir}/sensors.d/yosemite.conf
+}
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/Makefile b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/Makefile
new file mode 100644
index 0000000..00464e5
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/Makefile
@@ -0,0 +1,29 @@
+# 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
+
+all: oob-nic i2craw
+
+oob-nic: main.o nic.o intf.o ll_map.o libnetlink.o
+ $(CC) -o $@ $^ $(LDFLAGS) -lwedge_eeprom
+
+i2craw: i2craw.o
+ $(CC) -o $@ $^ $(LDFLAGS)
+
+.PHONY: clean
+
+clean:
+ rm -rf *.o oob-nic i2craw
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/README b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/README
new file mode 100644
index 0000000..f46971f
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/README
@@ -0,0 +1,10 @@
+
+TODO:
+
+1. Currently, we poll the SMbus instead of rely on the ALERT. The kernel does not handle the ALERT either other than just a print out.
+
+2. Maximum fragment is 32
+
+3. We use libnetlink for bring interface up and setting MAC. That increases the binary by about 50k and also we copied about 5 files from iproute2 here for that. We might be able to get away this by using some non-iproute2 API
+
+4. The dependency in the Makefile does not consider .h
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/etc/oob-nic.sh b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/etc/oob-nic.sh
new file mode 100644
index 0000000..71ee0fa
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/etc/oob-nic.sh
@@ -0,0 +1,93 @@
+#! /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: oob-nic
+# Required-Start:
+# Required-Stop:
+# Default-Start: S
+# Default-Stop: 0 6
+# Short-Description: One of the first scripts to be executed. Starts or stops
+# the OOB NIC.
+#
+### END INIT INFO
+
+PATH=/sbin:/bin:/usr/sbin:/usr/bin
+DAEMON=/usr/sbin/oob-nic
+NAME=oob-nic
+DESC="OOB NIC Driver"
+
+# source function library
+. /etc/init.d/functions
+
+test -f $DAEMON || exit 0
+
+. /usr/local/fbpackages/utils/ast-functions
+
+fix_etc_interfaces() {
+ local intf_conf rev
+ intf_conf="/etc/network/interfaces"
+}
+
+STOPPER=
+ACTION="$1"
+
+case "$ACTION" in
+ start)
+ echo -n "Starting $DESC: "
+ if [ ! -d /dev/net ]
+ then
+ mkdir /dev/net
+ fi
+ if [ ! -f /dev/net/tun ]
+ then
+ mknod /dev/net/tun c 10 200
+ chmod 666 /dev/net/tun
+ fi
+ fix_etc_interfaces
+ $DAEMON > /dev/null 2>&1 &
+ echo "$NAME."
+ ;;
+ stop)
+ echo -n "Stopping $DESC: "
+ start-stop-daemon --stop --quiet --exec $DAEMON
+ echo "$NAME."
+ ;;
+ restart|force-reload)
+ echo -n "Restarting $DESC: "
+ start-stop-daemon --stop --quiet --exec $DAEMON
+ sleep 1
+ fix_etc_interfaces
+ $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-yosemite/recipes-yosemite/oob-nic/oob-nic/src/hlist.h b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/hlist.h
new file mode 100644
index 0000000..5e89765
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/hlist.h
@@ -0,0 +1,73 @@
+/*
+ * Note: Original file from iproute2 package
+ *
+ * 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.
+ */
+#ifndef __HLIST_H__
+#define __HLIST_H__ 1
+/* Hash list stuff from kernel */
+
+#include <stddef.h>
+
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+
+struct hlist_head {
+ struct hlist_node *first;
+};
+
+struct hlist_node {
+ struct hlist_node *next, **pprev;
+};
+
+static inline void hlist_del(struct hlist_node *n)
+{
+ struct hlist_node *next = n->next;
+ struct hlist_node **pprev = n->pprev;
+ *pprev = next;
+ if (next)
+ next->pprev = pprev;
+}
+
+static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
+{
+ struct hlist_node *first = h->first;
+ n->next = first;
+ if (first)
+ first->pprev = &n->next;
+ h->first = n;
+ n->pprev = &h->first;
+}
+
+#define hlist_for_each(pos, head) \
+ for (pos = (head)->first; pos ; pos = pos->next)
+
+
+#define hlist_for_each_safe(pos, n, head) \
+ for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
+ pos = n)
+
+#define hlist_entry_safe(ptr, type, member) \
+ ({ typeof(ptr) ____ptr = (ptr); \
+ ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
+ })
+
+#define hlist_for_each_entry(pos, head, member) \
+ for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\
+ pos; \
+ pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
+
+#endif /* __HLIST_H__ */
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/i2craw.c b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/i2craw.c
new file mode 100644
index 0000000..f9d499b
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/i2craw.c
@@ -0,0 +1,245 @@
+/*
+ * Copyright 2004-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdint.h>
+
+#include "facebook/i2c-dev.h"
+#include "facebook/log.h"
+
+void usage(const char *prog) {
+ printf("Usage: %s [options] <bus number> <slave address>\n", prog);
+ printf("\n Options:\n"
+ "\n\t-w 'bytes to write':\n"
+ "\t\t i2c write\n"
+ "\n\t-r <number of bytes to read>:\n"
+ "\t\t if 0 is provided, the first byte of read is used to determine\n"
+ "\t\t how many bytes more to read\n"
+ "\n\t-p:\n"
+ "\t\t Use PEC\n"
+ "\n\t-h:\n"
+ "\t\t Print this help\n"
+ "\n Note: if both '-w' and '-r' are specified, write will be"
+ "\n performed first, followed by read\n");
+}
+
+#define MAX_BYTES 255
+
+int g_use_pec = 0;
+int g_has_write = 0;
+int g_n_write = 0;
+uint8_t g_write_bytes[MAX_BYTES];
+int g_has_read = 0;
+int g_n_read = -1;
+uint8_t g_read_bytes[MAX_BYTES];
+uint8_t g_bus = -1;
+uint8_t g_slave_addr = 0xff;
+
+static int parse_byte_string(const char *str) {
+ const char *startptr = str;
+ char *endptr;
+ int total = 0;
+ unsigned long val;
+
+ do {
+ val = strtoul(startptr, &endptr, 0);
+ if (startptr == endptr) {
+ printf("'%s' is invalid\n", str);
+ return -1;
+ }
+ if (val > MAX_BYTES) {
+ printf("'%s' is invalid\n", str);
+ return -1;
+ }
+ g_write_bytes[total++] = val;
+ if (*endptr == '\0') {
+ break;
+ }
+ if (total >= MAX_BYTES) {
+ printf("'%s' is invalid\n", str);
+ return -1;
+ }
+ startptr = endptr;
+ } while(1);
+
+ return total;
+}
+
+static int i2c_open() {
+ int fd;
+ char fn[32];
+ int rc;
+
+ snprintf(fn, sizeof(fn), "/dev/i2c-%d", g_bus);
+ fd = open(fn, O_RDWR);
+ if (fd == -1) {
+ LOG_ERR(errno, "Failed to open i2c device %s", fn);
+ return -1;
+ }
+
+ rc = ioctl(fd, I2C_SLAVE, g_slave_addr);
+ if (rc < 0) {
+ LOG_ERR(errno, "Failed to open slave @ address 0x%x", g_slave_addr);
+ close(fd);
+ }
+
+ return fd;
+}
+
+static int i2c_io(int fd) {
+ struct i2c_rdwr_ioctl_data data;
+ struct i2c_msg msg[2];
+ int n_msg = 0;
+ int rc;
+
+ memset(&msg, 0, sizeof(msg));
+
+ if (g_has_write) {
+ msg[n_msg].addr = g_slave_addr;
+ msg[n_msg].flags = (g_use_pec) ? I2C_CLIENT_PEC : 0;
+ msg[n_msg].len = g_n_write;
+ msg[n_msg].buf = g_write_bytes;
+ n_msg++;
+ }
+
+ if (g_has_read) {
+ msg[n_msg].addr = g_slave_addr;
+ msg[n_msg].flags = I2C_M_RD
+ | ((g_use_pec) ? I2C_CLIENT_PEC : 0)
+ | ((g_n_read == 0) ? I2C_M_RECV_LEN : 0);
+ /*
+ * In case of g_n_read is 0, block length will be added by
+ * the underlying bus driver.
+ */
+ msg[n_msg].len = (g_n_read) ? g_n_read : 256;
+ msg[n_msg].buf = g_read_bytes;
+ if (g_n_read == 0) {
+ /* If we're using variable length block reads, we have to set the
+ * first byte of the buffer to at least one or the kernel complains.
+ */
+ g_read_bytes[0] = 1;
+ }
+ n_msg++;
+ }
+
+ data.msgs = msg;
+ data.nmsgs = n_msg;
+
+ rc = ioctl(fd, I2C_RDWR, &data);
+ if (rc < 0) {
+ LOG_ERR(errno, "Failed to do raw io");
+ return -1;
+ }
+
+ return 0;
+}
+
+int main(int argc, char * const argv[]) {
+ int i;
+ int fd;
+ int opt;
+ while ((opt = getopt(argc, argv, "hpw:r:")) != -1) {
+ switch (opt) {
+ case 'h':
+ usage(argv[0]);
+ return 0;
+ case 'p':
+ g_use_pec = 1;
+ break;
+ case 'w':
+ g_has_write = 1;
+ if ((g_n_write = parse_byte_string(optarg)) <= 0) {
+ usage(argv[0]);
+ return -1;
+ }
+ break;
+ case 'r':
+ g_has_read = 1;
+ g_n_read = atoi(optarg);
+ break;
+ default:
+ usage(argv[0]);
+ return -1;
+ }
+ }
+
+ /* make sure we still have arguments for bus and slave address */
+ if (optind + 2 != argc) {
+ printf("Bus or slave address is missing\n");
+ usage(argv[0]);
+ return -1;
+ }
+
+ g_bus = atoi(argv[optind]);
+ g_slave_addr = strtoul(argv[optind + 1], NULL, 0);
+ if ((g_slave_addr & 0x80)) {
+ printf("Slave address must be 7-bit\n");
+ return -1;
+ }
+
+ if (!g_has_write && !g_has_read) {
+ /* by default, read, first byte read is the length */
+ g_has_read = 1;
+ g_n_read = 0;
+ }
+
+ printf("Bus: %d\nDevice address: 0x%x\n", g_bus, g_slave_addr);
+ if (g_has_write) {
+ printf("To write %d bytes:", g_n_write);
+ for (i = 0; i < g_n_write; i++) {
+ printf(" 0x%x", g_write_bytes[i]);
+ }
+ printf("\n");
+ }
+ if (g_has_read) {
+ if (g_n_read) {
+ printf("To read %d bytes.\n", g_n_read);
+ } else {
+ printf("To read data.\n");
+ }
+ }
+
+ fd = i2c_open();
+ if (fd < 0) {
+ return -1;
+ }
+
+ if (i2c_io(fd) < 0) {
+ return -1;
+ }
+
+ if (g_has_read) {
+ printf("Received:\n ");
+ if (g_n_read == 0) {
+ g_n_read = g_read_bytes[0] + 1;
+ }
+ for (i = 0; i < g_n_read; i++) {
+ printf(" 0x%x", g_read_bytes[i]);
+ }
+ printf("\n");
+ }
+
+ return 0;
+}
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/intf.c b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/intf.c
new file mode 100644
index 0000000..5bf8480
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/intf.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include "intf.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <linux/rtnetlink.h>
+#include <linux/if.h>
+#include <linux/if_tun.h>
+#include <linux/fib_rules.h>
+
+#include "facebook/log.h"
+#include "libnetlink.h"
+#include "ll_map.h"
+
+struct oob_intf_t {
+ char oi_name[32];
+ int oi_fd;
+ int oi_ifidx;
+ uint8_t oi_mac[6];
+ struct rtnl_handle oi_rth;
+};
+
+#define TUN_DEVICE "/dev/net/tun"
+
+static int oob_intf_set_mac(oob_intf *intf, const uint8_t mac[6]) {
+ int rc;
+ struct {
+ struct nlmsghdr n;
+ struct ifinfomsg ifi;
+ char buf[256];
+ } req;
+
+ memset(&req, 0, sizeof(req));
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+ req.n.nlmsg_type = RTM_NEWLINK;
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.ifi.ifi_family = AF_UNSPEC;
+ req.ifi.ifi_index = intf->oi_ifidx;
+ memcpy(intf->oi_mac, mac, sizeof(intf->oi_mac));
+ addattr_l(&req.n, sizeof(req), IFLA_ADDRESS,
+ intf->oi_mac, sizeof(intf->oi_mac));
+ rc = rtnl_talk(&intf->oi_rth, &req.n, 0, 0, NULL);
+ if (rc < 0) {
+ rc = errno;
+ LOG_ERR(rc, "Failed to set mac to interface %s @ index %d",
+ intf->oi_name, intf->oi_ifidx);
+ return -rc;
+ }
+
+ LOG_INFO("Set interface %s @ index %d mac to %x:%x:%x:%x:%x:%x",
+ intf->oi_name, intf->oi_ifidx,
+ intf->oi_mac[0], intf->oi_mac[1], intf->oi_mac[2],
+ intf->oi_mac[3], intf->oi_mac[4], intf->oi_mac[5]);
+
+ return 0;
+}
+
+static int oob_intf_bring_up(oob_intf *intf) {
+ int rc;
+ struct {
+ struct nlmsghdr n;
+ struct ifinfomsg ifi;
+ char buf[256];
+ } req;
+
+ memset(&req, 0, sizeof(req));
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+ req.n.nlmsg_type = RTM_NEWLINK;
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.ifi.ifi_family = AF_UNSPEC;
+ req.ifi.ifi_change |= IFF_UP;
+ req.ifi.ifi_flags |= IFF_UP;
+ req.ifi.ifi_index = intf->oi_ifidx;
+ rc = rtnl_talk(&intf->oi_rth, &req.n, 0, 0, NULL);
+ if (rc < 0) {
+ rc = errno;
+ LOG_ERR(rc, "Failed to bring up interface %s @ index %d",
+ intf->oi_name, intf->oi_ifidx);
+ return -rc;
+ }
+
+ LOG_INFO("Brought up interface %s @ index %d", intf->oi_name, intf->oi_ifidx);
+
+ return 0;
+}
+
+oob_intf* oob_intf_create(const char *name, const uint8_t mac[6]) {
+
+ int rc;
+ int flags;
+ struct ifreq ifr;
+ oob_intf *intf = NULL;
+
+#define _CHECK_RC(fmt, ...) do { \
+ if (rc < 0) { \
+ rc = errno; \
+ LOG_ERR(rc, fmt, ##__VA_ARGS__); \
+ goto err_out; \
+ } \
+} while(0)
+
+ intf = malloc(sizeof(*intf));
+ if (!intf) {
+ rc = ENOMEM;
+ LOG_ERR(rc, "Failed to allocate memory for interface");
+ goto err_out;
+ }
+ memset(intf, 0, sizeof(*intf));
+ strncpy(intf->oi_name, name, sizeof(intf->oi_name));
+ intf->oi_name[sizeof(intf->oi_name) - 1] = '\0';
+ intf->oi_fd = -1;
+
+ rc = rtnl_open(&intf->oi_rth, 0);
+ _CHECK_RC("Failed to open rth_handler");
+
+ rc = open(TUN_DEVICE, O_RDWR);
+ _CHECK_RC("Failed to open %s", TUN_DEVICE);
+ intf->oi_fd = rc;
+
+ memset(&ifr, 0, sizeof(ifr));
+ /*
+ * IFF_TAP: TAP interface
+ * IFF_NO_PI: Do not provide pracket information
+ */
+ ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
+ strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
+
+ rc = ioctl(intf->oi_fd, TUNSETIFF, (void *) &ifr);
+ _CHECK_RC("Failed to create tap interface %s", ifr.ifr_name);
+
+ /* make fd non-blocking */
+ rc = fcntl(intf->oi_fd, F_GETFL);
+ _CHECK_RC("Failed to get flags from fd ", intf->oi_fd);
+ flags = rc | O_NONBLOCK;
+ rc = fcntl(intf->oi_fd, F_SETFL, rc);
+ _CHECK_RC("Failed to set non-blocking flags ", flags,
+ " to fd ", intf->oi_fd);
+
+ /* set CLOEXEC */
+ rc = fcntl(intf->oi_fd, F_GETFD);
+ _CHECK_RC("Failed to get flags from fd ", intf->oi_fd);
+ flags = rc | FD_CLOEXEC;
+ rc = fcntl(intf->oi_fd, F_SETFD, flags);
+ _CHECK_RC("Failed to set close-on-exec flags ", flags,
+ " to fd ", intf->oi_fd);
+
+ // TODO: if needed, we can adjust send buffer size, TUNSETSNDBUF
+ intf->oi_ifidx = ll_name_to_index(intf->oi_name);
+
+ /* now set the mac address */
+ oob_intf_set_mac(intf, mac);
+
+#if 0
+ /* make it persistent */
+ rc = ioctl(intf->oi_fd, TUNSETPERSIST, 0);
+ _CHECK_RC("Failed to make the tap interface %s persistent", intf->oi_name);
+#endif
+
+ LOG_INFO("Create/attach to tap interface %s @ fd %d, index %d",
+ intf->oi_name, intf->oi_fd, intf->oi_ifidx);
+
+ //oob_intf_bring_up(intf);
+
+ return intf;
+
+ err_out:
+ if (intf) {
+ rtnl_close(&intf->oi_rth);
+ if (intf->oi_fd != -1) {
+ close(intf->oi_fd);
+ }
+ free(intf);
+ }
+
+ return NULL;
+}
+
+int oob_intf_get_fd(const oob_intf *intf) {
+ return intf->oi_fd;
+}
+
+int oob_intf_receive(const oob_intf *intf, char *buf, int len) {
+ int rc;
+ do {
+ rc = read(intf->oi_fd, buf, len);
+ } while (rc == -1 && errno == EINTR);
+ if (rc < 0) {
+ rc = errno;
+ if (rc != EAGAIN) {
+ LOG_ERR(rc, "Failed to read on interface fd %d", intf->oi_fd);
+ return -rc;
+ } else {
+ /* nothing is available */
+ return 0;
+ }
+ } else if (rc == 0) {
+ // Nothing to read. It shall not happen as the fd is non-blocking.
+ // Just add this case to be safe.
+ return 0;
+ } else if (rc > len) {
+ // The pkt is larger than the buffer. We don't have complete packet.
+ // It shall not happen unless the MTU is mis-match. Drop the packet.
+ LOG_ERR(ENOSPC, "Received a too large packet (%d bytes > %d) from the "
+ "tap interface. Drop it...", rc, len);
+ return -ENOSPC;
+ } else {
+ LOG_VER("Recv a packet of %d bytes from %s", rc, intf->oi_name);
+ return rc;
+ }
+}
+
+int oob_intf_send(const oob_intf *intf, const char *buf, int len) {
+ int rc;
+ do {
+ rc = write(intf->oi_fd, buf, len);
+ } while (rc == -1 && errno == EINTR);
+ if (rc < 0) {
+ rc = errno;
+ LOG_ERR(rc, "Failed to send on interface fd %d", intf->oi_fd);
+ return -rc;
+ } else if (rc < len) {
+ LOG_ERR(EIO, "Failed to send the full packet (%d bytes > %d) for fd %d",
+ len, rc, intf->oi_fd);
+ return -EIO;
+ } else {
+ LOG_VER("Sent a packet of %d bytes to %s", rc, intf->oi_name);
+ return rc;
+ }
+}
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/intf.h b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/intf.h
new file mode 100644
index 0000000..6ea7af1
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/intf.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+#ifndef INTF_H
+#define INTF_H
+
+#include <stdint.h>
+
+typedef struct oob_intf_t oob_intf;
+
+oob_intf* oob_intf_create(const char *name, const uint8_t mac[6]);
+int oob_intf_get_fd(const oob_intf *intf);
+
+int oob_intf_receive(const oob_intf *intf, char *buf, int len);
+int oob_intf_send(const oob_intf *intf, const char *buf, int len);
+
+#endif
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/libnetlink.c b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/libnetlink.c
new file mode 100644
index 0000000..019e2c8
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/libnetlink.c
@@ -0,0 +1,717 @@
+/*
+ * Note: Original file from iproute2 package
+ *
+ * libnetlink.c RTnetlink service routines.
+ *
+ * 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.
+ *
+ * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <fcntl.h>
+#include <net/if_arp.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+#include <sys/uio.h>
+
+#include "libnetlink.h"
+
+int rcvbuf = 1024 * 1024;
+
+void rtnl_close(struct rtnl_handle *rth)
+{
+ if (rth->fd >= 0) {
+ close(rth->fd);
+ rth->fd = -1;
+ }
+}
+
+int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions,
+ int protocol)
+{
+ socklen_t addr_len;
+ int sndbuf = 32768;
+
+ memset(rth, 0, sizeof(*rth));
+
+ rth->fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, protocol);
+ if (rth->fd < 0) {
+ perror("Cannot open netlink socket");
+ return -1;
+ }
+
+ if (setsockopt(rth->fd,SOL_SOCKET,SO_SNDBUF,&sndbuf,sizeof(sndbuf)) < 0) {
+ perror("SO_SNDBUF");
+ return -1;
+ }
+
+ if (setsockopt(rth->fd,SOL_SOCKET,SO_RCVBUF,&rcvbuf,sizeof(rcvbuf)) < 0) {
+ perror("SO_RCVBUF");
+ return -1;
+ }
+
+ memset(&rth->local, 0, sizeof(rth->local));
+ rth->local.nl_family = AF_NETLINK;
+ rth->local.nl_groups = subscriptions;
+
+ if (bind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)) < 0) {
+ perror("Cannot bind netlink socket");
+ return -1;
+ }
+ addr_len = sizeof(rth->local);
+ if (getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len) < 0) {
+ perror("Cannot getsockname");
+ return -1;
+ }
+ if (addr_len != sizeof(rth->local)) {
+ fprintf(stderr, "Wrong address length %d\n", addr_len);
+ return -1;
+ }
+ if (rth->local.nl_family != AF_NETLINK) {
+ fprintf(stderr, "Wrong address family %d\n", rth->local.nl_family);
+ return -1;
+ }
+ rth->seq = time(NULL);
+ return 0;
+}
+
+int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions)
+{
+ return rtnl_open_byproto(rth, subscriptions, NETLINK_ROUTE);
+}
+
+int rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type)
+{
+ return rtnl_wilddump_req_filter(rth, family, type, RTEXT_FILTER_VF);
+}
+
+int rtnl_wilddump_req_filter(struct rtnl_handle *rth, int family, int type,
+ __u32 filt_mask)
+{
+ struct {
+ struct nlmsghdr nlh;
+ struct ifinfomsg ifm;
+ /* attribute has to be NLMSG aligned */
+ struct rtattr ext_req __attribute__ ((aligned(NLMSG_ALIGNTO)));
+ __u32 ext_filter_mask;
+ } req;
+
+ memset(&req, 0, sizeof(req));
+ req.nlh.nlmsg_len = sizeof(req);
+ req.nlh.nlmsg_type = type;
+ req.nlh.nlmsg_flags = NLM_F_DUMP|NLM_F_REQUEST;
+ req.nlh.nlmsg_pid = 0;
+ req.nlh.nlmsg_seq = rth->dump = ++rth->seq;
+ req.ifm.ifi_family = family;
+
+ req.ext_req.rta_type = IFLA_EXT_MASK;
+ req.ext_req.rta_len = RTA_LENGTH(sizeof(__u32));
+ req.ext_filter_mask = filt_mask;
+
+ return send(rth->fd, (void*)&req, sizeof(req), 0);
+}
+
+int rtnl_send(struct rtnl_handle *rth, const void *buf, int len)
+{
+ return send(rth->fd, buf, len, 0);
+}
+
+int rtnl_send_check(struct rtnl_handle *rth, const void *buf, int len)
+{
+ struct nlmsghdr *h;
+ int status;
+ char resp[1024];
+
+ status = send(rth->fd, buf, len, 0);
+ if (status < 0)
+ return status;
+
+ /* Check for immediate errors */
+ status = recv(rth->fd, resp, sizeof(resp), MSG_DONTWAIT|MSG_PEEK);
+ if (status < 0) {
+ if (errno == EAGAIN)
+ return 0;
+ return -1;
+ }
+
+ for (h = (struct nlmsghdr *)resp; NLMSG_OK(h, status);
+ h = NLMSG_NEXT(h, status)) {
+ if (h->nlmsg_type == NLMSG_ERROR) {
+ struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h);
+ if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr)))
+ fprintf(stderr, "ERROR truncated\n");
+ else
+ errno = -err->error;
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len)
+{
+ struct nlmsghdr nlh;
+ struct sockaddr_nl nladdr = { .nl_family = AF_NETLINK };
+ struct iovec iov[2] = {
+ { .iov_base = &nlh, .iov_len = sizeof(nlh) },
+ { .iov_base = req, .iov_len = len }
+ };
+ struct msghdr msg = {
+ .msg_name = &nladdr,
+ .msg_namelen = sizeof(nladdr),
+ .msg_iov = iov,
+ .msg_iovlen = 2,
+ };
+
+ nlh.nlmsg_len = NLMSG_LENGTH(len);
+ nlh.nlmsg_type = type;
+ nlh.nlmsg_flags = NLM_F_DUMP|NLM_F_REQUEST;
+ nlh.nlmsg_pid = 0;
+ nlh.nlmsg_seq = rth->dump = ++rth->seq;
+
+ return sendmsg(rth->fd, &msg, 0);
+}
+
+int rtnl_dump_filter_l(struct rtnl_handle *rth,
+ const struct rtnl_dump_filter_arg *arg)
+{
+ struct sockaddr_nl nladdr;
+ struct iovec iov;
+ struct msghdr msg = {
+ .msg_name = &nladdr,
+ .msg_namelen = sizeof(nladdr),
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ };
+ char buf[16384];
+ int dump_intr = 0;
+
+ iov.iov_base = buf;
+ while (1) {
+ int status;
+ const struct rtnl_dump_filter_arg *a;
+ int found_done = 0;
+ int msglen = 0;
+
+ iov.iov_len = sizeof(buf);
+ status = recvmsg(rth->fd, &msg, 0);
+
+ if (status < 0) {
+ if (errno == EINTR || errno == EAGAIN)
+ continue;
+ fprintf(stderr, "netlink receive error %s (%d)\n",
+ strerror(errno), errno);
+ return -1;
+ }
+
+ if (status == 0) {
+ fprintf(stderr, "EOF on netlink\n");
+ return -1;
+ }
+
+ for (a = arg; a->filter; a++) {
+ struct nlmsghdr *h = (struct nlmsghdr*)buf;
+ msglen = status;
+
+ while (NLMSG_OK(h, msglen)) {
+ int err;
+
+ if (nladdr.nl_pid != 0 ||
+ h->nlmsg_pid != rth->local.nl_pid ||
+ h->nlmsg_seq != rth->dump)
+ goto skip_it;
+
+ if (h->nlmsg_flags & NLM_F_DUMP_INTR)
+ dump_intr = 1;
+
+ if (h->nlmsg_type == NLMSG_DONE) {
+ found_done = 1;
+ break; /* process next filter */
+ }
+ if (h->nlmsg_type == NLMSG_ERROR) {
+ struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h);
+ if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
+ fprintf(stderr,
+ "ERROR truncated\n");
+ } else {
+ errno = -err->error;
+ perror("RTNETLINK answers");
+ }
+ return -1;
+ }
+ err = a->filter(&nladdr, h, a->arg1);
+ if (err < 0)
+ return err;
+
+skip_it:
+ h = NLMSG_NEXT(h, msglen);
+ }
+ }
+
+ if (found_done) {
+ if (dump_intr)
+ fprintf(stderr,
+ "Dump was interrupted and may be inconsistent.\n");
+ return 0;
+ }
+
+ if (msg.msg_flags & MSG_TRUNC) {
+ fprintf(stderr, "Message truncated\n");
+ continue;
+ }
+ if (msglen) {
+ fprintf(stderr, "!!!Remnant of size %d\n", msglen);
+ exit(1);
+ }
+ }
+}
+
+int rtnl_dump_filter(struct rtnl_handle *rth,
+ rtnl_filter_t filter,
+ void *arg1)
+{
+ const struct rtnl_dump_filter_arg a[2] = {
+ { .filter = filter, .arg1 = arg1, },
+ { .filter = NULL, .arg1 = NULL, },
+ };
+
+ return rtnl_dump_filter_l(rth, a);
+}
+
+int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer,
+ unsigned groups, struct nlmsghdr *answer)
+{
+ int status;
+ unsigned seq;
+ struct nlmsghdr *h;
+ struct sockaddr_nl nladdr;
+ struct iovec iov = {
+ .iov_base = (void*) n,
+ .iov_len = n->nlmsg_len
+ };
+ struct msghdr msg = {
+ .msg_name = &nladdr,
+ .msg_namelen = sizeof(nladdr),
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ };
+ char buf[16384];
+
+ memset(&nladdr, 0, sizeof(nladdr));
+ nladdr.nl_family = AF_NETLINK;
+ nladdr.nl_pid = peer;
+ nladdr.nl_groups = groups;
+
+ n->nlmsg_seq = seq = ++rtnl->seq;
+
+ if (answer == NULL)
+ n->nlmsg_flags |= NLM_F_ACK;
+
+ status = sendmsg(rtnl->fd, &msg, 0);
+
+ if (status < 0) {
+ perror("Cannot talk to rtnetlink");
+ return -1;
+ }
+
+ memset(buf,0,sizeof(buf));
+
+ iov.iov_base = buf;
+
+ while (1) {
+ iov.iov_len = sizeof(buf);
+ status = recvmsg(rtnl->fd, &msg, 0);
+
+ if (status < 0) {
+ if (errno == EINTR || errno == EAGAIN)
+ continue;
+ fprintf(stderr, "netlink receive error %s (%d)\n",
+ strerror(errno), errno);
+ return -1;
+ }
+ if (status == 0) {
+ fprintf(stderr, "EOF on netlink\n");
+ return -1;
+ }
+ if (msg.msg_namelen != sizeof(nladdr)) {
+ fprintf(stderr, "sender address length == %d\n", msg.msg_namelen);
+ exit(1);
+ }
+ for (h = (struct nlmsghdr*)buf; status >= sizeof(*h); ) {
+ int len = h->nlmsg_len;
+ int l = len - sizeof(*h);
+
+ if (l < 0 || len>status) {
+ if (msg.msg_flags & MSG_TRUNC) {
+ fprintf(stderr, "Truncated message\n");
+ return -1;
+ }
+ fprintf(stderr, "!!!malformed message: len=%d\n", len);
+ exit(1);
+ }
+
+ if (nladdr.nl_pid != peer ||
+ h->nlmsg_pid != rtnl->local.nl_pid ||
+ h->nlmsg_seq != seq) {
+ /* Don't forget to skip that message. */
+ status -= NLMSG_ALIGN(len);
+ h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len));
+ continue;
+ }
+
+ if (h->nlmsg_type == NLMSG_ERROR) {
+ struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h);
+ if (l < sizeof(struct nlmsgerr)) {
+ fprintf(stderr, "ERROR truncated\n");
+ } else {
+ if (!err->error) {
+ if (answer)
+ memcpy(answer, h, h->nlmsg_len);
+ return 0;
+ }
+
+ fprintf(stderr, "RTNETLINK answers: %s\n", strerror(-err->error));
+ errno = -err->error;
+ }
+ return -1;
+ }
+ if (answer) {
+ memcpy(answer, h, h->nlmsg_len);
+ return 0;
+ }
+
+ fprintf(stderr, "Unexpected reply!!!\n");
+
+ status -= NLMSG_ALIGN(len);
+ h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len));
+ }
+ if (msg.msg_flags & MSG_TRUNC) {
+ fprintf(stderr, "Message truncated\n");
+ continue;
+ }
+ if (status) {
+ fprintf(stderr, "!!!Remnant of size %d\n", status);
+ exit(1);
+ }
+ }
+}
+
+int rtnl_listen(struct rtnl_handle *rtnl,
+ rtnl_filter_t handler,
+ void *jarg)
+{
+ int status;
+ struct nlmsghdr *h;
+ struct sockaddr_nl nladdr;
+ struct iovec iov;
+ struct msghdr msg = {
+ .msg_name = &nladdr,
+ .msg_namelen = sizeof(nladdr),
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ };
+ char buf[8192];
+
+ memset(&nladdr, 0, sizeof(nladdr));
+ nladdr.nl_family = AF_NETLINK;
+ nladdr.nl_pid = 0;
+ nladdr.nl_groups = 0;
+
+ iov.iov_base = buf;
+ while (1) {
+ iov.iov_len = sizeof(buf);
+ status = recvmsg(rtnl->fd, &msg, 0);
+
+ if (status < 0) {
+ if (errno == EINTR || errno == EAGAIN)
+ continue;
+ fprintf(stderr, "netlink receive error %s (%d)\n",
+ strerror(errno), errno);
+ if (errno == ENOBUFS)
+ continue;
+ return -1;
+ }
+ if (status == 0) {
+ fprintf(stderr, "EOF on netlink\n");
+ return -1;
+ }
+ if (msg.msg_namelen != sizeof(nladdr)) {
+ fprintf(stderr, "Sender address length == %d\n", msg.msg_namelen);
+ exit(1);
+ }
+ for (h = (struct nlmsghdr*)buf; status >= sizeof(*h); ) {
+ int err;
+ int len = h->nlmsg_len;
+ int l = len - sizeof(*h);
+
+ if (l<0 || len>status) {
+ if (msg.msg_flags & MSG_TRUNC) {
+ fprintf(stderr, "Truncated message\n");
+ return -1;
+ }
+ fprintf(stderr, "!!!malformed message: len=%d\n", len);
+ exit(1);
+ }
+
+ err = handler(&nladdr, h, jarg);
+ if (err < 0)
+ return err;
+
+ status -= NLMSG_ALIGN(len);
+ h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len));
+ }
+ if (msg.msg_flags & MSG_TRUNC) {
+ fprintf(stderr, "Message truncated\n");
+ continue;
+ }
+ if (status) {
+ fprintf(stderr, "!!!Remnant of size %d\n", status);
+ exit(1);
+ }
+ }
+}
+
+int rtnl_from_file(FILE *rtnl, rtnl_filter_t handler,
+ void *jarg)
+{
+ int status;
+ struct sockaddr_nl nladdr;
+ char buf[8192];
+ struct nlmsghdr *h = (void*)buf;
+
+ memset(&nladdr, 0, sizeof(nladdr));
+ nladdr.nl_family = AF_NETLINK;
+ nladdr.nl_pid = 0;
+ nladdr.nl_groups = 0;
+
+ while (1) {
+ int err, len;
+ int l;
+
+ status = fread(&buf, 1, sizeof(*h), rtnl);
+
+ if (status < 0) {
+ if (errno == EINTR)
+ continue;
+ perror("rtnl_from_file: fread");
+ return -1;
+ }
+ if (status == 0)
+ return 0;
+
+ len = h->nlmsg_len;
+ l = len - sizeof(*h);
+
+ if (l<0 || len>sizeof(buf)) {
+ fprintf(stderr, "!!!malformed message: len=%d @%lu\n",
+ len, ftell(rtnl));
+ return -1;
+ }
+
+ status = fread(NLMSG_DATA(h), 1, NLMSG_ALIGN(l), rtnl);
+
+ if (status < 0) {
+ perror("rtnl_from_file: fread");
+ return -1;
+ }
+ if (status < l) {
+ fprintf(stderr, "rtnl-from_file: truncated message\n");
+ return -1;
+ }
+
+ err = handler(&nladdr, h, jarg);
+ if (err < 0)
+ return err;
+ }
+}
+
+int addattr(struct nlmsghdr *n, int maxlen, int type)
+{
+ return addattr_l(n, maxlen, type, NULL, 0);
+}
+
+int addattr8(struct nlmsghdr *n, int maxlen, int type, __u8 data)
+{
+ return addattr_l(n, maxlen, type, &data, sizeof(__u8));
+}
+
+int addattr16(struct nlmsghdr *n, int maxlen, int type, __u16 data)
+{
+ return addattr_l(n, maxlen, type, &data, sizeof(__u16));
+}
+
+int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data)
+{
+ return addattr_l(n, maxlen, type, &data, sizeof(__u32));
+}
+
+int addattr64(struct nlmsghdr *n, int maxlen, int type, __u64 data)
+{
+ return addattr_l(n, maxlen, type, &data, sizeof(__u64));
+}
+
+int addattrstrz(struct nlmsghdr *n, int maxlen, int type, const char *str)
+{
+ return addattr_l(n, maxlen, type, str, strlen(str)+1);
+}
+
+int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data,
+ int alen)
+{
+ int len = RTA_LENGTH(alen);
+ struct rtattr *rta;
+
+ if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) {
+ fprintf(stderr, "addattr_l ERROR: message exceeded bound of %d\n",maxlen);
+ return -1;
+ }
+ rta = NLMSG_TAIL(n);
+ rta->rta_type = type;
+ rta->rta_len = len;
+ memcpy(RTA_DATA(rta), data, alen);
+ n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
+ return 0;
+}
+
+int addraw_l(struct nlmsghdr *n, int maxlen, const void *data, int len)
+{
+ if (NLMSG_ALIGN(n->nlmsg_len) + NLMSG_ALIGN(len) > maxlen) {
+ fprintf(stderr, "addraw_l ERROR: message exceeded bound of %d\n",maxlen);
+ return -1;
+ }
+
+ memcpy(NLMSG_TAIL(n), data, len);
+ memset((void *) NLMSG_TAIL(n) + len, 0, NLMSG_ALIGN(len) - len);
+ n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + NLMSG_ALIGN(len);
+ return 0;
+}
+
+struct rtattr *addattr_nest(struct nlmsghdr *n, int maxlen, int type)
+{
+ struct rtattr *nest = NLMSG_TAIL(n);
+
+ addattr_l(n, maxlen, type, NULL, 0);
+ return nest;
+}
+
+int addattr_nest_end(struct nlmsghdr *n, struct rtattr *nest)
+{
+ nest->rta_len = (void *)NLMSG_TAIL(n) - (void *)nest;
+ return n->nlmsg_len;
+}
+
+struct rtattr *addattr_nest_compat(struct nlmsghdr *n, int maxlen, int type,
+ const void *data, int len)
+{
+ struct rtattr *start = NLMSG_TAIL(n);
+
+ addattr_l(n, maxlen, type, data, len);
+ addattr_nest(n, maxlen, type);
+ return start;
+}
+
+int addattr_nest_compat_end(struct nlmsghdr *n, struct rtattr *start)
+{
+ struct rtattr *nest = (void *)start + NLMSG_ALIGN(start->rta_len);
+
+ start->rta_len = (void *)NLMSG_TAIL(n) - (void *)start;
+ addattr_nest_end(n, nest);
+ return n->nlmsg_len;
+}
+
+int rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32 data)
+{
+ int len = RTA_LENGTH(4);
+ struct rtattr *subrta;
+
+ if (RTA_ALIGN(rta->rta_len) + len > maxlen) {
+ fprintf(stderr,"rta_addattr32: Error! max allowed bound %d exceeded\n",maxlen);
+ return -1;
+ }
+ subrta = (struct rtattr*)(((char*)rta) + RTA_ALIGN(rta->rta_len));
+ subrta->rta_type = type;
+ subrta->rta_len = len;
+ memcpy(RTA_DATA(subrta), &data, 4);
+ rta->rta_len = NLMSG_ALIGN(rta->rta_len) + len;
+ return 0;
+}
+
+int rta_addattr_l(struct rtattr *rta, int maxlen, int type,
+ const void *data, int alen)
+{
+ struct rtattr *subrta;
+ int len = RTA_LENGTH(alen);
+
+ if (RTA_ALIGN(rta->rta_len) + RTA_ALIGN(len) > maxlen) {
+ fprintf(stderr,"rta_addattr_l: Error! max allowed bound %d exceeded\n",maxlen);
+ return -1;
+ }
+ subrta = (struct rtattr*)(((char*)rta) + RTA_ALIGN(rta->rta_len));
+ subrta->rta_type = type;
+ subrta->rta_len = len;
+ memcpy(RTA_DATA(subrta), data, alen);
+ rta->rta_len = NLMSG_ALIGN(rta->rta_len) + RTA_ALIGN(len);
+ return 0;
+}
+
+int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
+{
+ return parse_rtattr_flags(tb, max, rta, len, 0);
+}
+
+int parse_rtattr_flags(struct rtattr *tb[], int max, struct rtattr *rta,
+ int len, unsigned short flags)
+{
+ unsigned short type;
+
+ memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
+ while (RTA_OK(rta, len)) {
+ type = rta->rta_type & ~flags;
+ if ((type <= max) && (!tb[type]))
+ tb[type] = rta;
+ rta = RTA_NEXT(rta,len);
+ }
+ if (len)
+ fprintf(stderr, "!!!Deficit %d, rta_len=%d\n", len, rta->rta_len);
+ return 0;
+}
+
+int parse_rtattr_byindex(struct rtattr *tb[], int max, struct rtattr *rta, int len)
+{
+ int i = 0;
+
+ memset(tb, 0, sizeof(struct rtattr *) * max);
+ while (RTA_OK(rta, len)) {
+ if (rta->rta_type <= max && i < max)
+ tb[i++] = rta;
+ rta = RTA_NEXT(rta,len);
+ }
+ if (len)
+ fprintf(stderr, "!!!Deficit %d, rta_len=%d\n", len, rta->rta_len);
+ return i;
+}
+
+int __parse_rtattr_nested_compat(struct rtattr *tb[], int max, struct rtattr *rta,
+ int len)
+{
+ if (RTA_PAYLOAD(rta) < len)
+ return -1;
+ if (RTA_PAYLOAD(rta) >= RTA_ALIGN(len) + sizeof(struct rtattr)) {
+ rta = RTA_DATA(rta) + RTA_ALIGN(len);
+ return parse_rtattr_nested(tb, max, rta);
+ }
+ memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
+ return 0;
+}
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/libnetlink.h b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/libnetlink.h
new file mode 100644
index 0000000..9e72692
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/libnetlink.h
@@ -0,0 +1,161 @@
+/*
+ * Note: Original file from iproute2 package
+ *
+ * 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.
+ */
+#ifndef __LIBNETLINK_H__
+#define __LIBNETLINK_H__ 1
+
+#include <stdio.h>
+#include <string.h>
+#include <asm/types.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/if_link.h>
+#include <linux/if_addr.h>
+#include <linux/neighbour.h>
+#include <linux/netconf.h>
+
+struct rtnl_handle
+{
+ int fd;
+ struct sockaddr_nl local;
+ struct sockaddr_nl peer;
+ __u32 seq;
+ __u32 dump;
+};
+
+extern int rcvbuf;
+
+extern int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions);
+extern int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, int protocol);
+extern void rtnl_close(struct rtnl_handle *rth);
+extern int rtnl_wilddump_request(struct rtnl_handle *rth, int fam, int type);
+extern int rtnl_wilddump_req_filter(struct rtnl_handle *rth, int fam, int type,
+ __u32 filt_mask);
+extern int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len);
+
+typedef int (*rtnl_filter_t)(const struct sockaddr_nl *,
+ struct nlmsghdr *n, void *);
+
+struct rtnl_dump_filter_arg
+{
+ rtnl_filter_t filter;
+ void *arg1;
+};
+
+extern int rtnl_dump_filter_l(struct rtnl_handle *rth,
+ const struct rtnl_dump_filter_arg *arg);
+extern int rtnl_dump_filter(struct rtnl_handle *rth, rtnl_filter_t filter,
+ void *arg);
+extern int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer,
+ unsigned groups, struct nlmsghdr *answer);
+extern int rtnl_send(struct rtnl_handle *rth, const void *buf, int);
+extern int rtnl_send_check(struct rtnl_handle *rth, const void *buf, int);
+
+extern int addattr(struct nlmsghdr *n, int maxlen, int type);
+extern int addattr8(struct nlmsghdr *n, int maxlen, int type, __u8 data);
+extern int addattr16(struct nlmsghdr *n, int maxlen, int type, __u16 data);
+extern int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data);
+extern int addattr64(struct nlmsghdr *n, int maxlen, int type, __u64 data);
+extern int addattrstrz(struct nlmsghdr *n, int maxlen, int type, const char *data);
+
+extern int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data, int alen);
+extern int addraw_l(struct nlmsghdr *n, int maxlen, const void *data, int len);
+extern struct rtattr *addattr_nest(struct nlmsghdr *n, int maxlen, int type);
+extern int addattr_nest_end(struct nlmsghdr *n, struct rtattr *nest);
+extern struct rtattr *addattr_nest_compat(struct nlmsghdr *n, int maxlen, int type, const void *data, int len);
+extern int addattr_nest_compat_end(struct nlmsghdr *n, struct rtattr *nest);
+extern int rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32 data);
+extern int rta_addattr_l(struct rtattr *rta, int maxlen, int type, const void *data, int alen);
+
+extern int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len);
+extern int parse_rtattr_flags(struct rtattr *tb[], int max, struct rtattr *rta,
+ int len, unsigned short flags);
+extern int parse_rtattr_byindex(struct rtattr *tb[], int max, struct rtattr *rta, int len);
+extern int __parse_rtattr_nested_compat(struct rtattr *tb[], int max, struct rtattr *rta, int len);
+
+#define parse_rtattr_nested(tb, max, rta) \
+ (parse_rtattr((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta)))
+
+#define parse_rtattr_nested_compat(tb, max, rta, data, len) \
+ ({ data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \
+ __parse_rtattr_nested_compat(tb, max, rta, len); })
+
+static inline __u8 rta_getattr_u8(const struct rtattr *rta)
+{
+ return *(__u8 *)RTA_DATA(rta);
+}
+static inline __u16 rta_getattr_u16(const struct rtattr *rta)
+{
+ return *(__u16 *)RTA_DATA(rta);
+}
+static inline __u32 rta_getattr_u32(const struct rtattr *rta)
+{
+ return *(__u32 *)RTA_DATA(rta);
+}
+static inline __u64 rta_getattr_u64(const struct rtattr *rta)
+{
+ __u64 tmp;
+ memcpy(&tmp, RTA_DATA(rta), sizeof(__u64));
+ return tmp;
+}
+static inline const char *rta_getattr_str(const struct rtattr *rta)
+{
+ return (const char *)RTA_DATA(rta);
+}
+
+extern int rtnl_listen(struct rtnl_handle *, rtnl_filter_t handler,
+ void *jarg);
+extern int rtnl_from_file(FILE *, rtnl_filter_t handler,
+ void *jarg);
+
+#define NLMSG_TAIL(nmsg) \
+ ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
+
+#ifndef IFA_RTA
+#define IFA_RTA(r) \
+ ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))))
+#endif
+#ifndef IFA_PAYLOAD
+#define IFA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifaddrmsg))
+#endif
+
+#ifndef IFLA_RTA
+#define IFLA_RTA(r) \
+ ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
+#endif
+#ifndef IFLA_PAYLOAD
+#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
+#endif
+
+#ifndef NDA_RTA
+#define NDA_RTA(r) \
+ ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg))))
+#endif
+#ifndef NDA_PAYLOAD
+#define NDA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ndmsg))
+#endif
+
+#ifndef NDTA_RTA
+#define NDTA_RTA(r) \
+ ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndtmsg))))
+#endif
+#ifndef NDTA_PAYLOAD
+#define NDTA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ndtmsg))
+#endif
+
+#endif /* __LIBNETLINK_H__ */
+
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/ll_map.c b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/ll_map.c
new file mode 100644
index 0000000..64e5069
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/ll_map.c
@@ -0,0 +1,225 @@
+/*
+ * Note: Original file from iproute2 package
+ *
+ * ll_map.c
+ *
+ * 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.
+ *
+ * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <net/if.h>
+
+#include "libnetlink.h"
+#include "ll_map.h"
+#include "hlist.h"
+
+struct ll_cache {
+ struct hlist_node idx_hash;
+ struct hlist_node name_hash;
+ unsigned flags;
+ int index;
+ unsigned short type;
+ char name[IFNAMSIZ];
+};
+
+#define IDXMAP_SIZE 1024
+static struct hlist_head idx_head[IDXMAP_SIZE];
+static struct hlist_head name_head[IDXMAP_SIZE];
+
+static struct ll_cache *ll_get_by_index(unsigned index)
+{
+ struct hlist_node *n;
+ unsigned h = index & (IDXMAP_SIZE - 1);
+
+ hlist_for_each(n, &idx_head[h]) {
+ struct ll_cache *im
+ = container_of(n, struct ll_cache, idx_hash);
+ if (im->index == index)
+ return im;
+ }
+
+ return NULL;
+}
+
+static unsigned namehash(const char *str)
+{
+ unsigned hash = 5381;
+
+ while (*str)
+ hash = ((hash << 5) + hash) + *str++; /* hash * 33 + c */
+
+ return hash;
+}
+
+static struct ll_cache *ll_get_by_name(const char *name)
+{
+ struct hlist_node *n;
+ unsigned h = namehash(name) & (IDXMAP_SIZE - 1);
+
+ hlist_for_each(n, &name_head[h]) {
+ struct ll_cache *im
+ = container_of(n, struct ll_cache, name_hash);
+
+ if (strncmp(im->name, name, IFNAMSIZ) == 0)
+ return im;
+ }
+
+ return NULL;
+}
+
+int ll_remember_index(const struct sockaddr_nl *who,
+ struct nlmsghdr *n, void *arg)
+{
+ unsigned int h;
+ const char *ifname;
+ struct ifinfomsg *ifi = NLMSG_DATA(n);
+ struct ll_cache *im;
+ struct rtattr *tb[IFLA_MAX+1];
+
+ if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
+ return 0;
+
+ if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifi)))
+ return -1;
+
+ im = ll_get_by_index(ifi->ifi_index);
+ if (n->nlmsg_type == RTM_DELLINK) {
+ if (im) {
+ hlist_del(&im->name_hash);
+ hlist_del(&im->idx_hash);
+ free(im);
+ }
+ return 0;
+ }
+
+ memset(tb, 0, sizeof(tb));
+ parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), IFLA_PAYLOAD(n));
+ ifname = rta_getattr_str(tb[IFLA_IFNAME]);
+ if (ifname == NULL)
+ return 0;
+
+ if (im) {
+ /* change to existing entry */
+ if (strcmp(im->name, ifname) != 0) {
+ hlist_del(&im->name_hash);
+ h = namehash(ifname) & (IDXMAP_SIZE - 1);
+ hlist_add_head(&im->name_hash, &name_head[h]);
+ }
+
+ im->flags = ifi->ifi_flags;
+ return 0;
+ }
+
+ im = malloc(sizeof(*im));
+ if (im == NULL)
+ return 0;
+ im->index = ifi->ifi_index;
+ strcpy(im->name, ifname);
+ im->type = ifi->ifi_type;
+ im->flags = ifi->ifi_flags;
+
+ h = ifi->ifi_index & (IDXMAP_SIZE - 1);
+ hlist_add_head(&im->idx_hash, &idx_head[h]);
+
+ h = namehash(ifname) & (IDXMAP_SIZE - 1);
+ hlist_add_head(&im->name_hash, &name_head[h]);
+
+ return 0;
+}
+
+const char *ll_idx_n2a(unsigned idx, char *buf)
+{
+ const struct ll_cache *im;
+
+ if (idx == 0)
+ return "*";
+
+ im = ll_get_by_index(idx);
+ if (im)
+ return im->name;
+
+ if (if_indextoname(idx, buf) == NULL)
+ snprintf(buf, IFNAMSIZ, "if%d", idx);
+
+ return buf;
+}
+
+const char *ll_index_to_name(unsigned idx)
+{
+ static char nbuf[IFNAMSIZ];
+
+ return ll_idx_n2a(idx, nbuf);
+}
+
+int ll_index_to_type(unsigned idx)
+{
+ const struct ll_cache *im;
+
+ if (idx == 0)
+ return -1;
+
+ im = ll_get_by_index(idx);
+ return im ? im->type : -1;
+}
+
+unsigned ll_index_to_flags(unsigned idx)
+{
+ const struct ll_cache *im;
+
+ if (idx == 0)
+ return 0;
+
+ im = ll_get_by_index(idx);
+ return im ? im->flags : -1;
+}
+
+unsigned ll_name_to_index(const char *name)
+{
+ const struct ll_cache *im;
+ unsigned idx;
+
+ if (name == NULL)
+ return 0;
+
+ im = ll_get_by_name(name);
+ if (im)
+ return im->index;
+
+ idx = if_nametoindex(name);
+ if (idx == 0)
+ sscanf(name, "if%u", &idx);
+ return idx;
+}
+
+void ll_init_map(struct rtnl_handle *rth)
+{
+ static int initialized;
+
+ if (initialized)
+ return;
+
+ if (rtnl_wilddump_request(rth, AF_UNSPEC, RTM_GETLINK) < 0) {
+ perror("Cannot send dump request");
+ exit(1);
+ }
+
+ if (rtnl_dump_filter(rth, ll_remember_index, NULL) < 0) {
+ fprintf(stderr, "Dump terminated\n");
+ exit(1);
+ }
+
+ initialized = 1;
+}
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/ll_map.h b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/ll_map.h
new file mode 100644
index 0000000..d74a46f
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/ll_map.h
@@ -0,0 +1,32 @@
+/*
+ * Note: Original file from iproute2 package
+ *
+ * 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.
+ */
+
+#ifndef __LL_MAP_H__
+#define __LL_MAP_H__ 1
+
+extern int ll_remember_index(const struct sockaddr_nl *who,
+ struct nlmsghdr *n, void *arg);
+
+extern void ll_init_map(struct rtnl_handle *rth);
+extern unsigned ll_name_to_index(const char *name);
+extern const char *ll_index_to_name(unsigned idx);
+extern const char *ll_idx_n2a(unsigned idx, char *buf);
+extern int ll_index_to_type(unsigned idx);
+extern unsigned ll_index_to_flags(unsigned idx);
+
+#endif /* __LL_MAP_H__ */
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/main.c b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/main.c
new file mode 100644
index 0000000..4312402
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/main.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/errno.h>
+
+#include "nic.h"
+#include "intf.h"
+
+#include "facebook/log.h"
+#include "facebook/wedge_eeprom.h"
+
+#define WAIT4PACKET_TIMEOUT 10000 /* 10ms */
+#define NO_RCV_CHECK_THRESHOLD 100 /* if not receiving pkt for 100 times (1s),
+ * check the NIC status
+ */
+
+static void io_loop(oob_nic *nic, oob_intf *intf, const uint8_t mac[6]) {
+
+ fd_set rfds;
+ int fd = oob_intf_get_fd(intf);
+ struct timeval timeout;
+ int rc;
+ int n_fds;
+ int n_io;
+ char buf[NIC_PKT_SIZE_MAX];
+ int no_rcv = 0;
+ struct oob_nic_status_t sts;
+
+ while (1) {
+ memset(&timeout, 0, sizeof(timeout));
+ timeout.tv_sec = 0;
+ timeout.tv_usec = WAIT4PACKET_TIMEOUT;
+
+ FD_ZERO(&rfds);
+ FD_SET(fd, &rfds);
+
+ n_fds = select(fd + 1, &rfds, NULL, NULL, &timeout);
+ if (n_fds < 0) {
+ rc = errno;
+ LOG_ERR(rc, "Failed to select");
+ continue;
+ }
+
+ /*
+ * no matter what, receive packet from nic first, as the nic
+ * has small amount of memory. Without read, the sending could
+ * fail due to OOM.
+ *
+ * TODO: We might want to do something smart here to prevent attack or
+ * just rx flooding. Disable the Receive Enable first, drain the buffer
+ * with oob_nic_receive(), then Tx, and enable Receive Enable after.
+ */
+ for (n_io = 0; n_io < 16; n_io++) {
+ rc = oob_nic_receive(nic, buf, sizeof(buf));
+ if (rc <= 0) {
+ no_rcv++;
+ break;
+ }
+ oob_intf_send(intf, buf, rc);
+ no_rcv = 0;
+ }
+
+ /*
+ * if we didn't receive any packet for NO_RCV_CHECK_THRESHOLD times,
+ * check the nic status
+ */
+ if (no_rcv >= NO_RCV_CHECK_THRESHOLD) {
+ while(oob_nic_get_status(nic, &sts)) {
+ usleep(1000);
+ }
+ LOG_INFO("Failed to receive packets for %d times. NIC status is "
+ "%x.%x", NO_RCV_CHECK_THRESHOLD, sts.ons_byte1, sts.ons_byte2);
+ /*
+ * if the NIC went through initialization, or not set force up, need to
+ * re-program the filters by calling oob_nic_start().
+ */
+ if ((sts.ons_byte1 & NIC_STATUS_D1_INIT)
+ || !(sts.ons_byte1 & NIC_STATUS_D1_FORCE_UP)) {
+ while(oob_nic_start(nic, mac)) {
+ usleep(1000);
+ }
+ }
+ no_rcv = 0;
+ }
+
+ if (n_fds > 0 && FD_ISSET(fd, &rfds)) {
+ for (n_io = 0; n_io < 1; n_io++) {
+ rc = oob_intf_receive(intf, buf, sizeof(buf));
+ if (rc <= 0) {
+ break;
+ }
+ oob_nic_send(nic, buf, rc);
+ }
+ }
+ }
+}
+
+int main(int argc, const char **argv) {
+
+ uint8_t mac[6];
+ oob_nic *nic;
+ oob_intf *intf;
+ struct wedge_eeprom_st eeprom;
+ int rc;
+ int from_eeprom = 0;
+
+ nic = oob_nic_open(0, 0x49);
+ if (!nic) {
+ return -1;
+ }
+
+ /* read EEPROM for the MAC */
+ if (wedge_eeprom_parse(NULL, &eeprom) == 0) {
+ if (eeprom.fbw_mac_size <= 0) {
+ LOG_ERR(EFAULT, "Invalid extended MAC size: %d", eeprom.fbw_mac_size);
+ } else {
+ uint16_t carry;
+ int pos;
+ /* use the last MAC address from the extended MAC range */
+ memcpy(mac, eeprom.fbw_mac_base, sizeof(mac));
+ if (eeprom.fbw_mac_size > 128) {
+ LOG_ERR(EFAULT, "Extended MAC size (%d) is too large.",
+ eeprom.fbw_mac_size);
+ carry = 127;
+ } else {
+ /*
+ * hack around bug device which have the same MAC address on
+ * left and right.
+ */
+ if (strncmp(eeprom.fbw_location, "LEFT", FBW_EEPROM_F_LOCATION) == 0) {
+ carry = eeprom.fbw_mac_size - 2;
+ } else {
+ carry = eeprom.fbw_mac_size - 1;
+ }
+ }
+ for (pos = sizeof(mac) - 1; pos >= 0 && carry; pos--) {
+ uint16_t tmp = mac[pos] + carry;
+ mac[pos] = tmp & 0xFF;
+ carry = tmp >> 8;
+ }
+ from_eeprom = 1;
+ }
+ }
+
+ if (!from_eeprom) {
+ while (oob_nic_get_mac(nic, mac)) {
+ usleep(1000);
+ }
+ /*
+ * increase the last byte of the mac by 1 and turn on the
+ * local administered bit to use it as the oob nic mac
+ */
+ mac[0] |= 0x2;
+ mac[5]++;
+ }
+
+ LOG_INFO("Retrieve MAC %x:%x:%x:%x:%x:%x from %s",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
+ (from_eeprom) ? "EEPROM" : "NIC");
+
+ /* create the tap interface */
+ intf = oob_intf_create("oob", mac);
+ if (!intf) {
+ return -1;
+ }
+
+ while (oob_nic_start(nic, mac)) {
+ usleep(1000);
+ }
+
+ io_loop(nic, intf, mac);
+
+ return 0;
+}
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/nic.c b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/nic.c
new file mode 100644
index 0000000..a4dc071
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/nic.c
@@ -0,0 +1,487 @@
+/*
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+#include "nic.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "facebook/i2c-dev.h"
+#include "facebook/log.h"
+
+struct oob_nic_t {
+ int on_bus;
+ uint8_t on_addr;
+ int on_file; /* the file descriptor */
+ uint8_t on_mac[6]; /* the mac address assigned to this NIC */
+};
+
+oob_nic* oob_nic_open(int bus, uint8_t addr) {
+ oob_nic *dev = NULL;
+ char fn[32];
+ int rc;
+
+ /* address must be 7 bits maximum */
+ if ((addr & 0x80)) {
+ LOG_ERR(EINVAL, "Address 0x%x has the 8th bit", addr);
+ return NULL;
+ }
+
+ dev = calloc(1, sizeof(*dev));
+ if (!dev) {
+ return NULL;
+ }
+ dev->on_bus = bus;
+ dev->on_addr = addr;
+
+ /* construct the device file name */
+ snprintf(fn, sizeof(fn), "/dev/i2c-%d", bus);
+ dev->on_file = open(fn, O_RDWR);
+ if (dev->on_file == -1) {
+ LOG_ERR(errno, "Failed to open i2c device %s", fn);
+ goto err_out;
+ }
+
+ /* assign the device address */
+ rc = ioctl(dev->on_file, I2C_SLAVE, dev->on_addr);
+ if (rc < 0) {
+ LOG_ERR(errno, "Failed to open slave @ address 0x%x", dev->on_addr);
+ goto err_out;
+ }
+
+ return dev;
+
+ err_out:
+ oob_nic_close(dev);
+ return NULL;
+}
+
+void oob_nic_close(oob_nic *dev) {
+ if (!dev) {
+ return;
+ }
+ if (dev->on_file != -1) {
+ close(dev->on_file);
+ }
+ free(dev);
+}
+
+int oob_nic_get_mac(oob_nic *dev, uint8_t mac[6]) {
+ int rc;
+ uint8_t buf[64];
+
+ rc = i2c_smbus_read_block_data(dev->on_file, NIC_READ_MAC_CMD, buf);
+ if (rc < 0) {
+ rc = errno;
+ LOG_ERR(rc, "Failed to get MAC on %d-%x",
+ dev->on_bus, dev->on_addr);
+ return -rc;
+ }
+
+ if (rc != NIC_READ_MAC_RES_LEN) {
+ LOG_ERR(EFAULT, "Unexpected response len (%d) for get MAC on %d-%x",
+ rc, dev->on_bus, dev->on_addr);
+ return -EFAULT;
+ }
+
+ if (buf[0] != NIC_READ_MAC_RES_OPT) {
+ LOG_ERR(EFAULT, "Unexpected response opt code (0x%x) get MAC on %d-%x",
+ buf[0], dev->on_bus, dev->on_addr);
+ return -EFAULT;
+ }
+
+ memcpy(mac, &buf[1], 6);
+
+ LOG_DBG("Get MAC on %d-%x: %x:%x:%x:%x:%x:%x", dev->on_bus, dev->on_addr,
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+ return 0;
+}
+
+int oob_nic_get_status(oob_nic *dev, oob_nic_status *status) {
+ int rc;
+ uint8_t buf[64];
+
+ rc = i2c_smbus_read_block_data(dev->on_file, NIC_READ_STATUS_CMD, buf);
+ if (rc < 0) {
+ rc = errno;
+ LOG_ERR(rc, "Failed to get status on %d-%x",
+ dev->on_bus, dev->on_addr);
+ return -rc;
+ }
+
+ if (rc != NIC_READ_STATUS_RES_LEN) {
+ LOG_ERR(EFAULT, "Unexpected response len (%d) for get status on %d-%x",
+ rc, dev->on_bus, dev->on_addr);
+ return -EFAULT;
+ }
+
+ if (buf[0] != NIC_READ_STATUS_RES_OPT) {
+ LOG_ERR(EFAULT, "Unexpected response opt code (0x%x) get status on %d-%x",
+ buf[0], dev->on_bus, dev->on_addr);
+ return -EFAULT;
+ }
+
+ memset(status, 0, sizeof(*status));
+ status->ons_byte1 = buf[1];
+ status->ons_byte2 = buf[2];
+
+ LOG_VER("Get status on %d-%x: byte1:0x%x byte2:0x%x",
+ dev->on_bus, dev->on_addr,
+ status->ons_byte1, status->ons_byte2);
+ return 0;
+}
+
+int oob_nic_receive(oob_nic *dev, uint8_t *buf, int len) {
+
+ int rc = 0;
+ uint8_t pkt[I2C_SMBUS_BLOCK_LARGE_MAX];
+ uint8_t opt;
+ int copied = 0;
+ int to_copy;
+ int expect_first = 1;
+ int n_frags = 0;
+
+#define _COPY_DATA(n, data) do { \
+ int to_copy; \
+ if (copied >= len) { \
+ break; \
+ } \
+ to_copy = (n < len - copied) ? n : len - copied; \
+ if (to_copy) { \
+ memcpy(buf + copied, data, to_copy); \
+ } \
+ copied += to_copy; \
+} while(0)
+
+ do {
+ rc = i2c_smbus_read_block_large_data(dev->on_file, NIC_READ_PKT_CMD, pkt);
+ if (rc < 0) {
+ rc = errno;
+ LOG_ERR(rc, "Failed to get packet on %d-%x",
+ dev->on_bus, dev->on_addr);
+ goto err_out;
+ }
+ if (rc > I2C_SMBUS_BLOCK_LARGE_MAX) {
+ LOG_ERR(EFAULT, "Too large i2c block (%d) received on %d-%x",
+ rc, dev->on_bus, dev->on_addr);
+ rc = EFAULT;
+ goto err_out;
+ }
+ opt = pkt[0];
+ switch (opt) {
+ case NIC_READ_PKT_RES_FIRST_OPT:
+ if (!expect_first) {
+ rc = EFAULT;
+ LOG_ERR(rc, "Received more than one buffer with FIRST set");
+ goto err_out;
+ }
+ expect_first = 0;
+ n_frags++;
+ _COPY_DATA(rc - 1, &pkt[1]);
+ break;
+ case NIC_READ_PKT_RES_MIDDLE_OPT:
+ if (expect_first) {
+ rc = EFAULT;
+ LOG_ERR(rc, "Received MIDDLE before getting FIRST");
+ goto err_out;
+ }
+ _COPY_DATA(rc - 1, &pkt[1]);
+ n_frags++;
+ break;
+ case NIC_READ_PKT_RES_LAST_OPT:
+ if (expect_first) {
+ rc = EFAULT;
+ LOG_ERR(rc, "Received LAST before getting FIRST");
+ goto err_out;
+ }
+ if (rc != NIC_READ_PKT_RES_LAST_LEN) {
+ LOG_ERR(EFAULT, "Expect %d bytes (got %d) for LAST segement",
+ NIC_READ_PKT_RES_LAST_LEN, rc);
+ rc = EFAULT;
+ goto err_out;
+ }
+ /* TODO: pkt status???? */
+ break;
+ case NIC_READ_STATUS_RES_OPT:
+ /* that means no pkt available */
+ if (!expect_first) {
+ rc = EFAULT;
+ LOG_ERR(rc, "Received STATUS in the middle of packet");
+ goto err_out;
+ }
+ //LOG_VER("Received STATUS when receiving the packet");
+ return 0;
+ default:
+ rc = EFAULT;
+ LOG_ERR(rc, "Unexpected opt code 0x%x", opt);
+ goto err_out;
+ }
+ } while (opt != NIC_READ_PKT_RES_LAST_OPT);
+
+ LOG_VER("Received a packet with %d bytes in %d fragments", copied, n_frags);
+ return copied;
+
+ err_out:
+ return -rc;
+#undef _COPY_DATA
+}
+
+int oob_nic_send(oob_nic *dev, const uint8_t *data, int len) {
+
+ int rc;
+ uint8_t to_send;
+ int has_sent = 0;
+ int is_first = 1;
+ uint8_t cmd;
+ int n_frags = 0;
+
+ if (len <= 0 || len > NIC_PKT_SIZE_MAX) {
+ rc = EINVAL;
+ LOG_ERR(rc, "Invalid packet length %d", len);
+ return -rc;
+ }
+
+ while (len) {
+ to_send = (len < OOB_NIC_PKT_FRAGMENT_SIZE)
+ ? len : OOB_NIC_PKT_FRAGMENT_SIZE;
+
+ if (is_first) {
+ if (to_send >= len) {
+ /* this is the last pkt also */
+ cmd = NIC_WRITE_PKT_SINGLE_CMD;
+ } else {
+ cmd = NIC_WRITE_PKT_FIRST_CMD;
+ }
+ is_first = 0;
+ } else {
+ if (to_send >= len) {
+ /* this is the last pkt */
+ cmd = NIC_WRITE_PKT_LAST_CMD;
+ } else {
+ cmd = NIC_WRITE_PKT_MIDDLE_CMD;
+ }
+ }
+
+ rc = i2c_smbus_write_block_large_data(dev->on_file, cmd,
+ to_send, data + has_sent);
+ if (rc < 0) {
+ rc = errno;
+ LOG_ERR(rc, "Failed to sent packet with cmd 0x%x, has_sent=%d "
+ "to_send=%d", cmd, has_sent, to_send);
+ return -rc;
+ }
+
+ has_sent += to_send;
+ len -= to_send;
+ n_frags++;
+ }
+
+ LOG_VER("Sent a packet with %d bytes in %d fragments", has_sent, n_frags);
+
+ return has_sent;
+}
+
+static int oob_nic_set_mng_ctrl(oob_nic *dev, const uint8_t *data, int len) {
+ int rc;
+
+ if (len <= 0) {
+ rc = EINVAL;
+ LOG_ERR(rc, "Invalid data length: %d", len);
+ return -rc;
+ }
+
+ rc = i2c_smbus_write_block_data(dev->on_file, NIC_WRITE_MNG_CTRL_CMD,
+ len, data);
+ if (rc < 0) {
+ rc = errno;
+ LOG_ERR(rc, "Failed to send management control command for parameter # %d",
+ data[0]);
+ return -rc;
+ }
+
+ return 0;
+}
+
+static int oob_nic_set_force_up(oob_nic *dev, int enable) {
+ uint8_t cmd[2];
+
+ cmd[0] = NIC_MNG_CTRL_KEEP_LINK_UP_NUM;
+ cmd[1] = enable
+ ? NIC_MNG_CTRL_KEEP_LINK_UP_ENABLE : NIC_MNG_CTRL_KEEP_LINK_UP_DISABLE;
+
+ LOG_DBG("Turn %s link force up", enable ? "on" : "off");
+ return oob_nic_set_mng_ctrl(dev, cmd, sizeof(cmd));
+}
+
+static int oob_nic_setup_filters(oob_nic *dev, const uint8_t mac[6]) {
+ int rc;
+ int i;
+ uint32_t cmd32;
+ uint8_t buf[32];
+ uint8_t *cmd;
+
+ /*
+ * Command to set MAC filter
+ * Seven bytes are required to load the MAC address filters.
+ * Data 2—MAC address filters pair number (3:0).
+ * Data 3—MSB of MAC address.
+ * ...
+ * Data 8: LSB of MAC address.
+ */
+ /* set MAC filter to pair 0 */
+ cmd = buf;
+ *cmd++ = NIC_FILTER_MAC_NUM;
+ *cmd++ = NIC_FILTER_MAC_PAIR0; /* pair 0 */
+ for (i = 0; i < 6; i++) {
+ *cmd++ = mac[i];
+ }
+ rc = i2c_smbus_write_block_data(dev->on_file, NIC_WRITE_FILTER_CMD,
+ cmd - buf, buf);
+ if (rc < 0) {
+ rc = errno;
+ LOG_ERR(rc, "Failed to set MAC filter");
+ return -rc;
+ }
+
+ /*
+ * Command to enable filter
+ *
+ * 9 bytes to load the extended decision filters (MDEF_EXT & MDEF)
+ * Data 2—MDEF filter index (valid values are 0...6)
+ * Data 3—MSB of MDEF_EXT (DecisionFilter0)
+ * ....
+ * Data 6—LSB of MDEF_EXT (DecisionFilter0)
+ * Data 7—MSB of MDEF (DecisionFilter0)
+ * ....
+ * Data 10—LSB of MDEF (DecisionFilter0)
+ */
+
+ /* enable MAC filter pair 0 on filter 0 */
+ cmd = buf;
+ *cmd++ = NIC_FILTER_DECISION_EXT_NUM;
+ *cmd++ = NIC_FILTER_MDEF0;
+ /* enable filter for traffic from network and host */
+ cmd32 = NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_EXT_NET_EN_OFFSET)
+ | NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_EXT_HOST_EN_OFFSET);
+ for (i = 0; i < sizeof(cmd32); i++) {
+ *cmd++ = (cmd32 >> (24 - 8 * i)) & 0xFF;
+ }
+ /* enable mac pair 0 */
+ cmd32 = NIC_FILTER_MDEF_BIT_VAL(NIC_FILTER_MDEF_MAC_AND_OFFSET,
+ NIC_FILTER_MAC_PAIR0);
+ for (i = 0; i < sizeof(cmd32); i++) {
+ *cmd++ = (cmd32 >> (24 - 8 * i)) & 0xFF;
+ }
+ rc = i2c_smbus_write_block_data(dev->on_file, NIC_WRITE_FILTER_CMD,
+ cmd - buf, buf);
+ if (rc < 0) {
+ rc = errno;
+ LOG_ERR(rc, "Failed to set MAC filter to MDEF 0");
+ return -rc;
+ }
+ /* enable ARP and ND on filter 1*/
+ cmd = buf;
+ *cmd++ = NIC_FILTER_DECISION_EXT_NUM;
+ *cmd++ = NIC_FILTER_MDEF1;
+ /* enable filter for traffic from network and host */
+ cmd32 = NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_EXT_NET_EN_OFFSET)
+ | NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_EXT_HOST_EN_OFFSET);
+ for (i = 0; i < sizeof(cmd32); i++) {
+ *cmd++ = (cmd32 >> (24 - 8 * i)) & 0xFF;
+ }
+ /* enable ARP and ND */
+ cmd32 = NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_ARP_REQ_OR_OFFSET)
+ | NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_ARP_RES_OR_OFFSET)
+ | NIC_FILTER_MDEF_BIT(NIC_FILTER_MDEF_NBG_OR_OFFSET);
+ for (i = 0; i < sizeof(cmd32); i++) {
+ *cmd++ = (cmd32 >> (24 - 8 * i)) & 0xFF;
+ }
+ rc = i2c_smbus_write_block_data(dev->on_file, NIC_WRITE_FILTER_CMD,
+ cmd - buf, buf);
+ if (rc < 0) {
+ rc = errno;
+ LOG_ERR(rc, "Failed to set ARP and ND filter to MDEF 1");
+ return -rc;
+ }
+
+ /* make filter 0, matching MAC, to be mng only */
+ cmd = buf;
+ *cmd++ = NIC_FILTER_MNG_ONLY_NUM;
+ cmd32 = NIC_FILTER_MNG_ONLY_FILTER0;
+ for (i = 0; i < sizeof(cmd32); i++) {
+ *cmd++ = (cmd32 >> (24 - 8 * i)) & 0xFF;
+ }
+ rc = i2c_smbus_write_block_data(dev->on_file, NIC_WRITE_FILTER_CMD,
+ cmd - buf, buf);
+ if (rc < 0) {
+ rc = errno;
+ LOG_ERR(rc, "Failed to enabled management only filter");
+ return -rc;
+ }
+
+ return 0;
+}
+
+int oob_nic_start(oob_nic *dev, const uint8_t mac[6]) {
+ int rc;
+ uint8_t cmd;
+
+ /* force the link up, no matter what the status of the main link */
+ rc = oob_nic_set_force_up(dev, 1);
+ if (rc != 0) {
+ return rc;
+ }
+
+ oob_nic_setup_filters(dev, mac);
+
+ /* first byte is the control */
+ cmd = NIC_WRITE_RECV_ENABLE_EN
+ | NIC_WRITE_RECV_ENABLE_STA
+ | NIC_WRITE_RECV_ENABLE_NM_UNSUPP /* TODO, to support ALERT */
+ | NIC_WRITE_RECV_ENABLE_RESERVED;
+
+ rc = i2c_smbus_write_block_data(dev->on_file, NIC_WRITE_RECV_ENABLE_CMD,
+ 1, &cmd);
+ if (rc < 0) {
+ rc = errno;
+ LOG_ERR(rc, "Failed to start receive function");
+ return -rc;
+ }
+ LOG_DBG("Started receive function");
+ return 0;
+}
+
+int oob_nic_stop(oob_nic *dev) {
+ int rc;
+ uint8_t ctrl;
+ /* don't set any enable bits, which turns off the receive func */
+ ctrl = NIC_WRITE_RECV_ENABLE_RESERVED;
+ rc = i2c_smbus_write_block_data(dev->on_file, NIC_WRITE_RECV_ENABLE_CMD,
+ 1, &ctrl);
+ if (rc < 0) {
+ rc = errno;
+ LOG_ERR(rc, "Failed to stop receive function");
+ return -rc;
+ }
+ LOG_DBG("Stopped receive function");
+ return 0;
+}
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/nic.h b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/nic.h
new file mode 100644
index 0000000..1ac7ff8
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/nic.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+#ifndef NIC_H
+#define NIC_H
+
+#include <stdint.h>
+
+#include "nic_defs.h"
+
+typedef struct oob_nic_t oob_nic;
+
+oob_nic* oob_nic_open(int bus, uint8_t addr);
+void oob_nic_close(oob_nic* dev);
+
+/* MAC */
+int oob_nic_get_mac(oob_nic *dev, uint8_t mac[6]);
+
+/* Status */
+typedef struct oob_nic_status_t oob_nic_status;
+int oob_nic_get_status(oob_nic *dev, oob_nic_status *status);
+
+int oob_nic_start(oob_nic *dev, const uint8_t mac[6]);
+int oob_nic_stop(oob_nic *dev);
+
+int oob_nic_send(oob_nic *dev, const uint8_t *data, int len);
+
+int oob_nic_receive(oob_nic *dev, uint8_t *buf, int len);
+
+#endif
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/nic_defs.h b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/nic_defs.h
new file mode 100644
index 0000000..1ae8721
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic/src/nic_defs.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2014-present Facebook. All Rights Reserved.
+ *
+ * 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.
+ */
+#ifndef NIC_DEFS_H
+#define NIC_DEFS_H
+
+#include <stdint.h>
+
+#define OOB_NIC_PKT_FRAGMENT_SIZE 240
+#define NIC_PKT_SIZE_MAX 1536
+
+/** Get System MAC Address */
+#define NIC_READ_MAC_CMD 0xD4
+#define NIC_READ_MAC_RES_OPT 0xD4
+#define NIC_READ_MAC_RES_LEN 7
+
+/** Read Status */
+#define NIC_READ_STATUS_CMD 0xDE
+#define NIC_READ_STATUS_RES_OPT 0xDD
+#define NIC_READ_STATUS_RES_LEN 3
+
+struct oob_nic_status_t {
+ uint8_t ons_byte1;
+ uint8_t ons_byte2;
+};
+
+#define NIC_STATUS_D1_POWER_DR 0x00
+#define NIC_STATUS_D1_POWER_D0U 0x01
+#define NIC_STATUS_D1_POWER_D0 0x10
+#define NIC_STATUS_D1_POWER_D3 0x11
+#define NIC_STATUS_D1_PORT_MSB (0x1 << 2)
+#define NIC_STATUS_D1_INIT (0x1 << 3)
+#define NIC_STATUS_D1_FORCE_UP (0x1 << 4)
+#define NIC_STATUS_D1_LINK (0x1 << 5)
+#define NIC_STATUS_D1_TCO_CMD_ABORT (0x1 << 6)
+#define NIC_STATUS_D1_PORT_LSB (0x1 << 7)
+
+#define NIC_STATUS_D2_ICR (0x1 << 1)
+#define NIC_STATUS_D2_IPI (0x1 << 2)
+#define NIC_STATUS_D2_DRV_VALID (0x1 << 3)
+
+/** Receive TCO Packet */
+#define NIC_READ_PKT_CMD 0xC0
+#define NIC_READ_PKT_RES_FIRST_OPT 0x90
+#define NIC_READ_PKT_RES_MIDDLE_OPT 0x10
+#define NIC_READ_PKT_RES_LAST_OPT 0x50
+#define NIC_READ_PKT_RES_LAST_LEN 17
+
+/** Transmit Packet */
+#define NIC_WRITE_PKT_SINGLE_CMD 0xC4
+#define NIC_WRITE_PKT_FIRST_CMD 0x84
+#define NIC_WRITE_PKT_MIDDLE_CMD 0x04
+#define NIC_WRITE_PKT_LAST_CMD 0x44
+
+/** Management Control */
+#define NIC_WRITE_MNG_CTRL_CMD 0xC1
+
+#define NIC_MNG_CTRL_KEEP_LINK_UP_NUM 0x00
+#define NIC_MNG_CTRL_KEEP_LINK_UP_ENABLE 0x01
+#define NIC_MNG_CTRL_KEEP_LINK_UP_DISABLE 0x00
+
+/** Update MNG RCV Filter Parameters */
+#define NIC_WRITE_FILTER_CMD 0xCC
+
+#define NIC_FILTER_MAC_NUM 0x66
+#define NIC_FILTER_MAC_PAIR0 0
+#define NIC_FILTER_MAC_PAIR1 1
+#define NIC_FILTER_MAC_PAIR2 2
+#define NIC_FILTER_MAC_PAIR3 3
+
+#define NIC_FILTER_MNG_ONLY_NUM 0xF
+#define NIC_FILTER_MNG_ONLY_FILTER0 (0x1)
+#define NIC_FILTER_MNG_ONLY_FILTER1 (0x1 << 1)
+#define NIC_FILTER_MNG_ONLY_FILTER2 (0x1 << 2)
+#define NIC_FILTER_MNG_ONLY_FILTER3 (0x1 << 3)
+#define NIC_FILTER_MNG_ONLY_FILTER4 (0x1 << 4)
+
+#define NIC_FILTER_DECISION_EXT_NUM 0x68
+#define NIC_FILTER_MDEF0 0 /* index 0 */
+#define NIC_FILTER_MDEF1 1 /* index 1 */
+#define NIC_FILTER_MDEF2 2 /* index 2 */
+#define NIC_FILTER_MDEF3 3 /* index 3 */
+#define NIC_FILTER_MDEF4 4 /* index 4 */
+#define NIC_FILTER_MDEF5 5 /* index 5 */
+#define NIC_FILTER_MDEF6 6 /* index 6 */
+#define NIC_FILTER_MDEF7 7 /* index 7 */
+
+#define NIC_FILTER_MDEF_MAC_AND_OFFSET 0
+#define NIC_FILTER_MDEF_BCAST_AND_OFFSET 4
+#define NIC_FILTER_MDEF_VLAN_AND_OFFSET 5
+#define NIC_FILTER_MDEF_IPV4_AND_OFFSET 13
+#define NIC_FILTER_MDEF_IPV6_AND_OFFSET 17
+#define NIC_FILTER_MDEF_MAC_OR_OFFSET 21
+#define NIC_FILTER_MDEF_BCAST_OR_OFFSET 25
+#define NIC_FILTER_MDEF_MCAST_AND_OFFSET 26
+#define NIC_FILTER_MDEF_ARP_REQ_OR_OFFSET 27
+#define NIC_FILTER_MDEF_ARP_RES_OR_OFFSET 28
+#define NIC_FILTER_MDEF_NBG_OR_OFFSET 29
+#define NIC_FILTER_MDEF_PORT298_OR_OFFSET 30
+#define NIC_FILTER_MDEF_PORT26F_OR_OFFSET 31
+
+#define NIC_FILTER_MDEF_EXT_ETHTYPE_AND_OFFSET 0
+#define NIC_FILTER_MDEF_EXT_ETHTYPE_OR_OFFSET 8
+#define NIC_FILTER_MDEF_EXT_FLEX_PORT_OR_OFFSET 16
+#define NIC_FILTER_MDEF_EXT_FLEX_TCO_OR_OFFSET 24
+#define NIC_FILTER_MDEF_EXT_NCSI_DISABLE_OFFSET 28
+#define NIC_FILTER_MDEF_EXT_FLOW_CONTROL_DISCARD_OFFSET 29
+#define NIC_FILTER_MDEF_EXT_NET_EN_OFFSET 30
+#define NIC_FILTER_MDEF_EXT_HOST_EN_OFFSET 31
+
+#define NIC_FILTER_MDEF_BIT(offset) ((0x1) << (offset))
+#define NIC_FILTER_MDEF_BIT_VAL(offset, val) ((0x1) << ((offset) + (val)))
+
+/** Receive Enable */
+#define NIC_WRITE_RECV_ENABLE_CMD 0xCA
+#define NIC_WRITE_RECV_ENABLE_LEN_MAX 14
+
+#define NIC_WRITE_RECV_ENABLE_EN 0x1
+#define NIC_WRITE_RECV_ENABLE_ALL (0x1 << 1)
+#define NIC_WRITE_RECV_ENABLE_STA (0x1 << 2)
+#define NIC_WRITE_RECV_ENABLE_ARP_RES (0x1 << 3)
+#define NIC_WRITE_RECV_ENABLE_NM_ALERT (0x00 << 4)
+#define NIC_WRITE_RECV_ENABLE_NM_ASYNC (0x01 << 4)
+#define NIC_WRITE_RECV_ENABLE_NM_DIRECT (0x02 << 4)
+#define NIC_WRITE_RECV_ENABLE_NM_UNSUPP (0x03 << 4)
+#define NIC_WRITE_RECV_ENABLE_RESERVED (0x1 << 6)
+#define NIC_WRITE_RECV_ENABLE_CBDM (0x1 << 7)
+
+#endif
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic_0.1.bb b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic_0.1.bb
new file mode 100644
index 0000000..30f167f
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/oob-nic/oob-nic_0.1.bb
@@ -0,0 +1,44 @@
+# 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
+
+SUMMARY = "OOB Shared NIC driver"
+DESCRIPTION = "The shared-nic driver"
+SECTION = "base"
+PR = "r2"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://main.c;beginline=4;endline=16;md5=da35978751a9d71b73679307c4d296ec"
+
+SRC_URI = "file://src \
+ "
+
+S = "${WORKDIR}/src"
+
+DEPENDS += "fbutils libwedge-eeprom"
+
+RDEPENDS_${PN} += "libwedge-eeprom"
+
+do_install() {
+ install -d ${D}${sbindir}
+ install -m 755 oob-nic ${D}${sbindir}/oob-nic
+ install -m 755 i2craw ${D}${sbindir}/i2craw
+ install -d ${D}${sysconfdir}/init.d
+ install -d ${D}${sysconfdir}/rcS.d
+ install -m 755 etc/oob-nic.sh ${D}${sysconfdir}/init.d/oob-nic.sh
+ update-rc.d -r ${D} oob-nic.sh start 80 S .
+}
+
+FILES_${PN} = " ${sbindir} ${sysconfdir} "
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/rest-api/files/plat_tree.py b/meta-facebook/meta-yosemite/recipes-yosemite/rest-api/files/plat_tree.py
new file mode 100644
index 0000000..b93e98e
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/rest-api/files/plat_tree.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+#
+# 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
+#
+
+from ctypes import *
+import json
+import ssl
+import socket
+import os
+from node_api import get_node_api
+from node_spb import get_node_spb
+from node_bmc import get_node_bmc
+from node_server import get_node_server
+from node_fruid import get_node_fruid
+from node_sensors import get_node_sensors
+from node_config import get_node_config
+from tree import tree
+from pal import *
+
+def populate_server_node(num):
+ prsnt = pal_is_server_prsnt(num)
+ if prsnt == None or prsnt == 0:
+ return None
+
+ r_server = tree("server" + repr(num), data = get_node_server(num))
+
+ r_fruid = tree("fruid", data = get_node_fruid("slot" + repr(num)))
+
+ r_sensors = tree("sensors", data = get_node_sensors("slot" + repr(num)))
+
+ r_config = tree("config", data = get_node_config("slot" + repr(num)))
+
+ r_server.addChildren([r_fruid, r_sensors, r_config])
+
+ return r_server
+
+# Initialize Platform specific Resource Tree
+def init_plat_tree():
+
+ # Create /api end point as root node
+ r_api = tree("api", data = get_node_api())
+
+ # Add /api/spb to represent side plane board
+ r_spb = tree("spb", data = get_node_spb())
+ r_api.addChild(r_spb)
+
+ # Add servers /api/server[1-max]
+ num = pal_get_num_slots()
+ for i in range(1, num+1):
+ r_server = populate_server_node(i)
+ if r_server:
+ r_api.addChild(r_server)
+
+ # TODO: Need to add /api/nic to represent NIC Mezz Card
+
+ # Add /api/spb/fruid end point
+ r_temp = tree("fruid", data = get_node_fruid("spb"))
+ r_spb.addChild(r_temp)
+
+ # /api/spb/bmc end point
+ r_temp = tree("bmc", data = get_node_bmc())
+ r_spb.addChild(r_temp)
+
+ # /api/spb/sensors end point
+ r_temp = tree("sensors", data = get_node_sensors("spb"))
+ r_spb.addChild(r_temp)
+
+ return r_api
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/rest-api/files/setup-rest-api.sh b/meta-facebook/meta-yosemite/recipes-yosemite/rest-api/files/setup-rest-api.sh
new file mode 100644
index 0000000..bdd79b6
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/rest-api/files/setup-rest-api.sh
@@ -0,0 +1,32 @@
+#!/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: setup-rest-api
+# Required-Start:
+# Required-Stop:
+# Default-Start: S
+# Default-Stop:
+# Short-Description: Set REST API handler
+### END INIT INFO
+
+echo -n "Setup REST API handler... "
+/usr/local/bin/rest.py > /tmp/rest.log 2>&1 &
+echo "done."
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/rest-api/rest-api_0.2.bbappend b/meta-facebook/meta-yosemite/recipes-yosemite/rest-api/rest-api_0.2.bbappend
new file mode 100644
index 0000000..ce33bba
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/rest-api/rest-api_0.2.bbappend
@@ -0,0 +1,62 @@
+# 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
+SUMMARY = "Rest API Daemon"
+DESCRIPTION = "Daemon to handle RESTful interface."
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://rest.py;beginline=5;endline=18;md5=0b1ee7d6f844d472fa306b2fee2167e0"
+
+DEPENDS_append = " update-rc.d-native"
+
+S = "${WORKDIR}"
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+SRC_URI += "file://setup-rest-api.sh \
+ file://plat_tree.py \
+ file://node_api.py \
+ file://node_spb.py \
+ file://node_bmc.py \
+ file://node_server.py \
+ file://node_fruid.py \
+ file://node_sensors.py \
+ file://node_config.py \
+ "
+
+binfiles += "setup-rest-api.sh plat_tree.py node_api.py node_spb.py node_bmc.py node_server.py node_fruid.py node_sensors.py node_config.py"
+
+do_install() {
+ dst="${D}/usr/local/fbpackages/${pkgdir}"
+ bin="${D}/usr/local/bin"
+ install -d $dst
+ install -d $bin
+ for f in ${binfiles}; do
+ install -m 755 $f ${dst}/$f
+ ln -snf ../fbpackages/${pkgdir}/$f ${bin}/$f
+ done
+ for f in ${otherfiles}; do
+ install -m 644 $f ${dst}/$f
+ done
+ install -d ${D}${sysconfdir}/init.d
+ install -d ${D}${sysconfdir}/rcS.d
+ install -m 755 setup-rest-api.sh ${D}${sysconfdir}/init.d/setup-rest-api.sh
+ update-rc.d -r ${D} setup-rest-api.sh start 95 2 3 4 5 .
+}
+
+FBPACKAGEDIR = "${prefix}/local/fbpackages"
+
+FILES_${PN} = "${FBPACKAGEDIR}/rest-api ${prefix}/local/bin ${sysconfdir} "
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/sensor-mon/files/setup-sensord.sh b/meta-facebook/meta-yosemite/recipes-yosemite/sensor-mon/files/setup-sensord.sh
new file mode 100644
index 0000000..3f4b38e
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/sensor-mon/files/setup-sensord.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+#
+# 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
+#
+
+### BEGIN INIT INFO
+# Provides: setup-sensord
+# Required-Start:
+# Required-Stop:
+# Default-Start: S
+# Default-Stop:
+# Short-Description: Setup sensor monitoring
+### END INIT INFO
+
+. /usr/local/fbpackages/utils/ast-functions
+
+# TODO: check for the if slot/server is present before starting the daemon
+echo -n "Setup sensor monitoring for yosemite... "
+/usr/local/bin/sensord slot1 slot2 slot3 slot4
+echo "done."
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/sensor-mon/sensor-mon_0.1.bbappend b/meta-facebook/meta-yosemite/recipes-yosemite/sensor-mon/sensor-mon_0.1.bbappend
new file mode 100644
index 0000000..687a599
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/sensor-mon/sensor-mon_0.1.bbappend
@@ -0,0 +1,58 @@
+# 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
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
+
+SRC_URI += "file://setup-sensord.sh \
+ "
+
+S = "${WORKDIR}"
+
+CFLAGS_prepend = " -DCONFIG_YOSEMITE "
+
+LDFLAGS_append = " -lyosemite_sensor "
+
+DEPENDS_append = "libyosemite-sensor update-rc.d-native"
+
+pkgdir = "sensor-mon"
+
+do_install() {
+ dst="${D}/usr/local/fbpackages/${pkgdir}"
+ bin="${D}/usr/local/bin"
+ install -d $dst
+ install -d $bin
+ for f in ${binfiles}; do
+ install -m 755 $f ${dst}/$f
+ ln -snf ../fbpackages/${pkgdir}/$f ${bin}/$f
+ done
+ for f in ${otherfiles}; do
+ install -m 644 $f ${dst}/$f
+ done
+ install -d ${D}${sysconfdir}/init.d
+ install -d ${D}${sysconfdir}/rcS.d
+ install -m 755 setup-sensord.sh ${D}${sysconfdir}/init.d/setup-sensord.sh
+ update-rc.d -r ${D} setup-sensord.sh start 91 S .
+}
+
+FBPACKAGEDIR = "${prefix}/local/fbpackages"
+
+FILES_${PN} = "${FBPACKAGEDIR}/sensor-mon ${prefix}/local/bin ${sysconfdir} "
+
+# Inhibit complaints about .debug directories for the sensord binary:
+
+INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
+INHIBIT_PACKAGE_STRIP = "1"
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/sensor-setup/files/sensor-setup.sh b/meta-facebook/meta-yosemite/recipes-yosemite/sensor-setup/files/sensor-setup.sh
new file mode 100644
index 0000000..a53b316
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/sensor-setup/files/sensor-setup.sh
@@ -0,0 +1,54 @@
+#!/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: sensor-setup
+# Required-Start: power-on
+# Required-Stop:
+# Default-Start: S
+# Default-Stop:
+# Short-Description: Power on micro-server
+### END INIT INFO
+
+# Eventually, this will be used to configure the various (mostly
+# i2c-based) sensors, once we have a kernel version that supports
+# doing this more dynamically.
+#
+# For now, we're using it to install the lm75 and pmbus module so that it
+# can detect the fourth temperature sensor, which is located
+# on the uServer, which doesn't get power until power-on executes.
+#
+# Similarly, the pmbus sensor seems to have an easier time of
+# detecting the NCP4200 buck converters after poweron. This has not
+# been carefully explored.
+
+modprobe lm75
+modprobe pmbus
+
+# Enable the ADC inputs; adc0 - adc7 are connected to various voltage sensors
+
+echo 1 > /sys/devices/platform/ast_adc.0/adc0_en
+echo 1 > /sys/devices/platform/ast_adc.0/adc1_en
+echo 1 > /sys/devices/platform/ast_adc.0/adc2_en
+echo 1 > /sys/devices/platform/ast_adc.0/adc3_en
+echo 1 > /sys/devices/platform/ast_adc.0/adc4_en
+echo 1 > /sys/devices/platform/ast_adc.0/adc5_en
+echo 1 > /sys/devices/platform/ast_adc.0/adc6_en
+echo 1 > /sys/devices/platform/ast_adc.0/adc7_en
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/sensor-setup/sensor-setup_0.1.bb b/meta-facebook/meta-yosemite/recipes-yosemite/sensor-setup/sensor-setup_0.1.bb
new file mode 100644
index 0000000..1b0f937
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/sensor-setup/sensor-setup_0.1.bb
@@ -0,0 +1,38 @@
+# 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
+SUMMARY = "Configure the sensors"
+DESCRIPTION = "The script configure sensors"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://sensor-setup.sh;beginline=5;endline=18;md5=0b1ee7d6f844d472fa306b2fee2167e0"
+
+DEPENDS_append = " update-rc.d-native"
+
+SRC_URI = "file://sensor-setup.sh \
+ "
+
+S = "${WORKDIR}"
+
+do_install() {
+ install -d ${D}${sysconfdir}/init.d
+ install -d ${D}${sysconfdir}/rcS.d
+ install -m 755 sensor-setup.sh ${D}${sysconfdir}/init.d/sensor-setup.sh
+ update-rc.d -r ${D} sensor-setup.sh start 90 S .
+}
+
+FILES_${PN} = " ${sysconfdir} "
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/usb-console/files/usbcons.sh b/meta-facebook/meta-yosemite/recipes-yosemite/usb-console/files/usbcons.sh
new file mode 100755
index 0000000..de284bb
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/usb-console/files/usbcons.sh
@@ -0,0 +1,80 @@
+#! /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: usbcons
+# Required-Start:
+# Required-Stop:
+# Default-Start: S
+# Default-Stop: 0 6
+# Short-Description: Creates a virtual USB serial device and starts a console
+# on it.
+#
+### END INIT INFO
+
+PATH=/sbin:/bin:/usr/sbin:/usr/bin
+NAME=usbcons
+PIDFILE=/run/usbcons.pid
+DESC="USB Serial Console"
+
+# source function library
+. /etc/init.d/functions
+
+STOPPER=
+ACTION="$1"
+
+case "$ACTION" in
+ start)
+ # Ability to prevent this from starting by editing cmdline in u-boot.
+ # Keeping this here until I get gadget switching working properly. (t4906522)
+ if grep "nousbcons" /proc/cmdline > /dev/null 2>&1
+ then
+ echo "USB Console Disabled."
+ exit 0
+ fi
+ echo -n "Starting $DESC: "
+ /usr/local/bin/usbmon.sh > /dev/null 2>&1 &
+ echo "$NAME."
+ ;;
+ stop)
+ echo -n "Stopping $DESC: "
+ killall usbmon.sh
+ echo "$NAME."
+ ;;
+ restart|force-reload)
+ echo -n "Restarting $DESC: "
+ killall usbmon.sh
+ sleep 1
+ /usr/local/bin/usbmon.sh > /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-yosemite/recipes-yosemite/usb-console/files/usbmon.sh b/meta-facebook/meta-yosemite/recipes-yosemite/usb-console/files/usbmon.sh
new file mode 100755
index 0000000..0030775
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/usb-console/files/usbmon.sh
@@ -0,0 +1,25 @@
+#!/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
+#
+
+modprobe g_cdc host_addr=02:00:00:00:00:02 dev_addr=02:00:00:00:00:01
+while true; do
+ getty /dev/ttyGS0 57600
+ sleep 1
+done
diff --git a/meta-facebook/meta-yosemite/recipes-yosemite/usb-console/usb-console_0.1.bb b/meta-facebook/meta-yosemite/recipes-yosemite/usb-console/usb-console_0.1.bb
new file mode 100644
index 0000000..c934f46
--- /dev/null
+++ b/meta-facebook/meta-yosemite/recipes-yosemite/usb-console/usb-console_0.1.bb
@@ -0,0 +1,42 @@
+# 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
+SUMMARY = "Set up a USB serial console"
+DESCRIPTION = "Sets up a USB serial console"
+SECTION = "base"
+PR = "r1"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://usbcons.sh;beginline=5;endline=18;md5=0b1ee7d6f844d472fa306b2fee2167e0"
+
+DEPENDS_append = " update-rc.d-native"
+
+SRC_URI = "file://usbcons.sh \
+ file://usbmon.sh \
+ "
+
+S = "${WORKDIR}"
+
+do_install() {
+ install -d ${D}${sysconfdir}/init.d
+ install -d ${D}${sysconfdir}/rcS.d
+ install -m 755 usbcons.sh ${D}${sysconfdir}/init.d/usbcons.sh
+ update-rc.d -r ${D} usbcons.sh start 90 S .
+ localbindir="${D}/usr/local/bin"
+ install -d ${localbindir}
+ install -m 755 usbmon.sh ${localbindir}/usbmon.sh
+}
+
+FILES_${PN} = " ${sysconfdir} /usr/local"
OpenPOWER on IntegriCloud