diff --git a/platform/s3ip-sysfs/Makefile b/platform/s3ip-sysfs/Makefile new file mode 100644 index 000000000000..fa562ba235d5 --- /dev/null +++ b/platform/s3ip-sysfs/Makefile @@ -0,0 +1,46 @@ +PWD = $(shell pwd) +SYSFS_OUT_PUT := $(PWD)/build +sysfs_out_put_dir := $(SYSFS_OUT_PUT)/S3IP_sysfs/ +export sysfs_out_put_dir +KERNEL_SRC=/lib/modules/$(shell uname -r) +export KERNEL_SRC + +SYSFS_DRIVER_DIR = $(PWD)/s3ip_sysfs_frame +SWITCH_DRIVER_DIR = $(PWD)/demo_driver + +KBUILD_EXTRA_SYMBOLS += $(SYSFS_DRIVER_DIR)/Module.symvers +KBUILD_EXTRA_SYMBOLS += $(SWITCH_DRIVER_DIR)/Module.symvers +export KBUILD_EXTRA_SYMBOLS + +all : + $(MAKE) -C $(SYSFS_DRIVER_DIR) + $(MAKE) -C $(SWITCH_DRIVER_DIR) + +clean : + -rm -rf $(SYSFS_OUT_PUT) + $(MAKE) -C $(SYSFS_DRIVER_DIR) clean + $(MAKE) -C $(SWITCH_DRIVER_DIR) clean + + + +install: + install -d $(DESTDIR)/lib/modules/s3ip/ + install -D $(sysfs_out_put_dir)/*.ko \ + $(DESTDIR)/lib/modules/s3ip/ + install -D scripts/s3ip_load.py \ + $(DESTDIR)/$(prefix)/bin/s3ip_load.py + install -D scripts/s3ip_sysfs_conf.json \ + $(DESTDIR)/etc/s3ip/s3ip_sysfs_conf.json + install -D scripts/s3ip_sysfs_tool.sh \ + $(DESTDIR)/$(prefix)/bin/s3ip_sysfs_tool.sh + install -D scripts/s3ip-sysfs.service \ + $(DESTDIR)/etc/systemd/system/s3ip-sysfs.service + + +uninstall: + -rm -f $(DESTDIR)$(prefix)/bin/s3ip_load.py + -rm -f $(DESTDIR)/lib/modules/s3ip/ + -rm -f $(DESTDIR)/etc/s3ip + -rm -f $(DESTDIR)/$(prefix)/bin/s3ip_sysfs_tool.sh + -rm -f $(DESTDIR)/etc/systemd/system/s3ip-sysfs.service + diff --git a/platform/s3ip-sysfs/build.sh b/platform/s3ip-sysfs/build.sh new file mode 100755 index 000000000000..d72369ea50a1 --- /dev/null +++ b/platform/s3ip-sysfs/build.sh @@ -0,0 +1,3 @@ +#! /bin/bash + +dpkg-buildpackage -rfakeroot -b -us -uc diff --git a/platform/s3ip-sysfs/debian/README.Debian b/platform/s3ip-sysfs/debian/README.Debian new file mode 100755 index 000000000000..0a2ca471ac20 --- /dev/null +++ b/platform/s3ip-sysfs/debian/README.Debian @@ -0,0 +1,8 @@ +s3ip-sysfs for Debian + +Please edit this to provide information specific to +this libkbc Debian package. + + (Automatically generated by debmake Version 4.2.9) + + -- ubuntu Mon, 07 Sep 2020 20:06:06 +0800 diff --git a/platform/s3ip-sysfs/debian/changelog b/platform/s3ip-sysfs/debian/changelog new file mode 100755 index 000000000000..6f6762dd2262 --- /dev/null +++ b/platform/s3ip-sysfs/debian/changelog @@ -0,0 +1,6 @@ +s3ip-sysfs (1.0.0) unstable; urgency=medium + + * Initial release. + + -- shangfei tian Wed, 09 Sep 2021 12:00:00 -0800 + diff --git a/platform/s3ip-sysfs/debian/compat b/platform/s3ip-sysfs/debian/compat new file mode 100755 index 000000000000..ec635144f600 --- /dev/null +++ b/platform/s3ip-sysfs/debian/compat @@ -0,0 +1 @@ +9 diff --git a/platform/s3ip-sysfs/debian/control b/platform/s3ip-sysfs/debian/control new file mode 100755 index 000000000000..9b1d90ed1cfd --- /dev/null +++ b/platform/s3ip-sysfs/debian/control @@ -0,0 +1,14 @@ +Source: s3ip-sysfs +Maintainer: timsftian +Section: libs +Priority: optional +Build-Depends: dh-exec (>=0.3),debhelper (>= 8.0.0), autotools-dev +Standards-Version: 3.9.3 +Homepage: https://tencent.com + +Package: s3ip-sysfs +Architecture: any +Section: libdevel +Depends: ${misc:Depends} +Description: This package contains development files for s3ip sysfs + diff --git a/platform/s3ip-sysfs/debian/copyright b/platform/s3ip-sysfs/debian/copyright new file mode 100755 index 000000000000..0cf1e83c5a65 --- /dev/null +++ b/platform/s3ip-sysfs/debian/copyright @@ -0,0 +1,13 @@ +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: s3ip-sysfs +Source: +# +# Please double check copyright with the licensecheck(1) command. + +Files: Makefile +Copyright: __NO_COPYRIGHT_NOR_LICENSE__ +License: __NO_COPYRIGHT_NOR_LICENSE__ + +#---------------------------------------------------------------------------- +# Files marked as NO_LICENSE_TEXT_FOUND may be covered by the following +# license/copyright files. diff --git a/platform/s3ip-sysfs/debian/files b/platform/s3ip-sysfs/debian/files new file mode 100644 index 000000000000..b1b2585c4365 --- /dev/null +++ b/platform/s3ip-sysfs/debian/files @@ -0,0 +1,2 @@ +s3ip-sysfs_1.0.0_amd64.buildinfo libs optional +s3ip-sysfs_1.0.0_amd64.deb libdevel optional diff --git a/platform/s3ip-sysfs/debian/rules b/platform/s3ip-sysfs/debian/rules new file mode 100755 index 000000000000..86f77f3211c7 --- /dev/null +++ b/platform/s3ip-sysfs/debian/rules @@ -0,0 +1,17 @@ +#!/usr/bin/make -f +# You must remove unused comment lines for the released package. +#export DH_VERBOSE = 1 + +#export DEB_BUILD_MAINT_OPTIONS = hardening=+all +#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic +#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed + +%: + dh $@ + +override_dh_auto_install: + dh_auto_install -- prefix=/usr + +override_dh_shlibdeps: + +override_dh_installmodules: diff --git a/platform/s3ip-sysfs/debian/s3ip-sysfs.postinst b/platform/s3ip-sysfs/debian/s3ip-sysfs.postinst new file mode 100644 index 000000000000..a57c5a76865c --- /dev/null +++ b/platform/s3ip-sysfs/debian/s3ip-sysfs.postinst @@ -0,0 +1,3 @@ +systemctl daemon-reload +systemctl start s3ip-sysfs +systemctl enable s3ip-sysfs diff --git a/platform/s3ip-sysfs/debian/s3ip-sysfs.prerm b/platform/s3ip-sysfs/debian/s3ip-sysfs.prerm new file mode 100644 index 000000000000..3e6b2b5180ea --- /dev/null +++ b/platform/s3ip-sysfs/debian/s3ip-sysfs.prerm @@ -0,0 +1,2 @@ +systemctl stop s3ip-sysfs +systemctl disable s3ip-sysfs diff --git a/platform/s3ip-sysfs/debian/s3ip-sysfs.substvars b/platform/s3ip-sysfs/debian/s3ip-sysfs.substvars new file mode 100644 index 000000000000..978fc8b5a0eb --- /dev/null +++ b/platform/s3ip-sysfs/debian/s3ip-sysfs.substvars @@ -0,0 +1,2 @@ +misc:Depends= +misc:Pre-Depends= diff --git a/platform/s3ip-sysfs/debian/watch b/platform/s3ip-sysfs/debian/watch new file mode 100755 index 000000000000..33435127f6c8 --- /dev/null +++ b/platform/s3ip-sysfs/debian/watch @@ -0,0 +1,2 @@ +# You must remove unused comment lines for the released package. +#version=3 diff --git a/platform/s3ip-sysfs/demo_driver/Makefile b/platform/s3ip-sysfs/demo_driver/Makefile new file mode 100644 index 000000000000..2d565cef50c5 --- /dev/null +++ b/platform/s3ip-sysfs/demo_driver/Makefile @@ -0,0 +1,33 @@ +PWD = $(shell pwd) + +MAKEFILE_FILE_PATH = $(abspath $(lastword $(MAKEFILE_LIST))) +DEV_SYSFS_HEADER_DIR = $(abspath $(MAKEFILE_FILE_PATH)/../../s3ip_sysfs_frame/include) +SWITCH_DVR_HEADER_DIR = $(abspath $(MAKEFILE_FILE_PATH)/../../s3ip_sysfs_frame/include) +EXTRA_CFLAGS:= -I$(M)/include +EXTRA_CFLAGS+= -I$(DEV_SYSFS_HEADER_DIR) +EXTRA_CFLAGS+= -I$(SWITCH_DVR_HEADER_DIR) +EXTRA_CFLAGS+= -Wall + +obj-m := syseeprom_device_driver.o +obj-m += fan_device_driver.o +obj-m += cpld_device_driver.o +obj-m += sysled_device_driver.o +obj-m += slot_device_driver.o +obj-m += psu_device_driver.o +obj-m += transceiver_device_driver.o +obj-m += temp_sensor_device_driver.o +obj-m += vol_sensor_device_driver.o +obj-m += curr_sensor_device_driver.o +obj-m += fpga_device_driver.o +obj-m += watchdog_device_driver.o + + +all: + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(sysfs_out_put_dir) ]; then mkdir -p $(sysfs_out_put_dir) ;fi + cp -p $(PWD)/*.ko $(sysfs_out_put_dir) +clean: + rm -f $(PWD)/*.o $(PWD)/*.ko $(PWD)/*.mod.c $(PWD)/.*.cmd + rm -f $(PWD)/Module.markers $(PWD)/Module.symvers $(PWD)/modules.order + rm -rf $(PWD)/.tmp_versions + rm -rf $(PWD)/.cache.mk \ No newline at end of file diff --git a/platform/s3ip-sysfs/demo_driver/cpld_device_driver.c b/platform/s3ip-sysfs/demo_driver/cpld_device_driver.c new file mode 100644 index 000000000000..db28c13e1e67 --- /dev/null +++ b/platform/s3ip-sysfs/demo_driver/cpld_device_driver.c @@ -0,0 +1,168 @@ +/* + * cpld_device_driver.c + * + * This module realize /sys/s3ip/cpld attributes read and write functions + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-08-31 S3IP sysfs + */ + +#include + +#include "device_driver_common.h" +#include "cpld_sysfs.h" + +#define CPLD_INFO(fmt, args...) LOG_INFO("cpld: ", fmt, ##args) +#define CPLD_ERR(fmt, args...) LOG_ERR("cpld: ", fmt, ##args) +#define CPLD_DBG(fmt, args...) LOG_DBG("cpld: ", fmt, ##args) + +static int g_loglevel = 0; + +/******************************************CPLD***********************************************/ +static int demo_get_main_board_cpld_number(void) +{ + /* add vendor codes here */ + return 1; +} + +/* + * demo_get_main_board_cpld_alias - Used to identify the location of cpld, + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_cpld_alias(unsigned int cpld_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_main_board_cpld_type - Used to get cpld model name + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_cpld_type(unsigned int cpld_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_main_board_cpld_firmware_version - Used to get cpld firmware version, + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_cpld_firmware_version(unsigned int cpld_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_main_board_cpld_board_version - Used to get cpld board version, + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_cpld_board_version(unsigned int cpld_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_main_board_cpld_test_reg - Used to test cpld register read + * filled the value to buf, value is hexadecimal, start with 0x + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_cpld_test_reg(unsigned int cpld_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_main_board_cpld_test_reg - Used to test cpld register write + * @cpld_index: start with 1 + * @value: value write to cpld + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_main_board_cpld_test_reg(unsigned int cpld_index, unsigned int value) +{ + /* add vendor codes here */ + return -ENOSYS; +} +/***************************************end of CPLD*******************************************/ + +static struct s3ip_sysfs_cpld_drivers_s drivers = { + /* + * set ODM CPLD drivers to /sys/s3ip/cpld, + * if not support the function, set corresponding hook to NULL. + */ + .get_main_board_cpld_number = demo_get_main_board_cpld_number, + .get_main_board_cpld_alias = demo_get_main_board_cpld_alias, + .get_main_board_cpld_type = demo_get_main_board_cpld_type, + .get_main_board_cpld_firmware_version = demo_get_main_board_cpld_firmware_version, + .get_main_board_cpld_board_version = demo_get_main_board_cpld_board_version, + .get_main_board_cpld_test_reg = demo_get_main_board_cpld_test_reg, + .set_main_board_cpld_test_reg = demo_set_main_board_cpld_test_reg, +}; + +static int __init cpld_device_driver_init(void) +{ + int ret; + + CPLD_INFO("cpld_init...\n"); + + ret = s3ip_sysfs_cpld_drivers_register(&drivers); + if (ret < 0) { + CPLD_ERR("cpld drivers register err, ret %d.\n", ret); + return ret; + } + + CPLD_INFO("cpld_init success.\n"); + return 0; +} + +static void __exit cpld_device_driver_exit(void) +{ + s3ip_sysfs_cpld_drivers_unregister(); + CPLD_INFO("cpld_exit success.\n"); + return; +} + +module_init(cpld_device_driver_init); +module_exit(cpld_device_driver_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("cpld device driver"); diff --git a/platform/s3ip-sysfs/demo_driver/curr_sensor_device_driver.c b/platform/s3ip-sysfs/demo_driver/curr_sensor_device_driver.c new file mode 100644 index 000000000000..f5f7ffa53ef6 --- /dev/null +++ b/platform/s3ip-sysfs/demo_driver/curr_sensor_device_driver.c @@ -0,0 +1,188 @@ +/* + * curr_sensor_device_driver.c + * + * This module realize /sys/s3ip/curr_sensor attributes read and write functions + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-08-31 S3IP sysfs + */ + +#include + +#include "device_driver_common.h" +#include "curr_sensor_sysfs.h" + +#define CURR_SENSOR_INFO(fmt, args...) LOG_INFO("curr_sensor: ", fmt, ##args) +#define CURR_SENSOR_ERR(fmt, args...) LOG_ERR("curr_sensor: ", fmt, ##args) +#define CURR_SENSOR_DBG(fmt, args...) LOG_DBG("curr_sensor: ", fmt, ##args) + +static int g_loglevel = 0; + +/*************************************main board current***************************************/ +static int demo_get_main_board_curr_number(void) +{ + /* add vendor codes here */ + return 1; +} + +/* + * demo_get_main_board_curr_alias - Used to identify the location of the current sensor, + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_curr_alias(unsigned int curr_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_main_board_curr_type - Used to get the model of current sensor, + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_curr_type(unsigned int curr_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_main_board_curr_max - Used to get the maximum threshold of current sensor + * filled the value to buf, and the value keep three decimal places + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_curr_max(unsigned int curr_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_main_board_curr_max - Used to set the maximum threshold of current sensor + * get value from buf and set it to maximum threshold of current sensor + * @curr_index: start with 1 + * @buf: the buf store the data to be set + * @count: length of buf + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_main_board_curr_max(unsigned int curr_index, const char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_main_board_curr_min - Used to get the minimum threshold of current sensor + * filled the value to buf, and the value keep three decimal places + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_curr_min(unsigned int curr_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_main_board_curr_min - Used to set the minimum threshold of current sensor + * get value from buf and set it to minimum threshold of current sensor + * @curr_index: start with 1 + * @buf: the buf store the data to be set, eg '50.000' + * @count: length of buf + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_main_board_curr_min(unsigned int curr_index, const char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_main_board_curr_value - Used to get the input value of current sensor + * filled the value to buf, and the value keep three decimal places + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_curr_value(unsigned int curr_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} +/*********************************end of main board current************************************/ + +static struct s3ip_sysfs_curr_sensor_drivers_s drivers = { + /* + * set ODM current sensor drivers to /sys/s3ip/curr_sensor, + * if not support the function, set corresponding hook to NULL. + */ + .get_main_board_curr_number = demo_get_main_board_curr_number, + .get_main_board_curr_alias = demo_get_main_board_curr_alias, + .get_main_board_curr_type = demo_get_main_board_curr_type, + .get_main_board_curr_max = demo_get_main_board_curr_max, + .set_main_board_curr_max = demo_set_main_board_curr_max, + .get_main_board_curr_min = demo_get_main_board_curr_min, + .set_main_board_curr_min = demo_set_main_board_curr_min, + .get_main_board_curr_value = demo_get_main_board_curr_value, +}; + +static int __init curr_sensor_dev_drv_init(void) +{ + int ret; + + CURR_SENSOR_INFO("curr_sensor_init...\n"); + + ret = s3ip_sysfs_curr_sensor_drivers_register(&drivers); + if (ret < 0) { + CURR_SENSOR_ERR("curr sensor drivers register err, ret %d.\n", ret); + return ret; + } + + CURR_SENSOR_INFO("curr_sensor_init success.\n"); + return 0; +} + +static void __exit curr_sensor_dev_drv_exit(void) +{ + s3ip_sysfs_curr_sensor_drivers_unregister(); + CURR_SENSOR_INFO("curr_sensor_exit success.\n"); + return; +} + +module_init(curr_sensor_dev_drv_init); +module_exit(curr_sensor_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("current sensors device driver"); diff --git a/platform/s3ip-sysfs/demo_driver/fan_device_driver.c b/platform/s3ip-sysfs/demo_driver/fan_device_driver.c new file mode 100755 index 000000000000..17aa26a77f04 --- /dev/null +++ b/platform/s3ip-sysfs/demo_driver/fan_device_driver.c @@ -0,0 +1,372 @@ +/* + * fan_device_driver.c + * + * This module realize /sys/s3ip/fan attributes read and write functions + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-08-31 S3IP sysfs + */ + +#include + +#include "device_driver_common.h" +#include "fan_sysfs.h" + +#define FAN_INFO(fmt, args...) LOG_INFO("fan: ", fmt, ##args) +#define FAN_ERR(fmt, args...) LOG_ERR("fan: ", fmt, ##args) +#define FAN_DBG(fmt, args...) LOG_DBG("fan: ", fmt, ##args) + +static int g_loglevel = 0; + +/********************************************fan**********************************************/ +static int demo_get_fan_number(void) +{ + /* add vendor codes here */ + return 1; +} + +static int demo_get_fan_motor_number(unsigned int fan_index) +{ + /* add vendor codes here */ + return 1; +} + +/* + * demo_get_fan_model_name - Used to get fan model name, + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_fan_model_name(unsigned int fan_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_fan_serial_number - Used to get fan serial number, + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_fan_serial_number(unsigned int fan_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_fan_part_number - Used to get fan part number, + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_fan_part_number(unsigned int fan_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_fan_hardware_version - Used to get fan hardware version, + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_fan_hardware_version(unsigned int fan_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_fan_status - Used to get fan status, + * filled the value to buf, fan status define as below: + * 0: ABSENT + * 1: OK + * 2: NOT OK + * + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_fan_status(unsigned int fan_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_fan_led_status - Used to get fan led status + * filled the value to buf, led status value define as below: + * 0: dark + * 1: green + * 2: yellow + * 3: red + * 4:blue + * 5: green light flashing + * 6: yellow light flashing + * 7: red light flashing + * 8:blue light flashing + * + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_fan_led_status(unsigned int fan_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_fan_led_status - Used to set fan led status + * @fan_index: start with 1 + * @status: led status, led status value define as below: + * 0: dark + * 1: green + * 2: yellow + * 3: red + * 4:blue + * 5: green light flashing + * 6: yellow light flashing + * 7: red light flashing + * 8:blue light flashing + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_fan_led_status(unsigned int fan_index, int status) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_fan_direction - Used to get fan air flow direction, + * filled the value to buf, air flow direction define as below: + * 0: F2B + * 1: B2F + * + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_fan_direction(unsigned int fan_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_fan_motor_speed - Used to get fan motor speed + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_fan_motor_speed(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_fan_motor_speed_tolerance - Used to get fan motor speed tolerance + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_fan_motor_speed_tolerance(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_fan_motor_speed_target - Used to get fan motor speed target + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_fan_motor_speed_target(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_fan_motor_speed_max - Used to get the maximum threshold of fan motor + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_fan_motor_speed_max(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_fan_motor_speed_min - Used to get the minimum threshold of fan motor + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_fan_motor_speed_min(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_fan_motor_ratio - Used to get the ratio of fan motor + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_fan_ratio(unsigned int fan_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_fan_motor_ratio - Used to set the ratio of fan motor + * @fan_index: start with 1 + * @motor_index: start with 1 + * @ratio: motor speed ratio, from 0 to 100 + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_fan_ratio(unsigned int fan_index, int ratio) +{ + /* add vendor codes here */ + return -ENOSYS; +} +/****************************************end of fan*******************************************/ + +static struct s3ip_sysfs_fan_drivers_s drivers = { + /* + * set ODM fan drivers to /sys/s3ip/fan, + * if not support the function, set corresponding hook to NULL. + */ + .get_fan_number = demo_get_fan_number, + .get_fan_motor_number = demo_get_fan_motor_number, + .get_fan_model_name = demo_get_fan_model_name, + .get_fan_serial_number = demo_get_fan_serial_number, + .get_fan_part_number = demo_get_fan_part_number, + .get_fan_hardware_version = demo_get_fan_hardware_version, + .get_fan_status = demo_get_fan_status, + .get_fan_led_status = demo_get_fan_led_status, + .set_fan_led_status = demo_set_fan_led_status, + .get_fan_direction = demo_get_fan_direction, + .get_fan_motor_speed = demo_get_fan_motor_speed, + .get_fan_motor_speed_tolerance = demo_get_fan_motor_speed_tolerance, + .get_fan_motor_speed_target = demo_get_fan_motor_speed_target, + .get_fan_motor_speed_max = demo_get_fan_motor_speed_max, + .get_fan_motor_speed_min = demo_get_fan_motor_speed_min, + .get_fan_ratio = demo_get_fan_ratio, + .set_fan_ratio = demo_set_fan_ratio, +}; + +static int __init fan_dev_drv_init(void) +{ + int ret; + + FAN_INFO("fan_init...\n"); + + ret = s3ip_sysfs_fan_drivers_register(&drivers); + if (ret < 0) { + FAN_ERR("fan drivers register err, ret %d.\n", ret); + return ret; + } + + FAN_INFO("fan_init success.\n"); + return 0; +} + +static void __exit fan_dev_drv_exit(void) +{ + s3ip_sysfs_fan_drivers_unregister(); + FAN_INFO("fan_exit success.\n"); + return; +} + +module_init(fan_dev_drv_init); +module_exit(fan_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("fan device driver"); diff --git a/platform/s3ip-sysfs/demo_driver/fpga_device_driver.c b/platform/s3ip-sysfs/demo_driver/fpga_device_driver.c new file mode 100644 index 000000000000..819822af486d --- /dev/null +++ b/platform/s3ip-sysfs/demo_driver/fpga_device_driver.c @@ -0,0 +1,167 @@ +/* + * fpga_device_driver.c + * + * This module realize /sys/s3ip/fpga attributes read and write functions + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-08-31 S3IP sysfs + */ + +#include + +#include "device_driver_common.h" +#include "fpga_sysfs.h" + +#define FPGA_INFO(fmt, args...) LOG_INFO("fpga: ", fmt, ##args) +#define FPGA_ERR(fmt, args...) LOG_ERR("fpga: ", fmt, ##args) +#define FPGA_DBG(fmt, args...) LOG_DBG("fpga: ", fmt, ##args) + +static int g_loglevel = 0; + +/******************************************FPGA***********************************************/ +static int demo_get_main_board_fpga_number(void) +{ + /* add vendor codes here */ + return 1; +} + +/* + * demo_get_main_board_fpga_alias - Used to identify the location of fpga, + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_fpga_alias(unsigned int fpga_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_main_board_fpga_type - Used to get fpga model name + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_fpga_type(unsigned int fpga_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_main_board_fpga_firmware_version - Used to get fpga firmware version, + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_fpga_firmware_version(unsigned int fpga_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_main_board_fpga_board_version - Used to get fpga board version, + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_fpga_board_version(unsigned int fpga_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_main_board_fpga_test_reg - Used to test fpga register read + * filled the value to buf, value is hexadecimal, start with 0x + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_fpga_test_reg(unsigned int fpga_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_main_board_fpga_test_reg - Used to test fpga register write + * @fpga_index: start with 1 + * @value: value write to fpga + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_main_board_fpga_test_reg(unsigned int fpga_index, unsigned int value) +{ + /* add vendor codes here */ + return -ENOSYS; +} +/***************************************end of FPGA*******************************************/ + +static struct s3ip_sysfs_fpga_drivers_s drivers = { + /* + * set ODM FPGA drivers to /sys/s3ip/fpga, + * if not support the function, set corresponding hook to NULL. + */ + .get_main_board_fpga_number = demo_get_main_board_fpga_number, + .get_main_board_fpga_alias = demo_get_main_board_fpga_alias, + .get_main_board_fpga_type = demo_get_main_board_fpga_type, + .get_main_board_fpga_firmware_version = demo_get_main_board_fpga_firmware_version, + .get_main_board_fpga_board_version = demo_get_main_board_fpga_board_version, + .get_main_board_fpga_test_reg = demo_get_main_board_fpga_test_reg, + .set_main_board_fpga_test_reg = demo_set_main_board_fpga_test_reg, +}; + +static int __init fpga_dev_drv_init(void) +{ + int ret; + + FPGA_INFO("fpga_init...\n"); + + ret = s3ip_sysfs_fpga_drivers_register(&drivers); + if (ret < 0) { + FPGA_ERR("fpga drivers register err, ret %d.\n", ret); + return ret; + } + FPGA_INFO("fpga_init success.\n"); + return 0; +} + +static void __exit fpga_dev_drv_exit(void) +{ + s3ip_sysfs_fpga_drivers_unregister(); + FPGA_INFO("fpga_exit success.\n"); + return; +} + +module_init(fpga_dev_drv_init); +module_exit(fpga_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("fpga device driver"); diff --git a/platform/s3ip-sysfs/demo_driver/include/device_driver_common.h b/platform/s3ip-sysfs/demo_driver/include/device_driver_common.h new file mode 100644 index 000000000000..6386d88fafe9 --- /dev/null +++ b/platform/s3ip-sysfs/demo_driver/include/device_driver_common.h @@ -0,0 +1,49 @@ +#ifndef _DEVICE_DRIVER_COMMON_H_ +#define _DEVICE_DRIVER_COMMON_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +enum LOG_LEVEL{ + INFO = 0x1, + ERR = 0x2, + DBG = 0x4, + ALL = 0xf +}; + +#define LOG_INFO(_prefix, fmt, args...) do { \ + if (g_loglevel & INFO) { \ + printk( KERN_INFO _prefix "%s "fmt, __FUNCTION__, ##args); \ + } \ +} while (0) + +#define LOG_ERR(_prefix, fmt, args...) do { \ + if (g_loglevel & ERR) { \ + printk( KERN_ERR _prefix "%s "fmt, __FUNCTION__, ##args); \ + } \ +} while (0) + +#define LOG_DBG(_prefix, fmt, args...) do { \ + if (g_loglevel & DBG) { \ + printk( KERN_DEBUG _prefix "%s "fmt, __FUNCTION__, ##args); \ + } \ +} while (0) + +#define check_pfun(p) do { \ + if (p == NULL) { \ + if (g_loglevel & ERR) { \ + printk( KERN_ERR "%s, %s is NULL.\n", __FUNCTION__, #p); \ + } \ + return -ENOSYS; \ + } \ +} while(0) + +#define check_p(p) check_pfun(p) + +#endif /* _DEVICE_DRIVER_COMMON_H_ */ diff --git a/platform/s3ip-sysfs/demo_driver/psu_device_driver.c b/platform/s3ip-sysfs/demo_driver/psu_device_driver.c new file mode 100644 index 000000000000..2f424b5498c1 --- /dev/null +++ b/platform/s3ip-sysfs/demo_driver/psu_device_driver.c @@ -0,0 +1,587 @@ +/* + * psu_device_driver.c + * + * This module realize /sys/s3ip/psu attributes read and write functions + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-08-31 S3IP sysfs + */ + +#include + +#include "device_driver_common.h" +#include "psu_sysfs.h" + +#define PSU_INFO(fmt, args...) LOG_INFO("psu: ", fmt, ##args) +#define PSU_ERR(fmt, args...) LOG_ERR("psu: ", fmt, ##args) +#define PSU_DBG(fmt, args...) LOG_DBG("psu: ", fmt, ##args) + +static int g_loglevel = 0; + +/********************************************psu**********************************************/ +static int demo_get_psu_number(void) +{ + /* add vendor codes here */ + return 1; +} + +static int demo_get_psu_temp_number(unsigned int psu_index) +{ + /* add vendor codes here */ + return 1; +} + +/* + * demo_get_psu_model_name - Used to get psu model name, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_psu_model_name(unsigned int psu_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_psu_serial_number - Used to get psu serial number, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_psu_serial_number(unsigned int psu_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_psu_part_number - Used to get psu part number, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_psu_part_number(unsigned int psu_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_psu_hardware_version - Used to get psu hardware version, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_psu_hardware_version(unsigned int psu_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_psu_type - Used to get the input type of psu + * filled the value to buf, input type value define as below: + * 0: DC + * 1: AC + * + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_psu_type(unsigned int psu_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_psu_in_curr - Used to get the input current of psu + * filled the value to buf, and the value keep three decimal places + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_psu_in_curr(unsigned int psu_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_psu_in_vol - Used to get the input voltage of psu + * filled the value to buf, and the value keep three decimal places + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_psu_in_vol(unsigned int psu_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_psu_in_power - Used to get the input power of psu + * filled the value to buf, and the value keep three decimal places + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_psu_in_power(unsigned int psu_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_psu_out_curr - Used to get the output current of psu + * filled the value to buf, and the value keep three decimal places + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_psu_out_curr(unsigned int psu_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_psu_out_vol - Used to get the output voltage of psu + * filled the value to buf, and the value keep three decimal places + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_psu_out_vol(unsigned int psu_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_psu_out_power - Used to get the output power of psu + * filled the value to buf, and the value keep three decimal places + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_psu_out_power(unsigned int psu_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_psu_out_max_power - Used to get the output max power of psu + * filled the value to buf, and the value keep three decimal places + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_psu_out_max_power(unsigned int psu_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_psu_present_status - Used to get psu present status + * filled the value to buf, psu present status define as below: + * 0: ABSENT + * 1: PRESENT + * + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_psu_present_status(unsigned int psu_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_psu_in_status - Used to get psu input status + * filled the value to buf, psu input status define as below: + * 0: NOT OK + * 1: OK + * + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_psu_in_status(unsigned int psu_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_psu_out_status - Used to get psu output status + * filled the value to buf, psu output status define as below: + * 0: NOT OK + * 1: OK + * + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_psu_out_status(unsigned int psu_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_psu_fan_speed - Used to get psu fan speed + * filled the value to buf + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_psu_fan_speed(unsigned int psu_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_psu_fan_ratio - Used to get the ratio of psu fan + * filled the value to buf + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_psu_fan_ratio(unsigned int psu_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_psu_fan_ratio - Used to set the ratio of psu fan + * @psu_index: start with 1 + * @ratio: from 0 to 100 + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_psu_fan_ratio(unsigned int psu_index, int ratio) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_psu_fan_direction - Used to get psu air flow direction, + * filled the value to buf, air flow direction define as below: + * 0: F2B + * 1: B2F + * + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_psu_fan_direction(unsigned int psu_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_psu_led_status - Used to get psu led status + * filled the value to buf, led status value define as below: + * 0: dark + * 1: green + * 2: yellow + * 3: red + * 4:blue + * 5: green light flashing + * 6: yellow light flashing + * 7: red light flashing + * 8:blue light flashing + * + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_psu_led_status(unsigned int psu_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_psu_temp_alias - Used to identify the location of the temperature sensor of psu, + * @psu_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_psu_temp_alias(unsigned int psu_index, unsigned int temp_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_psu_temp_type - Used to get the model of temperature sensor of psu, + * @psu_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_psu_temp_type(unsigned int psu_index, unsigned int temp_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_psu_temp_max - Used to get the maximum threshold of temperature sensor of psu, + * filled the value to buf, and the value keep three decimal places + * @psu_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_psu_temp_max(unsigned int psu_index, unsigned int temp_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_psu_temp_max - Used to set the maximum threshold of temperature sensor of psu, + * get value from buf and set it to maximum threshold of psu temperature sensor + * @psu_index: start with 1 + * @temp_index: start with 1 + * @buf: the buf store the data to be set, eg '80.000' + * @count: length of buf + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_psu_temp_max(unsigned int psu_index, unsigned int temp_index, + const char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_psu_temp_min - Used to get the minimum threshold of temperature sensor of psu, + * filled the value to buf, and the value keep three decimal places + * @psu_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_psu_temp_min(unsigned int psu_index, unsigned int temp_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_psu_temp_min - Used to set the minimum threshold of temperature sensor of psu, + * get value from buf and set it to minimum threshold of psu temperature sensor + * @psu_index: start with 1 + * @temp_index: start with 1 + * @buf: the buf store the data to be set, eg '50.000' + * @count: length of buf + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_psu_temp_min(unsigned int psu_index, unsigned int temp_index, + const char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_psu_temp_value - Used to get the input value of temperature sensor of psu + * filled the value to buf, and the value keep three decimal places + * @psu_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_psu_temp_value(unsigned int psu_index, unsigned int temp_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} +/****************************************end of psu*******************************************/ + +static struct s3ip_sysfs_psu_drivers_s drivers = { + /* + * set ODM psu drivers to /sys/s3ip/psu, + * if not support the function, set corresponding hook to NULL. + */ + .get_psu_number = demo_get_psu_number, + .get_psu_temp_number = demo_get_psu_temp_number, + .get_psu_model_name = demo_get_psu_model_name, + .get_psu_serial_number = demo_get_psu_serial_number, + .get_psu_part_number = demo_get_psu_part_number, + .get_psu_hardware_version = demo_get_psu_hardware_version, + .get_psu_type = demo_get_psu_type, + .get_psu_in_curr = demo_get_psu_in_curr, + .get_psu_in_vol = demo_get_psu_in_vol, + .get_psu_in_power = demo_get_psu_in_power, + .get_psu_out_curr = demo_get_psu_out_curr, + .get_psu_out_vol = demo_get_psu_out_vol, + .get_psu_out_power = demo_get_psu_out_power, + .get_psu_out_max_power = demo_get_psu_out_max_power, + .get_psu_present_status = demo_get_psu_present_status, + .get_psu_in_status = demo_get_psu_in_status, + .get_psu_out_status = demo_get_psu_out_status, + .get_psu_fan_speed = demo_get_psu_fan_speed, + .get_psu_fan_ratio = demo_get_psu_fan_ratio, + .set_psu_fan_ratio = demo_set_psu_fan_ratio, + .get_psu_fan_direction = demo_get_psu_fan_direction, + .get_psu_led_status = demo_get_psu_led_status, + .get_psu_temp_alias = demo_get_psu_temp_alias, + .get_psu_temp_type = demo_get_psu_temp_type, + .get_psu_temp_max = demo_get_psu_temp_max, + .set_psu_temp_max = demo_set_psu_temp_max, + .get_psu_temp_min = demo_get_psu_temp_min, + .set_psu_temp_min = demo_set_psu_temp_min, + .get_psu_temp_value = demo_get_psu_temp_value, +}; + +static int __init psu_dev_drv_init(void) +{ + int ret; + + PSU_INFO("psu_init...\n"); + + ret = s3ip_sysfs_psu_drivers_register(&drivers); + if (ret < 0) { + PSU_ERR("psu drivers register err, ret %d.\n", ret); + return ret; + } + PSU_INFO("psu_init success.\n"); + return 0; +} + +static void __exit psu_dev_drv_exit(void) +{ + s3ip_sysfs_psu_drivers_unregister(); + PSU_INFO("psu_exit ok.\n"); + + return; +} + +module_init(psu_dev_drv_init); +module_exit(psu_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("psu device driver"); diff --git a/platform/s3ip-sysfs/demo_driver/slot_device_driver.c b/platform/s3ip-sysfs/demo_driver/slot_device_driver.c new file mode 100644 index 000000000000..dd924eb30012 --- /dev/null +++ b/platform/s3ip-sysfs/demo_driver/slot_device_driver.c @@ -0,0 +1,918 @@ +/* + * slot_device_driver.c + * + * This module realize /sys/s3ip/slot attributes read and write functions + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-08-31 S3IP sysfs + */ + +#include + +#include "device_driver_common.h" +#include "slot_sysfs.h" + +#define SLOT_INFO(fmt, args...) LOG_INFO("slot: ", fmt, ##args) +#define SLOT_ERR(fmt, args...) LOG_ERR("slot: ", fmt, ##args) +#define SLOT_DBG(fmt, args...) LOG_DBG("slot: ", fmt, ##args) + +static int g_loglevel = 0; + +/******************************************slot***********************************************/ +static int demo_get_slot_number(void) +{ + /* add vendor codes here */ + return 1; +} + +static int demo_get_slot_temp_number(unsigned int slot_index) +{ + /* add vendor codes here */ + return 1; +} + +static int demo_get_slot_vol_number(unsigned int slot_index) +{ + /* add vendor codes here */ + return 1; +} + +static int demo_get_slot_curr_number(unsigned int slot_index) +{ + /* add vendor codes here */ + return 1; +} + +static int demo_get_slot_fpga_number(unsigned int slot_index) +{ + /* add vendor codes here */ + return 1; +} + +static int demo_get_slot_cpld_number(unsigned int slot_index) +{ + /* add vendor codes here */ + return 1; +} + +/* + * demo_get_slot_model_name - Used to get slot model name, + * @slot_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_model_name(unsigned int slot_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_serial_number - Used to get slot serial number, + * @slot_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_serial_number(unsigned int slot_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_part_number - Used to get slot part number, + * @slot_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_part_number(unsigned int slot_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_hardware_version - Used to get slot hardware version, + * @slot_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_hardware_version(unsigned int slot_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_status - Used to get slot status, + * filled the value to buf, slot status define as below: + * 0: ABSENT + * 1: OK + * 2: NOT OK + * + * @slot_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_status(unsigned int slot_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_led_status - Used to get slot led status + * filled the value to buf, led status value define as below: + * 0: dark + * 1: green + * 2: yellow + * 3: red + * 4:blue + * 5: green light flashing + * 6: yellow light flashing + * 7: red light flashing + * 8:blue light flashing + * + * @slot_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_led_status(unsigned int slot_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_slot_led_status - Used to set slot led status + * @slot_index: start with 1 + * @status: led status, led status value define as below: + * 0: dark + * 1: green + * 2: yellow + * 3: red + * 4:blue + * 5: green light flashing + * 6: yellow light flashing + * 7: red light flashing + * 8:blue light flashing + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_slot_led_status(unsigned int slot_index, int status) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_temp_alias - Used to identify the location of the temperature sensor of slot, + * @slot_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_temp_alias(unsigned int slot_index, unsigned int temp_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_temp_type - Used to get the model of temperature sensor of slot, + * @slot_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_temp_type(unsigned int slot_index, unsigned int temp_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; + +} + +/* + * demo_get_slot_temp_max - Used to get the maximum threshold of temperature sensor of slot, + * filled the value to buf, and the value keep three decimal places + * @slot_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_temp_max(unsigned int slot_index, unsigned int temp_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_slot_temp_max - Used to set the maximum threshold of temperature sensor of slot, + * get value from buf and set it to maximum threshold of slot temperature sensor + * @slot_index: start with 1 + * @temp_index: start with 1 + * @buf: the buf store the data to be set, eg '80.000' + * @count: length of buf + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_slot_temp_max(unsigned int slot_index, unsigned int temp_index, + const char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_temp_min - Used to get the minimum threshold of temperature sensor of slot, + * filled the value to buf, and the value keep three decimal places + * @slot_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_temp_min(unsigned int slot_index, unsigned int temp_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_slot_temp_min - Used to set the minimum threshold of temperature sensor of slot, + * get value from buf and set it to minimum threshold of slot temperature sensor + * @slot_index: start with 1 + * @temp_index: start with 1 + * @buf: the buf store the data to be set, eg '50.000' + * @count: length of buf + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_slot_temp_min(unsigned int slot_index, unsigned int temp_index, + const char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_temp_value - Used to get the input value of temperature sensor of slot, + * filled the value to buf, and the value keep three decimal places + * @slot_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_temp_value(unsigned int slot_index, unsigned int temp_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_vol_alias - Used to identify the location of the voltage sensor of slot, + * @slot_index: start with 1 + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_vol_alias(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_vol_type - Used to get the model of voltage sensor of slot, + * such as udc90160, tps53622 and so on + * @slot_index: start with 1 + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_vol_type(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; + +} + +/* + * demo_get_slot_vol_max - Used to get the maximum threshold of voltage sensor of slot, + * filled the value to buf, and the value keep three decimal places + * @slot_index: start with 1 + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_vol_max(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_slot_vol_max - Used to set the maximum threshold of volatge sensor of slot, + * get value from buf and set it to maximum threshold of volatge sensor + * @slot_index: start with 1 + * @vol_index: start with 1 + * @buf: the buf store the data to be set, eg '3.567' + * @count: length of buf + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_slot_vol_max(unsigned int slot_index, unsigned int vol_index, + const char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_vol_min - Used to get the minimum threshold of voltage sensor of slot, + * filled the value to buf, and the value keep three decimal places + * @slot_index: start with 1 + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_vol_min(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_slot_vol_min - Used to set the minimum threshold of voltage sensor of slot, + * get value from buf and set it to minimum threshold of voltage sensor + * @slot_index: start with 1 + * @temp_index: start with 1 + * @buf: the buf store the data to be set, eg '3.123' + * @count: length of buf + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_slot_vol_min(unsigned int slot_index, unsigned int vol_index, + const char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_vol_range - Used to get the output error value of voltage sensor of slot, + * filled the value to buf + * @slot_index: start with 1 + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_vol_range(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_vol_nominal_value - Used to get the nominal value of voltage sensor of slot, + * filled the value to buf + * @slot_index: start with 1 + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_vol_nominal_value(unsigned int slot_index, + unsigned int vol_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_vol_value - Used to get the input value of voltage sensor of slot, + * filled the value to buf, and the value keep three decimal places + * @slot_index: start with 1 + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_vol_value(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_curr_alias - Used to identify the location of the current sensor of slot, + * @slot_index: start with 1 + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_curr_alias(unsigned int slot_index, unsigned int curr_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_curr_type - Used to get the model of current sensor of slot, + * @slot_index: start with 1 + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_curr_type(unsigned int slot_index, unsigned int curr_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_curr_max - Used to get the maximum threshold of current sensor of slot, + * filled the value to buf, and the value keep three decimal places + * @slot_index: start with 1 + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_curr_max(unsigned int slot_index, unsigned int curr_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_slot_curr_max - Used to set the maximum threshold of current sensor of slot, + * get value from buf and set it to maximum threshold of current sensor + * @slot_index: start with 1 + * @curr_index: start with 1 + * @buf: the buf store the data to be set + * @count: length of buf + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_slot_curr_max(unsigned int slot_index, unsigned int curr_index, + const char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_curr_min - Used to get the minimum threshold of current sensor of slot, + * filled the value to buf, and the value keep three decimal places + * @slot_index: start with 1 + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_curr_min(unsigned int slot_index, unsigned int curr_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_slot_curr_min - Used to set the minimum threshold of current sensor of slot, + * get value from buf and set it to minimum threshold of current sensor + * @slot_index: start with 1 + * @curr_index: start with 1 + * @buf: the buf store the data to be set, eg '50.000' + * @count: length of buf + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_slot_curr_min(unsigned int slot_index, unsigned int curr_index, + const char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_curr_value - Used to get the input value of current sensor of slot, + * filled the value to buf, and the value keep three decimal places + * @slot_index: start with 1 + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_curr_value(unsigned int slot_index, unsigned int curr_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_fpga_alias - Used to identify the location of slot fpga, + * @slot_index: start with 1 + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_fpga_alias(unsigned int slot_index, unsigned int fpga_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_fpga_type - Used to get slot fpga model name + * @slot_index: start with 1 + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_fpga_type(unsigned int slot_index, unsigned int fpga_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_fpga_firmware_version - Used to get slot fpga firmware version, + * @slot_index: start with 1 + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_fpga_firmware_version(unsigned int slot_index, unsigned int fpga_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_fpga_board_version - Used to get slot fpga board version, + * @slot_index: start with 1 + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_fpga_board_version(unsigned int slot_index, unsigned int fpga_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_fpga_test_reg - Used to test slot fpga register read + * filled the value to buf, value is hexadecimal, start with 0x + * @slot_index: start with 1 + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_fpga_test_reg(unsigned int slot_index, unsigned int fpga_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_slot_fpga_test_reg - Used to test slot fpga register write + * @slot_index: start with 1 + * @fpga_index: start with 1 + * @value: value write to slot fpga + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_slot_fpga_test_reg(unsigned int slot_index, unsigned int fpga_index, + unsigned int value) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_cpld_alias - Used to identify the location of slot cpld, + * @slot_index: start with 1 + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_cpld_alias(unsigned int slot_index, unsigned int cpld_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_cpld_type - Used to get slot cpld model name + * @slot_index: start with 1 + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_cpld_type(unsigned int slot_index, unsigned int cpld_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_cpld_firmware_version - Used to get slot cpld firmware version, + * @slot_index: start with 1 + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_cpld_firmware_version(unsigned int slot_index, unsigned int cpld_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_cpld_board_version - Used to get slot cpld board version, + * @slot_index: start with 1 + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_cpld_board_version(unsigned int slot_index, unsigned int cpld_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_slot_cpld_test_reg - Used to test slot cpld register read + * filled the value to buf, value is hexadecimal, start with 0x + * @slot_index: start with 1 + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_slot_cpld_test_reg(unsigned int slot_index, unsigned int cpld_index, + char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_slot_cpld_test_reg - Used to test slot cpld register write + * @slot_index: start with 1 + * @cpld_index: start with 1 + * @value: value write to slot cpld + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_slot_cpld_test_reg(unsigned int slot_index, unsigned int cpld_index, + unsigned int value) +{ + /* add vendor codes here */ + return -ENOSYS; +} +/***************************************end of slot*******************************************/ + +static struct s3ip_sysfs_slot_drivers_s drivers = { + /* + * set ODM slot drivers to /sys/s3ip/slot, + * if not support the function, set corresponding hook to NULL. + */ + .get_slot_number = demo_get_slot_number, + .get_slot_temp_number = demo_get_slot_temp_number, + .get_slot_vol_number = demo_get_slot_vol_number, + .get_slot_curr_number = demo_get_slot_curr_number, + .get_slot_cpld_number = demo_get_slot_cpld_number, + .get_slot_fpga_number = demo_get_slot_fpga_number, + .get_slot_model_name = demo_get_slot_model_name, + .get_slot_serial_number = demo_get_slot_serial_number, + .get_slot_part_number = demo_get_slot_part_number, + .get_slot_hardware_version = demo_get_slot_hardware_version, + .get_slot_status = demo_get_slot_status, + .get_slot_led_status = demo_get_slot_led_status, + .set_slot_led_status = demo_set_slot_led_status, + .get_slot_temp_alias = demo_get_slot_temp_alias, + .get_slot_temp_type = demo_get_slot_temp_type, + .get_slot_temp_max = demo_get_slot_temp_max, + .set_slot_temp_max = demo_set_slot_temp_max, + .get_slot_temp_min = demo_get_slot_temp_min, + .set_slot_temp_min = demo_set_slot_temp_min, + .get_slot_temp_value = demo_get_slot_temp_value, + .get_slot_vol_alias = demo_get_slot_vol_alias, + .get_slot_vol_type = demo_get_slot_vol_type, + .get_slot_vol_max = demo_get_slot_vol_max, + .set_slot_vol_max = demo_set_slot_vol_max, + .get_slot_vol_min = demo_get_slot_vol_min, + .set_slot_vol_min = demo_set_slot_vol_min, + .get_slot_vol_range = demo_get_slot_vol_range, + .get_slot_vol_nominal_value = demo_get_slot_vol_nominal_value, + .get_slot_vol_value = demo_get_slot_vol_value, + .get_slot_curr_alias = demo_get_slot_curr_alias, + .get_slot_curr_type = demo_get_slot_curr_type, + .get_slot_curr_max = demo_get_slot_curr_max, + .set_slot_curr_max = demo_set_slot_curr_max, + .get_slot_curr_min = demo_get_slot_curr_min, + .set_slot_curr_min = demo_set_slot_curr_min, + .get_slot_curr_value = demo_get_slot_curr_value, + .get_slot_fpga_alias = demo_get_slot_fpga_alias, + .get_slot_fpga_alias = demo_get_slot_fpga_alias, + .get_slot_fpga_type = demo_get_slot_fpga_type, + .get_slot_fpga_firmware_version = demo_get_slot_fpga_firmware_version, + .get_slot_fpga_board_version = demo_get_slot_fpga_board_version, + .get_slot_fpga_test_reg = demo_get_slot_fpga_test_reg, + .set_slot_fpga_test_reg = demo_set_slot_fpga_test_reg, + .get_slot_cpld_alias = demo_get_slot_cpld_alias, + .get_slot_cpld_type = demo_get_slot_cpld_type, + .get_slot_cpld_firmware_version = demo_get_slot_cpld_firmware_version, + .get_slot_cpld_board_version = demo_get_slot_cpld_board_version, + .get_slot_cpld_test_reg = demo_get_slot_cpld_test_reg, + .set_slot_cpld_test_reg = demo_set_slot_cpld_test_reg, +}; + +static int __init slot_dev_drv_init(void) +{ + int ret; + + SLOT_INFO("slot_init...\n"); + + ret = s3ip_sysfs_slot_drivers_register(&drivers); + if (ret < 0) { + SLOT_ERR("slot drivers register err, ret %d.\n", ret); + return ret; + } + SLOT_INFO("slot_init success.\n"); + return 0; +} + +static void __exit slot_dev_drv_exit(void) +{ + s3ip_sysfs_slot_drivers_unregister(); + SLOT_INFO("slot_exit success.\n"); + return; +} + +module_init(slot_dev_drv_init); +module_exit(slot_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("slot device driver"); diff --git a/platform/s3ip-sysfs/demo_driver/syseeprom_device_driver.c b/platform/s3ip-sysfs/demo_driver/syseeprom_device_driver.c new file mode 100644 index 000000000000..0ee7c6459a30 --- /dev/null +++ b/platform/s3ip-sysfs/demo_driver/syseeprom_device_driver.c @@ -0,0 +1,106 @@ +/* + * syseeprom_device_driver.c + * + * This module realize /sys/s3ip/syseeprom attributes read and write functions + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-08-31 S3IP sysfs + */ + +#include + +#include "device_driver_common.h" +#include "syseeprom_sysfs.h" + +#define SYSE2_INFO(fmt, args...) LOG_INFO("syseeprom: ", fmt, ##args) +#define SYSE2_ERR(fmt, args...) LOG_ERR("syseeprom: ", fmt, ##args) +#define SYSE2_DBG(fmt, args...) LOG_DBG("syseeprom: ", fmt, ##args) + +static int g_loglevel = 0; + +/*****************************************syseeprom*******************************************/ +/* + * demo_get_syseeprom_size - Used to get syseeprom size + * + * This function returns the size of syseeprom by your switch, + * otherwise it returns a negative value on failed. + */ +static int demo_get_syseeprom_size(void) +{ + /* add vendor codes here */ + return 256; +} + +/* + * demo_read_syseeprom_data - Used to read syseeprom data, + * @buf: Data read buffer + * @offset: offset address to read syseeprom data + * @count: length of buf + * + * This function returns the length of the filled buffer, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_read_syseeprom_data(char *buf, loff_t offset, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_write_syseeprom_data - Used to write syseeprom data + * @buf: Data write buffer + * @offset: offset address to write syseeprom data + * @count: length of buf + * + * This function returns the written length of syseeprom, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_write_syseeprom_data(char *buf, loff_t offset, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} +/*************************************end of syseeprom****************************************/ + +static struct s3ip_sysfs_syseeprom_drivers_s drivers = { + /* + * set ODM syseeprom drivers to /sys/s3ip/syseeprom, + * if not support the function, set corresponding hook to NULL. + */ + .get_syseeprom_size = demo_get_syseeprom_size, + .read_syseeprom_data = demo_read_syseeprom_data, + .write_syseeprom_data = demo_write_syseeprom_data, +}; + +static int __init syseeprom_dev_drv_init(void) +{ + int ret; + + SYSE2_INFO("syseeprom_dev_drv_init...\n"); + + ret = s3ip_sysfs_syseeprom_drivers_register(&drivers); + if (ret < 0) { + SYSE2_ERR("syseeprom drivers register err, ret %d.\n", ret); + return ret; + } + SYSE2_INFO("syseeprom_dev_drv_init success.\n"); + return 0; +} + +static void __exit syseeprom_dev_drv_exit(void) +{ + s3ip_sysfs_syseeprom_drivers_unregister(); + SYSE2_INFO("syseeprom_exit success.\n"); + return; +} + +module_init(syseeprom_dev_drv_init); +module_exit(syseeprom_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("syseeprom device driver"); diff --git a/platform/s3ip-sysfs/demo_driver/sysled_device_driver.c b/platform/s3ip-sysfs/demo_driver/sysled_device_driver.c new file mode 100644 index 000000000000..69ae1628f50d --- /dev/null +++ b/platform/s3ip-sysfs/demo_driver/sysled_device_driver.c @@ -0,0 +1,175 @@ +/* + * sysled_device_driver.c + * + * This module realize /sys/s3ip/sysled attributes read and write functions + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-08-31 S3IP sysfs + */ + +#include + +#include "device_driver_common.h" +#include "sysled_sysfs.h" + +#define SYSLED_INFO(fmt, args...) LOG_INFO("sysled: ", fmt, ##args) +#define SYSLED_ERR(fmt, args...) LOG_ERR("sysled: ", fmt, ##args) +#define SYSLED_DBG(fmt, args...) LOG_DBG("sysled: ", fmt, ##args) + +static int g_loglevel = 0; + +/*****************************************sysled**********************************************/ +/* + * demo_get_sys_led_status - Used to get sys led status + * filled the value to buf, led status value define as below: + * 0: dark + * 1: green + * 2: yellow + * 3: red + * 4:blue + * 5: green light flashing + * 6: yellow light flashing + * 7: red light flashing + * 8:blue light flashing + * + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_sys_led_status(char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_sys_led_status - Used to set sys led status + * @status: led status, led status value define as below: + * 0: dark + * 1: green + * 2: yellow + * 3: red + * 4:blue + * 5: green light flashing + * 6: yellow light flashing + * 7: red light flashing + * 8:blue light flashing + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_sys_led_status(int status) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* Similar to demo_get_sys_led_status */ +static ssize_t demo_get_bmc_led_status(char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* Similar to demo_set_sys_led_status */ +static int demo_set_bmc_led_status(int status) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* Similar to demo_get_sys_led_status */ +static ssize_t demo_get_sys_fan_led_status(char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* Similar to demo_set_sys_led_status */ +static int demo_set_sys_fan_led_status(int status) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* Similar to demo_get_sys_led_status */ +static ssize_t demo_get_sys_psu_led_status(char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* Similar to demo_set_sys_led_status */ +static int demo_set_sys_psu_led_status(int status) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* Similar to demo_get_sys_led_status */ +static ssize_t demo_get_id_led_status(char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* Similar to demo_set_sys_led_status */ +static int demo_set_id_led_status(int status) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/**************************************end of sysled******************************************/ + +static struct s3ip_sysfs_sysled_drivers_s drivers = { + /* + * set ODM sysled drivers to /sys/s3ip/sysled, + * if not support the function, set corresponding hook to NULL. + */ + .get_sys_led_status = demo_get_sys_led_status, + .set_sys_led_status = demo_set_sys_led_status, + .get_bmc_led_status = demo_get_bmc_led_status, + .set_bmc_led_status = demo_set_bmc_led_status, + .get_sys_fan_led_status = demo_get_sys_fan_led_status, + .set_sys_fan_led_status = demo_set_sys_fan_led_status, + .get_sys_psu_led_status = demo_get_sys_psu_led_status, + .set_sys_psu_led_status = demo_set_sys_psu_led_status, + .get_id_led_status = demo_get_id_led_status, + .set_id_led_status = demo_set_id_led_status, +}; + +static int __init sysled_init(void) +{ + int ret; + + SYSLED_INFO("sysled_init...\n"); + + ret = s3ip_sysfs_sysled_drivers_register(&drivers); + if (ret < 0) { + SYSLED_ERR("sysled drivers register err, ret %d.\n", ret); + return ret; + } + + SYSLED_INFO("sysled create success.\n"); + return 0; +} + +static void __exit sysled_exit(void) +{ + s3ip_sysfs_sysled_drivers_unregister(); + SYSLED_INFO("sysled_exit ok.\n"); + return; +} + +module_init(sysled_init); +module_exit(sysled_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("sysled device driver"); diff --git a/platform/s3ip-sysfs/demo_driver/temp_sensor_device_driver.c b/platform/s3ip-sysfs/demo_driver/temp_sensor_device_driver.c new file mode 100644 index 000000000000..e49887f2ee59 --- /dev/null +++ b/platform/s3ip-sysfs/demo_driver/temp_sensor_device_driver.c @@ -0,0 +1,196 @@ +/* + * temp_sensor_device_driver.c + * + * This module realize /sys/s3ip/temp_sensor attributes read and write functions + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-08-31 S3IP sysfs + */ + +#include + +#include "device_driver_common.h" +#include "temp_sensor_sysfs.h" + +#define TEMP_SENSOR_INFO(fmt, args...) LOG_INFO("temp_sensor: ", fmt, ##args) +#define TEMP_SENSOR_ERR(fmt, args...) LOG_ERR("temp_sensor: ", fmt, ##args) +#define TEMP_SENSOR_DBG(fmt, args...) LOG_DBG("temp_sensor: ", fmt, ##args) + +static int g_loglevel = 0; + +/***************************************main board temp*****************************************/ +/* + * demo_get_main_board_temp_number - Used to get main board temperature sensors number, + * + * This function returns main board temperature sensors by your switch, + * If there is no main board temperature sensors, returns 0, + * otherwise it returns a negative value on failed. + */ +static int demo_get_main_board_temp_number(void) +{ + /* add vendor codes here */ + return 1; +} + +/* + * demo_get_main_board_temp_alias - Used to identify the location of the temperature sensor, + * such as air_inlet, air_outlet and so on. + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_temp_alias(unsigned int temp_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_main_board_temp_type - Used to get the model of temperature sensor, + * such as lm75, tmp411 and so on + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_temp_type(unsigned int temp_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_main_board_temp_max - Used to get the maximum threshold of temperature sensor + * filled the value to buf, and the value keep three decimal places + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_temp_max(unsigned int temp_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_main_board_temp_max - Used to set the maximum threshold of temperature sensor + * get value from buf and set it to maximum threshold of temperature sensor + * @temp_index: start with 1 + * @buf: the buf store the data to be set, eg '80.000' + * @count: length of buf + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_main_board_temp_max(unsigned int temp_index, const char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_main_board_temp_min - Used to get the minimum threshold of temperature sensor + * filled the value to buf, and the value keep three decimal places + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_temp_min(unsigned int temp_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_main_board_temp_min - Used to set the minimum threshold of temperature sensor + * get value from buf and set it to minimum threshold of temperature sensor + * @temp_index: start with 1 + * @buf: the buf store the data to be set, eg '50.000' + * @count: length of buf + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_main_board_temp_min(unsigned int temp_index, const char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_main_board_temp_value - Used to get the input value of temperature sensor + * filled the value to buf, and the value keep three decimal places + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_temp_value(unsigned int temp_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} +/***********************************end of main board temp*************************************/ + +static struct s3ip_sysfs_temp_sensor_drivers_s drivers = { + /* + * set ODM temperature sensor drivers to /sys/s3ip/temp_sensor, + * if not support the function, set corresponding hook to NULL. + */ + .get_main_board_temp_number = demo_get_main_board_temp_number, + .get_main_board_temp_alias = demo_get_main_board_temp_alias, + .get_main_board_temp_type = demo_get_main_board_temp_type, + .get_main_board_temp_max = demo_get_main_board_temp_max, + .set_main_board_temp_max = demo_set_main_board_temp_max, + .get_main_board_temp_min = demo_get_main_board_temp_min, + .set_main_board_temp_min = demo_set_main_board_temp_min, + .get_main_board_temp_value = demo_get_main_board_temp_value, +}; + +static int __init temp_sensor_dev_drv_init(void) +{ + int ret; + + TEMP_SENSOR_INFO("temp_sensor_init...\n"); + + ret = s3ip_sysfs_temp_sensor_drivers_register(&drivers); + if (ret < 0) { + TEMP_SENSOR_ERR("temp sensor drivers register err, ret %d.\n", ret); + return ret; + } + TEMP_SENSOR_INFO("temp_sensor_init success.\n"); + return 0; +} + +static void __exit temp_sensor_dev_drv_exit(void) +{ + s3ip_sysfs_temp_sensor_drivers_unregister(); + TEMP_SENSOR_INFO("temp_sensor_exit success.\n"); + return; +} + +module_init(temp_sensor_dev_drv_init); +module_exit(temp_sensor_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("temperature sensors device driver"); diff --git a/platform/s3ip-sysfs/demo_driver/transceiver_device_driver.c b/platform/s3ip-sysfs/demo_driver/transceiver_device_driver.c new file mode 100644 index 000000000000..b89e1d7aa5b3 --- /dev/null +++ b/platform/s3ip-sysfs/demo_driver/transceiver_device_driver.c @@ -0,0 +1,335 @@ +/* + * transceiver_device_driver.c + * + * This module realize /sys/s3ip/transceiver attributes read and write functions + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-08-31 S3IP sysfs + */ + +#include + +#include "device_driver_common.h" +#include "transceiver_sysfs.h" + +#define SFF_INFO(fmt, args...) LOG_INFO("sff: ", fmt, ##args) +#define SFF_ERR(fmt, args...) LOG_ERR("sff: ", fmt, ##args) +#define SFF_DBG(fmt, args...) LOG_DBG("sff: ", fmt, ##args) + +static int g_loglevel = 0; + +/****************************************transceiver******************************************/ +static int demo_get_eth_number(void) +{ + /* add vendor codes here */ + return 1; +} + +/* + * demo_get_transceiver_power_on_status - Used to get the whole machine port power on status, + * filled the value to buf, 0: power off, 1: power on + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_transceiver_power_on_status(char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_transceiver_power_on_status - Used to set the whole machine port power on status, + * @status: power on status, 0: power off, 1: power on + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_transceiver_power_on_status(int status) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_eth_power_on_status - Used to get single port power on status, + * filled the value to buf, 0: power off, 1: power on + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_eth_power_on_status(unsigned int eth_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_eth_power_on_status - Used to set single port power on status, + * @eth_index: start with 1 + * @status: power on status, 0: power off, 1: power on + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_eth_power_on_status(unsigned int eth_index, int status) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_eth_tx_fault_status - Used to get port tx_fault status, + * filled the value to buf, 0: normal, 1: abnormal + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_eth_tx_fault_status(unsigned int eth_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_eth_tx_disable_status - Used to get port tx_disable status, + * filled the value to buf, 0: tx_enable, 1: tx_disable + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_eth_tx_disable_status(unsigned int eth_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_eth_tx_disable_status - Used to set port tx_disable status, + * @eth_index: start with 1 + * @status: tx_disable status, 0: tx_enable, 1: tx_disable + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_eth_tx_disable_status(unsigned int eth_index, int status) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_eth_present_status - Used to get port present status, + * filled the value to buf, 1: present, 0: absent + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_eth_present_status(unsigned int eth_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_eth_rx_los_status - Used to get port rx_los status, + * filled the value to buf, 0: normal, 1: abnormal + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_eth_rx_los_status(unsigned int eth_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_eth_reset_status - Used to get port reset status, + * filled the value to buf, 0: unreset, 1: reset + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_eth_reset_status(unsigned int eth_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_eth_reset_status - Used to set port reset status, + * @eth_index: start with 1 + * @status: reset status, 0: unreset, 1: reset + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_eth_reset_status(unsigned int eth_index, int status) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_eth_low_power_mode_status - Used to get port low power mode status, + * filled the value to buf, 0: high power mode, 1: low power mode + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_eth_low_power_mode_status(unsigned int eth_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_eth_interrupt_status - Used to get port interruption status, + * filled the value to buf, 0: no interruption, 1: interruption + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_eth_interrupt_status(unsigned int eth_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_eth_eeprom_size - Used to get port eeprom size + * + * This function returns the size of port eeprom, + * otherwise it returns a negative value on failed. + */ +static int demo_get_eth_eeprom_size(unsigned int eth_index) +{ + /* add vendor codes here */ + return 0x8180; +} + +/* + * demo_read_eth_eeprom_data - Used to read port eeprom data, + * @buf: Data read buffer + * @offset: offset address to read port eeprom data + * @count: length of buf + * + * This function returns the length of the filled buffer, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_read_eth_eeprom_data(unsigned int eth_index, char *buf, loff_t offset, + size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_write_eth_eeprom_data - Used to write port eeprom data + * @buf: Data write buffer + * @offset: offset address to write port eeprom data + * @count: length of buf + * + * This function returns the written length of port eeprom, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_write_eth_eeprom_data(unsigned int eth_index, char *buf, loff_t offset, + size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} +/************************************end of transceiver***************************************/ + +static struct s3ip_sysfs_transceiver_drivers_s drivers = { + /* + * set ODM transceiver drivers to /sys/s3ip/transceiver, + * if not support the function, set corresponding hook to NULL. + */ + .get_eth_number = demo_get_eth_number, + .get_transceiver_power_on_status = demo_get_transceiver_power_on_status, + .set_transceiver_power_on_status = demo_set_transceiver_power_on_status, + .get_eth_power_on_status = demo_get_eth_power_on_status, + .set_eth_power_on_status = demo_set_eth_power_on_status, + .get_eth_tx_fault_status = demo_get_eth_tx_fault_status, + .get_eth_tx_disable_status = demo_get_eth_tx_disable_status, + .set_eth_tx_disable_status = demo_set_eth_tx_disable_status, + .get_eth_present_status = demo_get_eth_present_status, + .get_eth_rx_los_status = demo_get_eth_rx_los_status, + .get_eth_reset_status = demo_get_eth_reset_status, + .set_eth_reset_status = demo_set_eth_reset_status, + .get_eth_low_power_mode_status = demo_get_eth_low_power_mode_status, + .get_eth_interrupt_status = demo_get_eth_interrupt_status, + .get_eth_eeprom_size = demo_get_eth_eeprom_size, + .read_eth_eeprom_data = demo_read_eth_eeprom_data, + .write_eth_eeprom_data = demo_write_eth_eeprom_data, +}; + +static int __init sff_dev_drv_init(void) +{ + int ret; + + SFF_INFO("sff_init...\n"); + + ret = s3ip_sysfs_sff_drivers_register(&drivers); + if (ret < 0) { + SFF_ERR("transceiver drivers register err, ret %d.\n", ret); + return ret; + } + SFF_INFO("sff_init success.\n"); + return 0; +} + +static void __exit sff_dev_drv_exit(void) +{ + s3ip_sysfs_sff_drivers_unregister(); + SFF_INFO("sff_exit success.\n"); + return; +} + +module_init(sff_dev_drv_init); +module_exit(sff_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("transceiver device driver"); diff --git a/platform/s3ip-sysfs/demo_driver/vol_sensor_device_driver.c b/platform/s3ip-sysfs/demo_driver/vol_sensor_device_driver.c new file mode 100644 index 000000000000..1c2b2fa7af59 --- /dev/null +++ b/platform/s3ip-sysfs/demo_driver/vol_sensor_device_driver.c @@ -0,0 +1,224 @@ +/* + * vol_sensor_device_driver.c + * + * This module realize /sys/s3ip/vol_sensor attributes read and write functions + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-08-31 S3IP sysfs + */ + +#include + +#include "device_driver_common.h" +#include "vol_sensor_sysfs.h" + +#define VOL_SENSOR_INFO(fmt, args...) LOG_INFO("vol_sensor: ", fmt, ##args) +#define VOL_SENSOR_ERR(fmt, args...) LOG_ERR("vol_sensor: ", fmt, ##args) +#define VOL_SENSOR_DBG(fmt, args...) LOG_DBG("vol_sensor: ", fmt, ##args) + +static int g_loglevel = 0; + +/*************************************main board voltage***************************************/ +static int demo_get_main_board_vol_number(void) +{ + /* add vendor codes here */ + return 1; +} + +/* + * demo_get_main_board_vol_alias - Used to identify the location of the voltage sensor, + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_vol_alias(unsigned int vol_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_main_board_vol_type - Used to get the model of voltage sensor, + * such as udc90160, tps53622 and so on + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_vol_type(unsigned int vol_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_main_board_vol_max - Used to get the maximum threshold of voltage sensor + * filled the value to buf, and the value keep three decimal places + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_vol_max(unsigned int vol_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_main_board_vol_max - Used to set the maximum threshold of volatge sensor + * get value from buf and set it to maximum threshold of volatge sensor + * @vol_index: start with 1 + * @buf: the buf store the data to be set, eg '3.567' + * @count: length of buf + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_main_board_vol_max(unsigned int vol_index, const char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_main_board_vol_min - Used to get the minimum threshold of voltage sensor + * filled the value to buf, and the value keep three decimal places + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_vol_min(unsigned int vol_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_main_board_vol_min - Used to set the minimum threshold of voltage sensor + * get value from buf and set it to minimum threshold of voltage sensor + * @temp_index: start with 1 + * @buf: the buf store the data to be set, eg '3.123' + * @count: length of buf + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_main_board_vol_min(unsigned int vol_index, const char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_main_board_vol_range - Used to get the output error value of voltage sensor + * filled the value to buf + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_vol_range(unsigned int vol_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_main_board_vol_nominal_value - Used to get the nominal value of voltage sensor + * filled the value to buf + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_vol_nominal_value(unsigned int vol_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_main_board_vol_value - Used to get the input value of voltage sensor + * filled the value to buf, and the value keep three decimal places + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_main_board_vol_value(unsigned int vol_index, char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} +/*********************************end of main board voltage************************************/ + +static struct s3ip_sysfs_vol_sensor_drivers_s drivers = { + /* + * set ODM voltage sensor drivers to /sys/s3ip/vol_sensor, + * if not support the function, set corresponding hook to NULL. + */ + .get_main_board_vol_number = demo_get_main_board_vol_number, + .get_main_board_vol_alias = demo_get_main_board_vol_alias, + .get_main_board_vol_type = demo_get_main_board_vol_type, + .get_main_board_vol_max = demo_get_main_board_vol_max, + .set_main_board_vol_max = demo_set_main_board_vol_max, + .get_main_board_vol_min = demo_get_main_board_vol_min, + .set_main_board_vol_min = demo_set_main_board_vol_min, + .get_main_board_vol_range = demo_get_main_board_vol_range, + .get_main_board_vol_nominal_value = demo_get_main_board_vol_nominal_value, + .get_main_board_vol_value = demo_get_main_board_vol_value, +}; + +static int __init vol_sensor_dev_drv_init(void) +{ + int ret; + + VOL_SENSOR_INFO("vol_sensor_init...\n"); + + ret = s3ip_sysfs_vol_sensor_drivers_register(&drivers); + if (ret < 0) { + VOL_SENSOR_ERR("vol sensor drivers register err, ret %d.\n", ret); + return ret; + } + VOL_SENSOR_INFO("vol_sensor_init success.\n"); + return 0; +} + +static void __exit vol_sensor_dev_drv_exit(void) +{ + s3ip_sysfs_vol_sensor_drivers_unregister(); + VOL_SENSOR_INFO("vol_sensor_exit success.\n"); + return; +} + +module_init(vol_sensor_dev_drv_init); +module_exit(vol_sensor_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("voltage sensors device driver"); diff --git a/platform/s3ip-sysfs/demo_driver/watchdog_device_driver.c b/platform/s3ip-sysfs/demo_driver/watchdog_device_driver.c new file mode 100755 index 000000000000..2cb5852a9908 --- /dev/null +++ b/platform/s3ip-sysfs/demo_driver/watchdog_device_driver.c @@ -0,0 +1,166 @@ +/* + * watchdog_device_driver.c + * + * This module realize /sys/s3ip/watchdog attributes read and write functions + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-08-31 S3IP sysfs + */ + +#include + +#include "device_driver_common.h" +#include "watchdog_sysfs.h" + +#define WDT_INFO(fmt, args...) LOG_INFO("watchdog: ", fmt, ##args) +#define WDT_ERR(fmt, args...) LOG_ERR("watchdog: ", fmt, ##args) +#define WDT_DBG(fmt, args...) LOG_DBG("watchdog: ", fmt, ##args) + +static int g_loglevel = 0; + +/****************************************watchdog*********************************************/ +/* + * demo_get_watchdog_identify - Used to get watchdog identify, such as iTCO_wdt + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_watchdog_identify(char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_watchdog_timeleft - Used to get watchdog timeleft, + * filled the value to buf + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_watchdog_timeleft(char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_watchdog_timeout - Used to get watchdog timeout, + * filled the value to buf + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_watchdog_timeout(char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_watchdog_timeout - Used to set watchdog timeout, + * @value: timeout value + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_watchdog_timeout(int value) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_watchdog_enable_status - Used to get watchdog enable status, + * filled the value to buf, 0: disable, 1: enable + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t demo_get_watchdog_enable_status(char *buf, size_t count) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_set_watchdog_enable_status - Used to set watchdog enable status, + * @value: enable status value, 0: disable, 1: enable + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int demo_set_watchdog_enable_status(int value) +{ + /* add vendor codes here */ + return -ENOSYS; +} + +/* + * demo_get_watchdog_state - Used to get watchdog state, + * filled the value to buf, 0: inactive, 1: active + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static int demo_set_watchdog_reset(int value) +{ + /* add vendor codes here */ + return -ENOSYS; +} +/*************************************end of watchdog*****************************************/ + +static struct s3ip_sysfs_watchdog_drivers_s drivers = { + /* + * set ODM watchdog sensor drivers to /sys/s3ip/watchdog, + * if not support the function, set corresponding hook to NULL. + */ + .get_watchdog_identify = demo_get_watchdog_identify, + .get_watchdog_timeleft = demo_get_watchdog_timeleft, + .get_watchdog_timeout = demo_get_watchdog_timeout, + .set_watchdog_timeout = demo_set_watchdog_timeout, + .get_watchdog_enable_status = demo_get_watchdog_enable_status, + .set_watchdog_enable_status = demo_set_watchdog_enable_status, + .set_watchdog_reset = demo_set_watchdog_reset, +}; + +static int __init watchdog_dev_drv_init(void) +{ + int ret; + + WDT_INFO("watchdog_init...\n"); + + ret = s3ip_sysfs_watchdog_drivers_register(&drivers); + if (ret < 0) { + WDT_ERR("watchdog drivers register err, ret %d.\n", ret); + return ret; + } + WDT_INFO("watchdog create success.\n"); + return 0; +} + +static void __exit watchdog_dev_drv_exit(void) +{ + s3ip_sysfs_watchdog_drivers_unregister(); + WDT_INFO("watchdog_exit success.\n"); + return; +} + +module_init(watchdog_dev_drv_init); +module_exit(watchdog_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("watchdog device driver"); diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/Makefile b/platform/s3ip-sysfs/s3ip_sysfs_frame/Makefile new file mode 100755 index 000000000000..38ed6083335a --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/Makefile @@ -0,0 +1,27 @@ +PWD = $(shell pwd) + +EXTRA_CFLAGS:= -I$(M)/include +EXTRA_CFLAGS+= -Wall + +s3ip_sysfs-objs := switch.o cpld_sysfs.o \ +curr_sensor_sysfs.o \ +fan_sysfs.o \ +fpga_sysfs.o \ +psu_sysfs.o \ +slot_sysfs.o \ +sysled_sysfs.o \ +temp_sensor_sysfs.o \ +transceiver_sysfs.o \ +vol_sensor_sysfs.o \ +watchdog_sysfs.o \ + +obj-m := s3ip_sysfs.o + +all: + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(sysfs_out_put_dir) ]; then mkdir -p $(sysfs_out_put_dir) ;fi + cp -p $(PWD)/*.ko $(sysfs_out_put_dir) +clean: + rm -f $(PWD)/*.o $(PWD)/*.ko $(PWD)/*.mod.c $(PWD)/.*.cmd + rm -f $(PWD)/Module.markers $(PWD)/Module.symvers $(PWD)/modules.order + rm -rf $(PWD)/.tmp_versions \ No newline at end of file diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/cpld_sysfs.c b/platform/s3ip-sysfs/s3ip_sysfs_frame/cpld_sysfs.c new file mode 100644 index 000000000000..9e3efaca497a --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/cpld_sysfs.c @@ -0,0 +1,365 @@ +/* + * cpld_sysfs.c + * + * This module create cpld kobjects and attributes in /sys/s3ip/cpld + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-08-31 S3IP sysfs + */ + +#include + +#include "switch.h" +#include "cpld_sysfs.h" + +static int g_cpld_loglevel = 0; + +#define CPLD_INFO(fmt, args...) do { \ + if (g_cpld_loglevel & INFO) { \ + printk(KERN_INFO "[CPLD_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define CPLD_ERR(fmt, args...) do { \ + if (g_cpld_loglevel & ERR) { \ + printk(KERN_ERR "[CPLD_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define CPLD_DBG(fmt, args...) do { \ + if (g_cpld_loglevel & DBG) { \ + printk(KERN_DEBUG "[CPLD_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct cpld_obj_s { + struct switch_obj *obj; +}; + +struct cpld_s { + unsigned int cpld_number; + struct cpld_obj_s *cpld; +}; + +static struct cpld_s g_cpld; +static struct switch_obj *g_cpld_obj = NULL; +static struct s3ip_sysfs_cpld_drivers_s *g_cpld_drv = NULL; + +static ssize_t cpld_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_cpld.cpld_number); +} + +static ssize_t cpld_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int cpld_index; + int ret; + + check_p(g_cpld_drv); + check_p(g_cpld_drv->get_main_board_cpld_alias); + + cpld_index = obj->index; + CPLD_DBG("cpld index: %u\n", cpld_index); + ret = g_cpld_drv->get_main_board_cpld_alias(cpld_index, buf, PAGE_SIZE); + if (ret < 0) { + CPLD_ERR("get cpld%u alias failed, ret: %d\n", cpld_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t cpld_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int cpld_index; + int ret; + + check_p(g_cpld_drv); + check_p(g_cpld_drv->get_main_board_cpld_type); + + cpld_index = obj->index; + CPLD_DBG("cpld index: %u\n", cpld_index); + ret = g_cpld_drv->get_main_board_cpld_type(cpld_index, buf, PAGE_SIZE); + if (ret < 0) { + CPLD_ERR("get cpld%u type failed, ret: %d\n", cpld_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t cpld_fw_version_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int cpld_index; + int ret; + + check_p(g_cpld_drv); + check_p(g_cpld_drv->get_main_board_cpld_firmware_version); + + cpld_index = obj->index; + CPLD_DBG("cpld index: %u\n", cpld_index); + ret = g_cpld_drv->get_main_board_cpld_firmware_version(cpld_index, buf, PAGE_SIZE); + if (ret < 0) { + CPLD_ERR("get cpld%u firmware version failed, ret: %d\n", cpld_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t cpld_board_version_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int cpld_index; + int ret; + + check_p(g_cpld_drv); + check_p(g_cpld_drv->get_main_board_cpld_board_version); + + cpld_index = obj->index; + CPLD_DBG("cpld index: %u\n", cpld_index); + ret = g_cpld_drv->get_main_board_cpld_board_version(cpld_index, buf, PAGE_SIZE); + if (ret < 0) { + CPLD_ERR("get cpld%u board version failed, ret: %d\n", cpld_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t cpld_test_reg_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int cpld_index; + int ret; + + check_p(g_cpld_drv); + check_p(g_cpld_drv->get_main_board_cpld_test_reg); + + cpld_index = obj->index; + CPLD_DBG("cpld index: %u\n", cpld_index); + ret = g_cpld_drv->get_main_board_cpld_test_reg(cpld_index, buf, PAGE_SIZE); + if (ret < 0) { + CPLD_ERR("get cpld%u test register failed, ret: %d\n", cpld_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t cpld_test_reg_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int cpld_index, value; + int ret; + + check_p(g_cpld_drv); + check_p(g_cpld_drv->set_main_board_cpld_test_reg); + + cpld_index = obj->index; + sscanf(buf, "0x%x", &value); + ret = g_cpld_drv->set_main_board_cpld_test_reg(cpld_index, value); + if (ret < 0) { + CPLD_ERR("set cpld%u test reg failed, value:0x%x, ret: %d.\n", cpld_index, value, ret); + return -EIO; + } + CPLD_DBG("set cpld%u test reg success, value: 0x%x.\n", cpld_index, value); + return count; +} + +/************************************cpld dir and attrs*******************************************/ +static struct switch_attribute cpld_number_att = __ATTR(number, S_IRUGO, cpld_number_show, NULL); + +static struct attribute *cpld_dir_attrs[] = { + &cpld_number_att.attr, + NULL, +}; + +static struct attribute_group cpld_root_attr_group = { + .attrs = cpld_dir_attrs, +}; + +/*******************************cpld[1-n] dir and attrs*******************************************/ +static struct switch_attribute cpld_alias_attr = __ATTR(alias, S_IRUGO, cpld_alias_show, NULL); +static struct switch_attribute cpld_type_attr = __ATTR(type, S_IRUGO, cpld_type_show, NULL); +static struct switch_attribute cpld_fw_version_attr = __ATTR(firmware_version, S_IRUGO, cpld_fw_version_show, NULL); +static struct switch_attribute cpld_board_version_attr = __ATTR(board_version, S_IRUGO, cpld_board_version_show, NULL); +static struct switch_attribute cpld_test_reg_attr = __ATTR(reg_test, S_IRUGO | S_IWUSR, cpld_test_reg_show, cpld_test_reg_store); + +static struct attribute *cpld_attrs[] = { + &cpld_alias_attr.attr, + &cpld_type_attr.attr, + &cpld_fw_version_attr.attr, + &cpld_board_version_attr.attr, + &cpld_test_reg_attr.attr, + NULL, +}; + +static struct attribute_group cpld_attr_group = { + .attrs = cpld_attrs, +}; + +static int cpld_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct cpld_obj_s *curr_cpld; + + curr_cpld = &g_cpld.cpld[index - 1]; + if (curr_cpld->obj) { + sysfs_remove_group(&curr_cpld->obj->kobj, &cpld_attr_group); + switch_kobject_delete(&curr_cpld->obj); + CPLD_DBG("delete cpld%u dir and attrs success.\n", index); + } + + return 0; +} + +static int cpld_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[8]; + struct cpld_obj_s *curr_cpld; + + curr_cpld = &g_cpld.cpld[index - 1]; + memset(name, 0, sizeof(name)); + snprintf(name, sizeof(name), "cpld%u", index); + curr_cpld->obj = switch_kobject_create(name, parent); + if (!curr_cpld->obj) { + CPLD_ERR("create %s object error!\n", name); + return -EBADRQC; + } + curr_cpld->obj->index = index; + if (sysfs_create_group(&curr_cpld->obj->kobj, &cpld_attr_group) != 0) { + CPLD_ERR("create %s attrs error.\n", name); + switch_kobject_delete(&curr_cpld->obj); + return -EBADRQC; + } + CPLD_DBG("create %s dir and attrs success.\n", name); + return 0; +} + +static int cpld_sub_create_kobj_and_attrs(struct kobject *parent, int cpld_num) +{ + unsigned int cpld_index, i; + + g_cpld.cpld = kzalloc(sizeof(struct cpld_obj_s) * cpld_num, GFP_KERNEL); + if (!g_cpld.cpld) { + CPLD_ERR("kzalloc g_cpld.cpld error, cpld number = %d.\n", cpld_num); + return -ENOMEM; + } + + for(cpld_index = 1; cpld_index <= cpld_num; cpld_index++) { + if(cpld_sub_single_create_kobj_and_attrs(parent, cpld_index) != 0) { + goto error; + } + } + return 0; +error: + for(i = cpld_index; i > 0; i--) { + cpld_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_cpld.cpld); + g_cpld.cpld = NULL; + return -EBADRQC; +} + +/* create cpld[1-n] directory and attributes*/ +static int cpld_sub_create(void) +{ + int ret; + + ret = cpld_sub_create_kobj_and_attrs(&g_cpld_obj->kobj, g_cpld.cpld_number); + return ret; +} + +/* delete cpld[1-n] directory and attributes*/ +static void cpld_sub_remove(void) +{ + unsigned int cpld_index; + + if (g_cpld.cpld) { + for (cpld_index = g_cpld.cpld_number; cpld_index > 0; cpld_index--) { + cpld_sub_single_remove_kobj_and_attrs(cpld_index); + } + kfree(g_cpld.cpld); + g_cpld.cpld = NULL; + } + g_cpld.cpld_number = 0; + return; +} + +/* create cpld directory and number attributes */ +static int cpld_root_create(void) +{ + g_cpld_obj = switch_kobject_create("cpld", NULL); + if (!g_cpld_obj) { + CPLD_ERR("switch_kobject_create cpld error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_cpld_obj->kobj, &cpld_root_attr_group) != 0) { + switch_kobject_delete(&g_cpld_obj); + CPLD_ERR("create cpld dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete cpld directory and number attributes */ +static void cpld_root_remove(void) +{ + if (g_cpld_obj) { + sysfs_remove_group(&g_cpld_obj->kobj, &cpld_root_attr_group); + switch_kobject_delete(&g_cpld_obj); + } + + return; +} + +int s3ip_sysfs_cpld_drivers_register(struct s3ip_sysfs_cpld_drivers_s *drv) +{ + int ret, cpld_num; + + CPLD_INFO("s3ip_sysfs_cpld_drivers_register...\n"); + if (g_cpld_drv) { + CPLD_ERR("g_cpld_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_main_board_cpld_number); + g_cpld_drv = drv; + + cpld_num = g_cpld_drv->get_main_board_cpld_number(); + if (cpld_num <= 0) { + CPLD_ERR("cpld number: %d, don't need to create cpld dirs and attrs.\n", cpld_num); + g_cpld_drv = NULL; + return -EINVAL; + } + + memset(&g_cpld, 0, sizeof(struct cpld_s)); + g_cpld.cpld_number = cpld_num; + ret = cpld_root_create(); + if (ret < 0) { + CPLD_ERR("create cpld root dir and attrs failed, ret: %d\n", ret); + g_cpld_drv = NULL; + return ret; + } + ret = cpld_sub_create(); + if (ret < 0) { + CPLD_ERR("create cpld sub dir and attrs failed, ret: %d\n", ret); + cpld_root_remove(); + g_cpld_drv = NULL; + return ret; + } + CPLD_INFO("s3ip_sysfs_cpld_drivers_register success\n"); + return 0; +} + +void s3ip_sysfs_cpld_drivers_unregister(void) +{ + if (g_cpld_drv) { + cpld_sub_remove(); + cpld_root_remove(); + g_cpld_drv = NULL; + CPLD_DBG("s3ip_sysfs_cpld_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_cpld_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_cpld_drivers_unregister); +module_param(g_cpld_loglevel, int, 0644); +MODULE_PARM_DESC(g_cpld_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/curr_sensor_sysfs.c b/platform/s3ip-sysfs/s3ip_sysfs_frame/curr_sensor_sysfs.c new file mode 100644 index 000000000000..7972dd9b3ee1 --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/curr_sensor_sysfs.c @@ -0,0 +1,391 @@ +/* + * curr_sensor_sysfs.c + * + * This module create curr sensor kobjects and attributes in /sys/s3ip/curr_sensor + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-08-31 S3IP sysfs + */ + +#include + +#include "switch.h" +#include "curr_sensor_sysfs.h" + +static int g_curr_sensor_loglevel = 0; + +#define CURR_SENSOR_INFO(fmt, args...) do { \ + if (g_curr_sensor_loglevel & INFO) { \ + printk(KERN_INFO "[CURR_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define CURR_SENSOR_ERR(fmt, args...) do { \ + if (g_curr_sensor_loglevel & ERR) { \ + printk(KERN_ERR "[CURR_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define CURR_SENSOR_DBG(fmt, args...) do { \ + if (g_curr_sensor_loglevel & DBG) { \ + printk(KERN_DEBUG "[CURR_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct curr_sensor_obj_s { + struct switch_obj *obj; +}; + +struct curr_sensor_s { + unsigned int curr_number; + struct curr_sensor_obj_s *curr; +}; + +static struct s3ip_sysfs_curr_sensor_drivers_s *g_curr_sensor_drv = NULL; +static struct curr_sensor_s g_curr_sensor; +static struct switch_obj *g_curr_sensor_obj = NULL; + +static ssize_t curr_sensor_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_curr_sensor.curr_number); +} + +static ssize_t curr_sensor_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int curr_index; + int ret; + + check_p(g_curr_sensor_drv); + check_p(g_curr_sensor_drv->get_main_board_curr_value); + + curr_index = obj->index; + CURR_SENSOR_DBG("curr index: %u\n", curr_index); + ret = g_curr_sensor_drv->get_main_board_curr_value(curr_index, buf, PAGE_SIZE); + if (ret < 0) { + CURR_SENSOR_ERR("get curr%u value failed, ret: %d\n", curr_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t curr_sensor_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int curr_index; + int ret; + + check_p(g_curr_sensor_drv); + check_p(g_curr_sensor_drv->get_main_board_curr_alias); + + curr_index = obj->index; + CURR_SENSOR_DBG("curr index: %u\n", curr_index); + ret = g_curr_sensor_drv->get_main_board_curr_alias(curr_index, buf, PAGE_SIZE); + if (ret < 0) { + CURR_SENSOR_ERR("get curr%u alias failed, ret: %d\n", curr_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t curr_sensor_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int curr_index; + int ret; + + check_p(g_curr_sensor_drv); + check_p(g_curr_sensor_drv->get_main_board_curr_type); + + curr_index = obj->index; + CURR_SENSOR_DBG("curr index: %u\n", curr_index); + ret = g_curr_sensor_drv->get_main_board_curr_type(curr_index, buf, PAGE_SIZE); + if (ret < 0) { + CURR_SENSOR_ERR("get curr%u type failed, ret: %d\n", curr_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t curr_sensor_max_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int curr_index; + int ret; + + check_p(g_curr_sensor_drv); + check_p(g_curr_sensor_drv->get_main_board_curr_max); + + curr_index = obj->index; + CURR_SENSOR_DBG("curr index: %u\n", curr_index); + ret = g_curr_sensor_drv->get_main_board_curr_max(curr_index, buf, PAGE_SIZE); + if (ret < 0) { + CURR_SENSOR_ERR("get curr%u max threshold failed, ret: %d\n", curr_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t curr_sensor_max_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int curr_index; + int ret; + + check_p(g_curr_sensor_drv); + check_p(g_curr_sensor_drv->set_main_board_curr_max); + + curr_index = obj->index; + CURR_SENSOR_DBG("curr index: %u\n", curr_index); + ret = g_curr_sensor_drv->set_main_board_curr_max(curr_index, buf, count); + if (ret < 0) { + CURR_SENSOR_ERR("set curr%u max threshold failed, value: %s, count: %lu, ret: %d\n", + curr_index, buf, count, ret); + return -EIO; + } + CURR_SENSOR_DBG("set curr%u max threshold success, value: %s, count: %lu, ret: %d\n", + curr_index, buf, count, ret); + return count; +} + +static ssize_t curr_sensor_min_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int curr_index; + int ret; + + check_p(g_curr_sensor_drv); + check_p(g_curr_sensor_drv->get_main_board_curr_min); + + curr_index = obj->index; + CURR_SENSOR_DBG("curr index: %u\n", curr_index); + ret = g_curr_sensor_drv->get_main_board_curr_min(curr_index, buf, PAGE_SIZE); + if (ret < 0) { + CURR_SENSOR_ERR("get curr%u min threshold failed, ret: %d\n", curr_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t curr_sensor_min_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int curr_index; + int ret; + + check_p(g_curr_sensor_drv); + check_p(g_curr_sensor_drv->set_main_board_curr_min); + + curr_index = obj->index; + CURR_SENSOR_DBG("curr index: %u\n", curr_index); + ret = g_curr_sensor_drv->set_main_board_curr_min(curr_index, buf, count); + if (ret < 0) { + CURR_SENSOR_ERR("set curr%u min threshold failed, value: %s, count: %lu, ret: %d\n", + curr_index, buf, count, ret); + return -EIO; + } + CURR_SENSOR_DBG("set curr%u min threshold success, value: %s, count: %lu, ret: %d\n", + curr_index, buf, count, ret); + return count; +} + +/************************************curr_sensor dir and attrs*******************************************/ +static struct switch_attribute num_curr_att = __ATTR(number, S_IRUGO, curr_sensor_number_show, NULL); + +static struct attribute *curr_sensor_dir_attrs[] = { + &num_curr_att.attr, + NULL, +}; + +static struct attribute_group curr_sensor_root_attr_group = { + .attrs = curr_sensor_dir_attrs, +}; + +/*******************************curr1 curr2 dir and attrs*******************************************/ +static struct switch_attribute curr_value_attr = __ATTR(value, S_IRUGO, curr_sensor_value_show, NULL); +static struct switch_attribute curr_alias_attr = __ATTR(alias, S_IRUGO, curr_sensor_alias_show, NULL); +static struct switch_attribute curr_type_attr = __ATTR(type, S_IRUGO, curr_sensor_type_show, NULL); +static struct switch_attribute curr_max_attr = __ATTR(max, S_IRUGO | S_IWUSR, curr_sensor_max_show, curr_sensor_max_store); +static struct switch_attribute curr_min_attr = __ATTR(min, S_IRUGO | S_IWUSR, curr_sensor_min_show, curr_sensor_min_store); + +static struct attribute *curr_sensor_attrs[] = { + &curr_value_attr.attr, + &curr_alias_attr.attr, + &curr_type_attr.attr, + &curr_max_attr.attr, + &curr_min_attr.attr, + NULL, +}; + +static struct attribute_group curr_sensor_attr_group = { + .attrs = curr_sensor_attrs, +}; + +static int curr_sensor_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[DIR_NAME_MAX_LEN]; + struct curr_sensor_obj_s *curr_sensor; + + curr_sensor = &g_curr_sensor.curr[index - 1]; + memset(name, 0, sizeof(name)); + snprintf(name, sizeof(name), "curr%u", index); + curr_sensor->obj = switch_kobject_create(name, parent); + if (!curr_sensor->obj) { + CURR_SENSOR_ERR("create %s object error.\n", name); + return -ENOMEM; + } + curr_sensor->obj->index = index; + if (sysfs_create_group(&curr_sensor->obj->kobj, &curr_sensor_attr_group) != 0) { + CURR_SENSOR_ERR("create %s attrs error.\n", name); + switch_kobject_delete(&curr_sensor->obj); + return -EBADRQC; + } + CURR_SENSOR_DBG("create %s dir and attrs success.\n", name); + return 0; +} + +static void curr_sensor_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct curr_sensor_obj_s *curr_sensor; + + curr_sensor = &g_curr_sensor.curr[index - 1]; + if (curr_sensor->obj) { + sysfs_remove_group(&curr_sensor->obj->kobj, &curr_sensor_attr_group); + switch_kobject_delete(&curr_sensor->obj); + CURR_SENSOR_DBG("delete curr%u dir and attrs success.\n", index); + } + + return; +} + +static int curr_sensor_sub_create_kobj_and_attrs(struct kobject *parent, int curr_num) +{ + unsigned int curr_index, i; + + g_curr_sensor.curr = kzalloc(sizeof(struct curr_sensor_obj_s) * curr_num, GFP_KERNEL); + if (!g_curr_sensor.curr) { + CURR_SENSOR_ERR("kzalloc g_curr_sensor.curr error, curr number: %d.\n", curr_num); + return -ENOMEM; + } + + for (curr_index = 1; curr_index <= curr_num; curr_index++) { + if (curr_sensor_sub_single_create_kobj_and_attrs(parent, curr_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = curr_index; i > 0; i--) { + curr_sensor_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_curr_sensor.curr); + g_curr_sensor.curr = NULL; + return -EBADRQC; +} + +/* create curr[1-n] directory and attributes*/ +static int curr_sensor_sub_create(void) +{ + int ret; + + ret = curr_sensor_sub_create_kobj_and_attrs(&g_curr_sensor_obj->kobj, + g_curr_sensor.curr_number); + return ret; +} + +/* delete curr[1-n] directory and attributes*/ +static void curr_sensor_sub_remove(void) +{ + unsigned int curr_index; + + if (g_curr_sensor.curr) { + for (curr_index = g_curr_sensor.curr_number; curr_index > 0; curr_index--) { + curr_sensor_sub_single_remove_kobj_and_attrs(curr_index); + } + kfree(g_curr_sensor.curr); + g_curr_sensor.curr = NULL; + } + g_curr_sensor.curr_number = 0; + return; +} + +/* create curr_sensor directory and number attributes */ +static int curr_sensor_root_create(void) +{ + g_curr_sensor_obj = switch_kobject_create("curr_sensor", NULL); + if (!g_curr_sensor_obj) { + CURR_SENSOR_ERR("switch_kobject_create curr_sensor error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_curr_sensor_obj->kobj, &curr_sensor_root_attr_group) != 0) { + switch_kobject_delete(&g_curr_sensor_obj); + CURR_SENSOR_ERR("create curr_sensor dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete curr_sensor directory and number attributes */ +static void curr_sensor_root_remove(void) +{ + if (g_curr_sensor_obj) { + sysfs_remove_group(&g_curr_sensor_obj->kobj, &curr_sensor_root_attr_group); + switch_kobject_delete(&g_curr_sensor_obj); + } + + return; +} + +int s3ip_sysfs_curr_sensor_drivers_register(struct s3ip_sysfs_curr_sensor_drivers_s *drv) +{ + int ret, curr_num; + + CURR_SENSOR_INFO("s3ip_sysfs_curr_sensor_drivers_register...\n"); + if (g_curr_sensor_drv) { + CURR_SENSOR_ERR("g_curr_sensor_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_main_board_curr_number); + g_curr_sensor_drv = drv; + + curr_num = g_curr_sensor_drv->get_main_board_curr_number(); + if (curr_num <= 0) { + CURR_SENSOR_ERR("curr sensor number: %d, don't need to create curr_sensor dirs and attrs.\n", + curr_num); + return -EINVAL; + } + memset(&g_curr_sensor, 0, sizeof(struct curr_sensor_s)); + g_curr_sensor.curr_number = curr_num; + ret = curr_sensor_root_create(); + if (ret < 0) { + CURR_SENSOR_ERR("create curr_sensor root dir and attrs failed, ret: %d\n", ret); + g_curr_sensor_drv = NULL; + return ret; + } + + ret = curr_sensor_sub_create(); + if (ret < 0) { + CURR_SENSOR_ERR("create curr_sensor sub dir and attrs failed, ret: %d\n", ret); + curr_sensor_root_remove(); + g_curr_sensor_drv = NULL; + return ret; + } + CURR_SENSOR_INFO("s3ip_sysfs_curr_sensor_drivers_register success\n"); + return ret; +} + +void s3ip_sysfs_curr_sensor_drivers_unregister(void) +{ + if (g_curr_sensor_drv) { + curr_sensor_sub_remove(); + curr_sensor_root_remove(); + g_curr_sensor_drv = NULL; + CURR_SENSOR_DBG("s3ip_sysfs_curr_sensor_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_curr_sensor_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_curr_sensor_drivers_unregister); +module_param(g_curr_sensor_loglevel, int, 0644); +MODULE_PARM_DESC(g_curr_sensor_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/fan_sysfs.c b/platform/s3ip-sysfs/s3ip_sysfs_frame/fan_sysfs.c new file mode 100755 index 000000000000..b9602b9e2093 --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/fan_sysfs.c @@ -0,0 +1,754 @@ +/* + * fan_sysfs.c + * + * This module create fan kobjects and attributes in /sys/s3ip/fan + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-08-31 S3IP sysfs + */ + +#include + +#include "switch.h" +#include "fan_sysfs.h" + +static int g_fan_loglevel = 0; + +#define FAN_INFO(fmt, args...) do { \ + if (g_fan_loglevel & INFO) { \ + printk(KERN_INFO "[FAN_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FAN_ERR(fmt, args...) do { \ + if (g_fan_loglevel & ERR) { \ + printk(KERN_ERR "[FAN_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FAN_DBG(fmt, args...) do { \ + if (g_fan_loglevel & DBG) { \ + printk(KERN_DEBUG "[FAN_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct motor_obj_s { + struct switch_obj *obj; +}; + +struct fan_obj_s { + unsigned int motor_number; + struct motor_obj_s *motor; + struct switch_obj *obj; +}; + +struct fan_s { + unsigned int fan_number; + struct fan_obj_s *fan; +}; + +static struct fan_s g_fan; +static struct switch_obj *g_fan_obj = NULL; +static struct s3ip_sysfs_fan_drivers_s *g_fan_drv = NULL; + +static ssize_t fan_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_fan.fan_number); +} + +static ssize_t fan_motor_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int index; + + index = obj->index; + FAN_DBG("fan_motor_number_show, fan index: %u\n", index); + + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_fan.fan[index - 1].motor_number); +} + +static ssize_t fan_model_name_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int fan_index; + int ret; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_model_name); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + ret = g_fan_drv->get_fan_model_name(fan_index, buf, PAGE_SIZE); + if (ret < 0) { + FAN_ERR("get fan%u model name failed, ret: %d\n", fan_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t fan_sn_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int fan_index; + int ret; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_serial_number); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + ret = g_fan_drv->get_fan_serial_number(fan_index, buf, PAGE_SIZE); + if (ret < 0) { + FAN_ERR("get fan%u serial number failed, ret: %d\n", fan_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t fan_pn_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index; + int ret; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_part_number); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + ret = g_fan_drv->get_fan_part_number(fan_index, buf, PAGE_SIZE); + if (ret < 0) { + FAN_ERR("get fan%u part number failed, ret: %d\n", fan_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t fan_hw_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index; + int ret; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_hardware_version); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + ret = g_fan_drv->get_fan_hardware_version(fan_index, buf, PAGE_SIZE); + if (ret < 0) { + FAN_ERR("get fan%u hardware version failed, ret: %d\n", fan_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t fan_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index; + int ret; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_status); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + ret = g_fan_drv->get_fan_status(fan_index, buf, PAGE_SIZE); + if (ret < 0) { + FAN_ERR("get fan%u status failed, ret: %d\n", fan_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t fan_led_status_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int fan_index; + int ret; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_led_status); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + ret = g_fan_drv->get_fan_led_status(fan_index, buf, PAGE_SIZE); + if (ret < 0) { + FAN_ERR("get fan%u led status failed, ret: %d\n", fan_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t fan_led_status_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + unsigned int fan_index; + int ret, led_status; + + check_p(g_fan_drv); + check_p(g_fan_drv->set_fan_led_status); + + fan_index = obj->index; + sscanf(buf, "%d", &led_status); + FAN_DBG("fan index: %u, led_status: %d\n", fan_index, led_status); + ret = g_fan_drv->set_fan_led_status(fan_index, led_status); + if (ret < 0) { + FAN_ERR("set fan%u led_status: %d failed, ret: %d\n", fan_index, led_status, ret); + return -EIO; + } + FAN_DBG("set fan%u led_status: %d success\n", fan_index, led_status); + return count; +} + +static ssize_t fan_motor_speed_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int fan_index, motor_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_motor_speed); + + p_obj = to_switch_obj(obj->kobj.parent); + fan_index = p_obj->index; + motor_index = obj->index; + FAN_DBG("fan index: %u, motor index: %d\n", fan_index, motor_index); + ret = g_fan_drv->get_fan_motor_speed(fan_index, motor_index, buf, PAGE_SIZE); + if (ret < 0) { + FAN_ERR("get fan%u motor%u speed failed, ret: %d\n", fan_index, motor_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t fan_motor_speed_tolerance_show(struct switch_obj *obj, + struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index, motor_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_motor_speed_tolerance); + + p_obj = to_switch_obj(obj->kobj.parent); + fan_index = p_obj->index; + motor_index = obj->index; + FAN_DBG("fan index: %u, motor index: %d\n", fan_index, motor_index); + ret = g_fan_drv->get_fan_motor_speed_tolerance(fan_index, motor_index, buf, PAGE_SIZE); + if (ret < 0) { + FAN_ERR("get fan%u motor%u speed tolerance failed, ret: %d\n", + fan_index, motor_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t fan_motor_speed_target_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int fan_index, motor_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_motor_speed_target); + + p_obj = to_switch_obj(obj->kobj.parent); + fan_index = p_obj->index; + motor_index = obj->index; + FAN_DBG("fan index: %u, motor index: %d\n", fan_index, motor_index); + ret = g_fan_drv->get_fan_motor_speed_target(fan_index, motor_index, buf, PAGE_SIZE); + if (ret < 0) { + FAN_ERR("get fan%u motor%u speed target failed, ret: %d\n", fan_index, motor_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t fan_motor_speed_max_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int fan_index, motor_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_motor_speed_max); + + p_obj = to_switch_obj(obj->kobj.parent); + fan_index = p_obj->index; + motor_index = obj->index; + FAN_DBG("fan index: %u, motor index: %d\n", fan_index, motor_index); + ret = g_fan_drv->get_fan_motor_speed_max(fan_index, motor_index, buf, PAGE_SIZE); + if (ret < 0) { + FAN_ERR("get fan%u motor%u speed max threshold failed, ret: %d\n", + fan_index, motor_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t fan_motor_speed_min_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int fan_index, motor_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_motor_speed_min); + + p_obj = to_switch_obj(obj->kobj.parent); + fan_index = p_obj->index; + motor_index = obj->index; + FAN_DBG("fan index: %u, motor index: %d\n", fan_index, motor_index); + ret = g_fan_drv->get_fan_motor_speed_min(fan_index, motor_index, buf, PAGE_SIZE); + if (ret < 0) { + FAN_ERR("get fan%u motor%u speed min threshold failed, ret: %d\n", + fan_index, motor_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +ssize_t fan_ratio_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index; + int ret; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_ratio); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + ret = g_fan_drv->get_fan_ratio(fan_index, buf, PAGE_SIZE); + if (ret < 0) { + FAN_ERR("get fan%u ratio failed, ret: %d\n", fan_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t fan_ratio_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int fan_index; + int ret, ratio; + + check_p(g_fan_drv); + check_p(g_fan_drv->set_fan_ratio); + + fan_index = obj->index; + sscanf(buf, "%d", &ratio); + if (ratio < 0 || ratio > 100) { + FAN_ERR("param invalid, can not set ratio: %d.\n", ratio); + return -EINVAL; + } + FAN_DBG("fan index: %u, ratio: %d\n", fan_index, ratio); + ret = g_fan_drv->set_fan_ratio(fan_index, ratio); + if (ret < 0) { + FAN_ERR("set fan%u ratio: %d failed, ret: %d\n", fan_index, ratio, ret); + return -EIO; + } + FAN_DBG("set fan%u, ratio: %d success\n", fan_index, ratio); + return count; +} + +ssize_t fan_direction_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index; + int ret; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_direction); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + ret = g_fan_drv->get_fan_direction(fan_index, buf, PAGE_SIZE); + if (ret < 0) { + FAN_ERR("get fan%u direction failed, ret: %d\n", fan_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +/************************************fan dir and attrs*******************************************/ +static struct switch_attribute fan_number_att = __ATTR(number, S_IRUGO, fan_number_show, NULL); + +static struct attribute *fan_dir_attrs[] = { + &fan_number_att.attr, + NULL, +}; + +static struct attribute_group fan_root_attr_group = { + .attrs = fan_dir_attrs, +}; + +/*******************************fan1 fan2 dir and attrs*******************************************/ +static struct switch_attribute fan_model_name_attr = __ATTR(model_name, S_IRUGO, fan_model_name_show, NULL); +static struct switch_attribute fan_sn_attr = __ATTR(serial_number, S_IRUGO, fan_sn_show, NULL); +static struct switch_attribute fan_pn_attr = __ATTR(part_number, S_IRUGO, fan_pn_show, NULL); +static struct switch_attribute fan_hw_attr = __ATTR(hardware_version, S_IRUGO, fan_hw_show, NULL); +static struct switch_attribute fan_num_motors_attr = __ATTR(motor_number, S_IRUGO, fan_motor_number_show, NULL); +static struct switch_attribute fan_status_attr = __ATTR(status, S_IRUGO, fan_status_show, NULL); +static struct switch_attribute fan_led_status_attr = __ATTR(led_status, S_IRUGO | S_IWUSR, fan_led_status_show, fan_led_status_store); +static struct switch_attribute fan_direction_attr = __ATTR(direction, S_IRUGO, fan_direction_show, NULL); +static struct switch_attribute fan_ratio_attr = __ATTR(ratio, S_IRUGO | S_IWUSR, fan_ratio_show, fan_ratio_store); + + +static struct attribute *fan_attrs[] = { + &fan_model_name_attr.attr, + &fan_sn_attr.attr, + &fan_pn_attr.attr, + &fan_hw_attr.attr, + &fan_num_motors_attr.attr, + &fan_status_attr.attr, + &fan_led_status_attr.attr, + &fan_direction_attr.attr, + &fan_ratio_attr.attr, + NULL, +}; + +static struct attribute_group fan_attr_group = { + .attrs = fan_attrs, +}; + +/*******************************motor1 motor2 dir and attrs*******************************************/ +static struct switch_attribute motor_speed_attr = __ATTR(speed, S_IRUGO, fan_motor_speed_show, NULL); +static struct switch_attribute motor_speed_tolerance_attr = __ATTR(speed_tolerance, S_IRUGO, fan_motor_speed_tolerance_show, NULL); +static struct switch_attribute motor_speed_target_attr = __ATTR(speed_target, S_IRUGO, fan_motor_speed_target_show, NULL); +static struct switch_attribute motor_speed_max_attr = __ATTR(speed_max, S_IRUGO, fan_motor_speed_max_show, NULL); +static struct switch_attribute motor_speed_min_attr = __ATTR(speed_min, S_IRUGO, fan_motor_speed_min_show, NULL); + +static struct attribute *motor_attrs[] = { + &motor_speed_attr.attr, + &motor_speed_tolerance_attr.attr, + &motor_speed_target_attr.attr, + &motor_speed_max_attr.attr, + &motor_speed_min_attr.attr, + NULL, +}; + +static struct attribute_group motor_attr_group = { + .attrs = motor_attrs, +}; + +static void fanindex_single_motor_remove_kobj_and_attrs(struct fan_obj_s *curr_fan, unsigned int motor_index) +{ + struct motor_obj_s *curr_motor; /* point to motor1 motor2...*/ + + curr_motor = &curr_fan->motor[motor_index - 1]; + if (curr_motor->obj) { + sysfs_remove_group(&curr_motor->obj->kobj, &motor_attr_group); + switch_kobject_delete(&curr_motor->obj); + FAN_DBG("delete fan%u motor%u dir and attrs success.\n", curr_fan->obj->index, + motor_index); + } + return; +} + +static int fanindex_single_motor_create_kobj_and_attrs(struct fan_obj_s *curr_fan, unsigned int motor_index) +{ + char name[8]; + struct motor_obj_s *curr_motor; /* point to motor1 motor2...*/ + + curr_motor = &curr_fan->motor[motor_index - 1]; + memset(name, 0, sizeof(name)); + snprintf(name, sizeof(name), "motor%u", motor_index); + curr_motor->obj = switch_kobject_create(name, &curr_fan->obj->kobj); + if (!curr_motor->obj) { + FAN_ERR("create fan%u, motor%u object error!\n", curr_fan->obj->index, motor_index); + return -ENOMEM; + } + + curr_motor->obj->index = motor_index; + if (sysfs_create_group(&curr_motor->obj->kobj, &motor_attr_group) != 0) { + FAN_ERR("create fan%u, motor%u attrs error.\n", curr_fan->obj->index, motor_index); + switch_kobject_delete(&curr_motor->obj); + return -EBADRQC; + } + FAN_DBG("create fan%u, motor%u dir and attrs success.\n", curr_fan->obj->index, motor_index); + return 0; +} + +/* create motor[1-n] directory and attributes in fan directory */ +static int fanindex_motor_create_kobj_and_attrs(struct fan_obj_s *curr_fan) +{ + unsigned int motor_index, i, motor_num; + + motor_num = curr_fan->motor_number; + curr_fan->motor = kzalloc(sizeof(struct motor_obj_s) * motor_num, GFP_KERNEL); + if (!curr_fan->motor) { + FAN_ERR("kzalloc motor error, fan index: %u, motor number: %d.\n", + curr_fan->obj->index, motor_num); + return -ENOMEM; + } + for(motor_index = 1; motor_index <= motor_num; motor_index++) { + if(fanindex_single_motor_create_kobj_and_attrs(curr_fan, motor_index) != 0 ) { + goto motor_error; + } + } + return 0; +motor_error: + for(i = motor_index; i > 0; i--) { + fanindex_single_motor_remove_kobj_and_attrs(curr_fan, i); + } + kfree(curr_fan->motor); + curr_fan->motor = NULL; + return -EBADRQC; +} + +/* delete motor[1-n] directory and attributes in fan directory */ +static void fanindex_motor_remove_kobj_and_attrs(struct fan_obj_s *curr_fan) +{ + unsigned int motor_index, motor_num; + + if (curr_fan->motor) { + motor_num = curr_fan->motor_number; + for(motor_index = motor_num; motor_index > 0; motor_index--) { + fanindex_single_motor_remove_kobj_and_attrs(curr_fan, motor_index); + } + kfree(curr_fan->motor); + curr_fan->motor = NULL; + } + + return; +} + +/* create motor[1-n] directory and attributes */ +static int fan_motor_create(void) +{ + int fan_num, motor_num; + unsigned int fan_index, i; + struct fan_obj_s *curr_fan; /* point to fan1 fan2...*/ + + fan_num = g_fan.fan_number; + if (fan_num <= 0) { + FAN_DBG("fan number: %d, skip to create motor* dirs and attrs.\n", fan_num); + return 0; + } + + check_p(g_fan_drv->get_fan_motor_number); + + for(fan_index = 1; fan_index <= fan_num; fan_index++) { + motor_num = g_fan_drv->get_fan_motor_number(fan_index); + if (motor_num <= 0) { + FAN_DBG("fan%u motor number: %d, don't need to create motor* dirs and attrs.\n", + fan_index, motor_num); + continue; + } + curr_fan = &g_fan.fan[fan_index - 1]; + curr_fan->motor_number = motor_num; + if(fanindex_motor_create_kobj_and_attrs(curr_fan) != 0) { + goto error; + } + } + return 0; +error: + for(i = fan_index; i > 0; i--) { + curr_fan = &g_fan.fan[i - 1]; + fanindex_motor_remove_kobj_and_attrs(curr_fan); + } + return -EBADRQC; +} + +/* delete motor[1-n] directory and attributes */ +static void fan_motor_remove(void) +{ + unsigned int fan_index; + struct fan_obj_s *curr_fan; + + if (g_fan.fan) { + for (fan_index = g_fan.fan_number; fan_index > 0; fan_index--) { + curr_fan = &g_fan.fan[fan_index - 1]; + fanindex_motor_remove_kobj_and_attrs(curr_fan); + curr_fan->motor_number = 0; + } + } + return; +} + +static int fan_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct fan_obj_s *curr_fan; + + curr_fan = &g_fan.fan[index - 1]; + if (curr_fan->obj) { + sysfs_remove_group(&curr_fan->obj->kobj, &fan_attr_group); + switch_kobject_delete(&curr_fan->obj); + FAN_DBG("delete fan%u dir and attrs success.\n", index); + } + return 0; +} + +static int fan_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[8]; + struct fan_obj_s *curr_fan; + + curr_fan = &g_fan.fan[index - 1]; + memset(name, 0, sizeof(name)); + snprintf(name, sizeof(name), "fan%u", index); + curr_fan->obj = switch_kobject_create(name, parent); + if (!curr_fan->obj) { + FAN_ERR("create %s object error!\n", name); + return -ENOMEM; + } + + curr_fan->obj->index = index; + if (sysfs_create_group(&curr_fan->obj->kobj, &fan_attr_group) != 0) { + FAN_ERR("create %s attrs error.\n", name); + switch_kobject_delete(&curr_fan->obj); + return -EBADRQC; + } + FAN_DBG("create %s dir and attrs success.\n", name); + return 0; +} + +/* create fan[1-n] directory and attributes */ +static int fan_sub_create_kobj_and_attrs(struct kobject *parent, int fan_num) +{ + unsigned int fan_index, i; + + g_fan.fan = kzalloc(sizeof(struct fan_obj_s) * fan_num, GFP_KERNEL); + if (!g_fan.fan) { + FAN_ERR("kzalloc fan.fan error, fan number: %d.\n", fan_num); + return -ENOMEM; + } + + for(fan_index = 1; fan_index <= fan_num; fan_index++) { + if(fan_sub_single_create_kobj_and_attrs(parent, fan_index) != 0 ) { + goto error; + } + } + return 0; +error: + for(i = fan_index; i > 0; i--) { + fan_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_fan.fan); + g_fan.fan = NULL; + return -EBADRQC; +} + +static int fan_sub_create(void) +{ + int ret; + + ret = fan_sub_create_kobj_and_attrs(&g_fan_obj->kobj, g_fan.fan_number); + return ret; +} + +/* delete fan[1-n] directory and attributes */ +static void fan_sub_remove(void) +{ + unsigned int fan_index; + + if (g_fan.fan) { + for (fan_index = g_fan.fan_number; fan_index > 0; fan_index--) { + fan_sub_single_remove_kobj_and_attrs(fan_index); + } + kfree(g_fan.fan); + g_fan.fan = NULL; + } + g_fan.fan_number = 0; + + return; +} + +/* create fan directory and number attributes */ +static int fan_root_create(void) +{ + g_fan_obj = switch_kobject_create("fan", NULL); + if (!g_fan_obj) { + FAN_ERR("switch_kobject_create fan error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_fan_obj->kobj, &fan_root_attr_group) != 0) { + switch_kobject_delete(&g_fan_obj); + FAN_ERR("create fan dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete fan directory and number attributes */ +static void fan_root_remove(void) +{ + if (g_fan_obj) { + sysfs_remove_group(&g_fan_obj->kobj, &fan_root_attr_group); + switch_kobject_delete(&g_fan_obj); + FAN_DBG("delete fan dir and attrs success.\n"); + } + return; +} + +int s3ip_sysfs_fan_drivers_register(struct s3ip_sysfs_fan_drivers_s *drv) +{ + int ret, fan_num; + + FAN_INFO("s3ip_sysfs_fan_drivers_register...\n"); + if (g_fan_drv) { + FAN_ERR("g_fan_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_fan_number); + g_fan_drv = drv; + + fan_num = g_fan_drv->get_fan_number(); + if (fan_num <= 0) { + FAN_ERR("fan number: %d, don't need to create fan dirs and attrs.\n", fan_num); + g_fan_drv = NULL; + return -EINVAL; + } + + memset(&g_fan, 0, sizeof(struct fan_s)); + g_fan.fan_number = fan_num; + ret = fan_root_create(); + if (ret < 0) { + FAN_ERR("create fan root dir and attrs failed, ret: %d\n", ret); + g_fan_drv = NULL; + return ret; + } + + ret = fan_sub_create(); + if (ret < 0) { + FAN_ERR("create fan sub dir and attrs failed, ret: %d\n", ret); + fan_root_remove(); + g_fan_drv = NULL; + return ret; + } + + ret = fan_motor_create(); + if (ret < 0) { + FAN_ERR("create fan motor dir and attrs failed, ret: %d\n", ret); + fan_sub_remove(); + fan_root_remove(); + g_fan_drv = NULL; + return ret; + } + FAN_INFO("s3ip_sysfs_fan_drivers_register success.\n"); + return 0; +} + +void s3ip_sysfs_fan_drivers_unregister(void) +{ + if (g_fan_drv) { + fan_motor_remove(); + fan_sub_remove(); + fan_root_remove(); + g_fan_drv = NULL; + FAN_DBG("s3ip_sysfs_fan_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_fan_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_fan_drivers_unregister); +module_param(g_fan_loglevel, int, 0644); +MODULE_PARM_DESC(g_fan_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/fpga_sysfs.c b/platform/s3ip-sysfs/s3ip_sysfs_frame/fpga_sysfs.c new file mode 100644 index 000000000000..8fc5736c0154 --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/fpga_sysfs.c @@ -0,0 +1,366 @@ +/* + * fpga_sysfs.c + * + * This module create fpga kobjects and attributes in /sys/s3ip/fpga + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-08-31 S3IP sysfs + */ + +#include + +#include "switch.h" +#include "fpga_sysfs.h" + +static int g_fpga_loglevel = 0; + +#define FPGA_INFO(fmt, args...) do { \ + if (g_fpga_loglevel & INFO) { \ + printk(KERN_INFO "[FPGA_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FPGA_ERR(fmt, args...) do { \ + if (g_fpga_loglevel & ERR) { \ + printk(KERN_ERR "[FPGA_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FPGA_DBG(fmt, args...) do { \ + if (g_fpga_loglevel & DBG) { \ + printk(KERN_DEBUG "[FPGA_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct fpga_obj_s { + struct switch_obj *obj; +}; + +struct fpga_s { + unsigned int fpga_number; + struct fpga_obj_s *fpga; +}; + +static struct fpga_s g_fpga; +static struct switch_obj *g_fpga_obj = NULL; +static struct s3ip_sysfs_fpga_drivers_s *g_fpga_drv = NULL; + +static ssize_t fpga_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_fpga.fpga_number); +} + +static ssize_t fpga_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fpga_index; + int ret; + + check_p(g_fpga_drv); + check_p(g_fpga_drv->get_main_board_fpga_alias); + + fpga_index = obj->index; + FPGA_DBG("fpga index: %u\n", fpga_index); + ret = g_fpga_drv->get_main_board_fpga_alias(fpga_index, buf, PAGE_SIZE); + if (ret < 0) { + FPGA_ERR("get fpga%u alias failed, ret: %d\n", fpga_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t fpga_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fpga_index; + int ret; + + check_p(g_fpga_drv); + check_p(g_fpga_drv->get_main_board_fpga_type); + + fpga_index = obj->index; + FPGA_DBG("fpga index: %u\n", fpga_index); + ret = g_fpga_drv->get_main_board_fpga_type(fpga_index, buf, PAGE_SIZE); + if (ret < 0) { + FPGA_ERR("get fpga%u type failed, ret: %d\n", fpga_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t fpga_fw_version_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fpga_index; + int ret; + + check_p(g_fpga_drv); + check_p(g_fpga_drv->get_main_board_fpga_firmware_version); + + fpga_index = obj->index; + FPGA_DBG("fpga index: %u\n", fpga_index); + ret = g_fpga_drv->get_main_board_fpga_firmware_version(fpga_index, buf, PAGE_SIZE); + if (ret < 0) { + FPGA_ERR("get fpga%u firmware version failed, ret: %d\n", fpga_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t fpga_board_version_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fpga_index; + int ret; + + check_p(g_fpga_drv); + check_p(g_fpga_drv->get_main_board_fpga_board_version); + + fpga_index = obj->index; + FPGA_DBG("fpga index: %u\n", fpga_index); + ret = g_fpga_drv->get_main_board_fpga_board_version(fpga_index, buf, PAGE_SIZE); + if (ret < 0) { + FPGA_ERR("get fpga%u board version failed, ret: %d\n", fpga_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t fpga_test_reg_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fpga_index; + int ret; + + check_p(g_fpga_drv); + check_p(g_fpga_drv->get_main_board_fpga_test_reg); + + fpga_index = obj->index; + FPGA_DBG("fpga index: %u\n", fpga_index); + ret = g_fpga_drv->get_main_board_fpga_test_reg(fpga_index, buf, PAGE_SIZE); + if (ret < 0) { + FPGA_ERR("get fpga%u test register failed, ret: %d\n", fpga_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t fpga_test_reg_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int fpga_index, value; + int ret; + + check_p(g_fpga_drv); + check_p(g_fpga_drv->set_main_board_fpga_test_reg); + + fpga_index = obj->index; + sscanf(buf, "0x%x", &value); + ret = g_fpga_drv->set_main_board_fpga_test_reg(fpga_index, value); + if (ret < 0) { + FPGA_ERR("set fpga%u test reg failed, value:0x%x, ret: %d.\n", fpga_index, value, ret); + return -EIO; + } + FPGA_DBG("set fpga%u test reg success, value: 0x%x.\n", fpga_index, value); + return count; +} + +/************************************fpga dir and attrs*******************************************/ +static struct switch_attribute fpga_number_att = __ATTR(number, S_IRUGO, fpga_number_show, NULL); + +static struct attribute *fpga_dir_attrs[] = { + &fpga_number_att.attr, + NULL, +}; + +static struct attribute_group fpga_root_attr_group = { + .attrs = fpga_dir_attrs, +}; + +/*******************************fpga[1-n] dir and attrs*******************************************/ +static struct switch_attribute fpga_alias_attr = __ATTR(alias, S_IRUGO, fpga_alias_show, NULL); +static struct switch_attribute fpga_type_attr = __ATTR(type, S_IRUGO, fpga_type_show, NULL); +static struct switch_attribute fpga_fw_version_attr = __ATTR(firmware_version, S_IRUGO, fpga_fw_version_show, NULL); +static struct switch_attribute fpga_board_version_attr = __ATTR(board_version, S_IRUGO, fpga_board_version_show, NULL); +static struct switch_attribute fpga_test_reg_attr = __ATTR(reg_test, S_IRUGO | S_IWUSR, fpga_test_reg_show, fpga_test_reg_store); + +static struct attribute *fpga_attrs[] = { + &fpga_alias_attr.attr, + &fpga_type_attr.attr, + &fpga_fw_version_attr.attr, + &fpga_board_version_attr.attr, + &fpga_test_reg_attr.attr, + NULL, +}; + +static struct attribute_group fpga_attr_group = { + .attrs = fpga_attrs, +}; + +static int fpga_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct fpga_obj_s *curr_fpga; + + curr_fpga = &g_fpga.fpga[index - 1]; + if (curr_fpga->obj) { + sysfs_remove_group(&curr_fpga->obj->kobj, &fpga_attr_group); + switch_kobject_delete(&curr_fpga->obj); + FPGA_DBG("delete fpga%u dir and attrs success.\n", index); + } + return 0; +} + +static int fpga_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[8]; + struct fpga_obj_s *curr_fpga; + + curr_fpga = &g_fpga.fpga[index - 1]; + memset(name, 0, sizeof(name)); + snprintf(name, sizeof(name), "fpga%u", index); + curr_fpga->obj = switch_kobject_create(name, parent); + if (!curr_fpga->obj) { + FPGA_ERR("create %s object error!\n", name); + return -EBADRQC; + } + curr_fpga->obj->index = index; + if (sysfs_create_group(&curr_fpga->obj->kobj, &fpga_attr_group) != 0) { + FPGA_ERR("create %s attrs error.\n", name); + switch_kobject_delete(&curr_fpga->obj); + return -EBADRQC; + } + FPGA_DBG("create %s dir and attrs success.\n", name); + return 0; +} + +static int fpga_sub_create_kobj_and_attrs(struct kobject *parent, int fpga_num) +{ + unsigned int fpga_index, i; + + g_fpga.fpga = kzalloc(sizeof(struct fpga_obj_s) * fpga_num, GFP_KERNEL); + if (!g_fpga.fpga) { + FPGA_ERR("kzalloc g_fpga.fpga error, fpga number = %d.\n", fpga_num); + return -ENOMEM; + } + + for(fpga_index = 1; fpga_index <= fpga_num; fpga_index++) { + if(fpga_sub_single_create_kobj_and_attrs(parent, fpga_index) != 0 ) { + goto error; + } + } + return 0; +error: + for(i = fpga_index; i > 0; i--) { + fpga_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_fpga.fpga); + g_fpga.fpga = NULL; + return -EBADRQC; +} + +/* create fpga[1-n] directory and attributes*/ +static int fpga_sub_create(void) +{ + int ret; + + ret = fpga_sub_create_kobj_and_attrs(&g_fpga_obj->kobj, g_fpga.fpga_number); + return ret; +} + +/* delete fpga[1-n] directory and attributes*/ +static void fpga_sub_remove(void) +{ + unsigned int fpga_index; + + if (g_fpga.fpga) { + for (fpga_index = g_fpga.fpga_number; fpga_index > 0; fpga_index--) { + fpga_sub_single_remove_kobj_and_attrs(fpga_index); + } + kfree(g_fpga.fpga); + g_fpga.fpga = NULL; + } + g_fpga.fpga_number = 0; + return; +} + +/* create fpga directory and number attributes */ +static int fpga_root_create(void) +{ + g_fpga_obj = switch_kobject_create("fpga", NULL); + if (!g_fpga_obj) { + FPGA_ERR("switch_kobject_create fpga error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_fpga_obj->kobj, &fpga_root_attr_group) != 0) { + switch_kobject_delete(&g_fpga_obj); + FPGA_ERR("create fpga dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete fpga directory and number attributes */ +static void fpga_root_remove(void) +{ + if (g_fpga_obj) { + sysfs_remove_group(&g_fpga_obj->kobj, &fpga_root_attr_group); + switch_kobject_delete(&g_fpga_obj); + } + + return; +} + +int s3ip_sysfs_fpga_drivers_register(struct s3ip_sysfs_fpga_drivers_s *drv) +{ + int ret, fpga_num; + + FPGA_INFO("s3ip_sysfs_fpga_drivers_register...\n"); + if (g_fpga_drv) { + FPGA_ERR("g_fpga_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_main_board_fpga_number); + g_fpga_drv = drv; + + fpga_num = g_fpga_drv->get_main_board_fpga_number(); + if (fpga_num <= 0) { + FPGA_ERR("fpga number: %d, don't need to create fpga dirs and attrs.\n", fpga_num); + g_fpga_drv = NULL; + return -EINVAL; + } + + memset(&g_fpga, 0, sizeof(struct fpga_s)); + g_fpga.fpga_number = fpga_num; + ret = fpga_root_create(); + if (ret < 0) { + FPGA_ERR("create fpga root dir and attrs failed, ret: %d\n", ret); + g_fpga_drv = NULL; + return ret; + } + ret = fpga_sub_create(); + if (ret < 0) { + FPGA_ERR("create fpga sub dir and attrs failed, ret: %d\n", ret); + fpga_root_remove(); + g_fpga_drv = NULL; + return ret; + } + FPGA_INFO("s3ip_sysfs_fpga_drivers_register success\n"); + return 0; +} + +void s3ip_sysfs_fpga_drivers_unregister(void) +{ + if (g_fpga_drv) { + fpga_sub_remove(); + fpga_root_remove(); + g_fpga_drv = NULL; + FPGA_DBG("s3ip_sysfs_fpga_drivers_unregister success.\n"); + } + + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_fpga_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_fpga_drivers_unregister); +module_param(g_fpga_loglevel, int, 0644); +MODULE_PARM_DESC(g_fpga_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); + diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/include/cpld_sysfs.h b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/cpld_sysfs.h new file mode 100644 index 000000000000..3d47a422ae01 --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/cpld_sysfs.h @@ -0,0 +1,16 @@ +#ifndef _CPLD_SYSFS_H_ +#define _CPLD_SYSFS_H_ + +struct s3ip_sysfs_cpld_drivers_s { + int (*get_main_board_cpld_number)(void); + ssize_t (*get_main_board_cpld_alias)(unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_main_board_cpld_type)(unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_main_board_cpld_firmware_version)(unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_main_board_cpld_board_version)(unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_main_board_cpld_test_reg)(unsigned int cpld_index, char *buf, size_t count); + int (*set_main_board_cpld_test_reg)(unsigned int cpld_index, unsigned int value); +}; + +extern int s3ip_sysfs_cpld_drivers_register(struct s3ip_sysfs_cpld_drivers_s *drv); +extern void s3ip_sysfs_cpld_drivers_unregister(void); +#endif /*_CPLD_SYSFS_H_ */ diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/include/curr_sensor_sysfs.h b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/curr_sensor_sysfs.h new file mode 100644 index 000000000000..7a0b85a0fc3c --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/curr_sensor_sysfs.h @@ -0,0 +1,17 @@ +#ifndef _CURR_SENSOR_SYSFS_H_ +#define _CURR_SENSOR_SYSFS_H_ + +struct s3ip_sysfs_curr_sensor_drivers_s { + int (*get_main_board_curr_number)(void); + ssize_t (*get_main_board_curr_alias)(unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_main_board_curr_type)(unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_main_board_curr_max)(unsigned int curr_index, char *buf, size_t count); + int (*set_main_board_curr_max)(unsigned int curr_index, const char *buf, size_t count); + ssize_t (*get_main_board_curr_min)(unsigned int curr_index, char *buf, size_t count); + int (*set_main_board_curr_min)(unsigned int curr_index, const char *buf, size_t count); + ssize_t (*get_main_board_curr_value)(unsigned int curr_index, char *buf, size_t count); +}; + +extern int s3ip_sysfs_curr_sensor_drivers_register(struct s3ip_sysfs_curr_sensor_drivers_s *drv); +extern void s3ip_sysfs_curr_sensor_drivers_unregister(void); +#endif /*_CURR_SENSOR_SYSFS_H_ */ diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/include/fan_sysfs.h b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/fan_sysfs.h new file mode 100755 index 000000000000..fbd5ea82eca0 --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/fan_sysfs.h @@ -0,0 +1,26 @@ +#ifndef _FAN_SYSFS_H_ +#define _FAN_SYSFS_H_ + +struct s3ip_sysfs_fan_drivers_s { + int (*get_fan_number)(void); + int (*get_fan_motor_number)(unsigned int fan_index); + ssize_t (*get_fan_model_name)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_serial_number)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_part_number)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_hardware_version)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_status)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_led_status)(unsigned int fan_index, char *buf, size_t count); + int (*set_fan_led_status)(unsigned int fan_index, int status); + ssize_t (*get_fan_direction)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_motor_speed)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_motor_speed_tolerance)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_motor_speed_target)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_motor_speed_max)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_motor_speed_min)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_ratio)(unsigned int fan_index, char *buf, size_t count); + int (*set_fan_ratio)(unsigned int fan_index, int ratio); +}; + +extern int s3ip_sysfs_fan_drivers_register(struct s3ip_sysfs_fan_drivers_s *drv); +extern void s3ip_sysfs_fan_drivers_unregister(void); +#endif /*_FAN_SYSFS_H_ */ diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/include/fpga_sysfs.h b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/fpga_sysfs.h new file mode 100644 index 000000000000..c8a6935e4638 --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/fpga_sysfs.h @@ -0,0 +1,16 @@ +#ifndef _FPGA_SYSFS_H_ +#define _FPGA_SYSFS_H_ + +struct s3ip_sysfs_fpga_drivers_s { + int (*get_main_board_fpga_number)(void); + ssize_t (*get_main_board_fpga_alias)(unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_main_board_fpga_type)(unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_main_board_fpga_firmware_version)(unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_main_board_fpga_board_version)(unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_main_board_fpga_test_reg)(unsigned int fpga_index, char *buf, size_t count); + int (*set_main_board_fpga_test_reg)(unsigned int fpga_index, unsigned int value); +}; + +extern int s3ip_sysfs_fpga_drivers_register(struct s3ip_sysfs_fpga_drivers_s *drv); +extern void s3ip_sysfs_fpga_drivers_unregister(void); +#endif /*_FPGA_SYSFS_H_ */ diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/include/psu_sysfs.h b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/psu_sysfs.h new file mode 100644 index 000000000000..4f6d1aba3d92 --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/psu_sysfs.h @@ -0,0 +1,38 @@ +#ifndef _PSU_SYSFS_H_ +#define _PSU_SYSFS_H_ + +struct s3ip_sysfs_psu_drivers_s { + int (*get_psu_number)(void); + int (*get_psu_temp_number)(unsigned int psu_index); + ssize_t (*get_psu_model_name)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_serial_number)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_part_number)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_hardware_version)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_type)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_in_curr)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_in_vol)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_in_power)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_out_curr)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_out_vol)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_out_power)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_out_max_power)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_present_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_in_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_out_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_fan_speed)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_fan_ratio)(unsigned int psu_index, char *buf, size_t count); + int (*set_psu_fan_ratio)(unsigned int psu_index, int ratio); + ssize_t (*get_psu_fan_direction)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_led_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_temp_alias)(unsigned int psu_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_psu_temp_type)(unsigned int psu_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_psu_temp_max)(unsigned int psu_index, unsigned int temp_index, char *buf, size_t count); + int (*set_psu_temp_max)(unsigned int psu_index, unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_psu_temp_min)(unsigned int psu_index, unsigned int temp_index, char *buf, size_t count); + int (*set_psu_temp_min)(unsigned int psu_index, unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_psu_temp_value)(unsigned int psu_index, unsigned int temp_index, char *buf, size_t count); +}; + +extern int s3ip_sysfs_psu_drivers_register(struct s3ip_sysfs_psu_drivers_s *drv); +extern void s3ip_sysfs_psu_drivers_unregister(void); +#endif /*_PSU_SYSFS_H_ */ diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/include/slot_sysfs.h b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/slot_sysfs.h new file mode 100644 index 000000000000..058ee450598b --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/slot_sysfs.h @@ -0,0 +1,57 @@ +#ifndef _SLOT_SYSFS_H_ +#define _SLOT_SYSFS_H_ + +struct s3ip_sysfs_slot_drivers_s { + int (*get_slot_number)(void); + int (*get_slot_temp_number)(unsigned int slot_index); + int (*get_slot_vol_number)(unsigned int slot_index); + int (*get_slot_curr_number)(unsigned int slot_index); + int (*get_slot_cpld_number)(unsigned int slot_index); + int (*get_slot_fpga_number)(unsigned int slot_index); + ssize_t (*get_slot_model_name)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_serial_number)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_part_number)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_hardware_version)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_status)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_led_status)(unsigned int slot_index, char *buf, size_t count); + int (*set_slot_led_status)(unsigned int slot_index, int status); + ssize_t (*get_slot_temp_alias)(unsigned int slot_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_slot_temp_type)(unsigned int slot_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_slot_temp_max)(unsigned int slot_index, unsigned int temp_index, char *buf, size_t count); + int (*set_slot_temp_max)(unsigned int slot_index, unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_slot_temp_min)(unsigned int slot_index, unsigned int temp_index, char *buf, size_t count); + int (*set_slot_temp_min)(unsigned int slot_index, unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_slot_temp_value)(unsigned int slot_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_slot_vol_alias)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_slot_vol_type)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_slot_vol_max)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + int (*set_slot_vol_max)(unsigned int slot_index, unsigned int vol_index, const char *buf, size_t count); + ssize_t (*get_slot_vol_min)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + int (*set_slot_vol_min)(unsigned int slot_index, unsigned int vol_index, const char *buf, size_t count); + ssize_t (*get_slot_vol_range)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_slot_vol_nominal_value)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_slot_vol_value)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_slot_curr_alias)(unsigned int slot_index, unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_slot_curr_type)(unsigned int slot_index, unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_slot_curr_max)(unsigned int slot_index, unsigned int curr_index, char *buf, size_t count); + int (*set_slot_curr_max)(unsigned int slot_index, unsigned int curr_index, const char *buf, size_t count); + ssize_t (*get_slot_curr_min)(unsigned int slot_index, unsigned int curr_index, char *buf, size_t count); + int (*set_slot_curr_min)(unsigned int slot_index, unsigned int curr_index, const char *buf, size_t count); + ssize_t (*get_slot_curr_value)(unsigned int slot_index, unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_slot_fpga_alias)(unsigned int slot_index, unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_slot_fpga_type)(unsigned int slot_index, unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_slot_fpga_firmware_version)(unsigned int slot_index, unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_slot_fpga_board_version)(unsigned int slot_index, unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_slot_fpga_test_reg)(unsigned int slot_index, unsigned int fpga_index, char *buf, size_t count); + int (*set_slot_fpga_test_reg)(unsigned int slot_index, unsigned int fpga_index, unsigned int value); + ssize_t (*get_slot_cpld_alias)(unsigned int slot_index, unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_slot_cpld_type)(unsigned int slot_index, unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_slot_cpld_firmware_version)(unsigned int slot_index, unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_slot_cpld_board_version)(unsigned int slot_index, unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_slot_cpld_test_reg)(unsigned int slot_index, unsigned int cpld_index, char *buf, size_t count); + int (*set_slot_cpld_test_reg)(unsigned int slot_index, unsigned int cpld_index, unsigned int value); +}; + +extern int s3ip_sysfs_slot_drivers_register(struct s3ip_sysfs_slot_drivers_s *drv); +extern void s3ip_sysfs_slot_drivers_unregister(void); +#endif /*_SLOT_SYSFS_H_ */ diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/include/switch.h b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/switch.h new file mode 100644 index 000000000000..ea0b1a266b1f --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/switch.h @@ -0,0 +1,68 @@ +#ifndef _SWITCH_H_ +#define _SWITCH_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DIR_NAME_MAX_LEN (64) +#define SYSFS_DEV_ERROR "NA" + +enum LOG_LEVEL{ + INFO = 0x1, + ERR = 0x2, + DBG = 0x4, + ALL = 0xf +}; + +extern int g_switch_loglevel; + +#define check_pfun(p) do { \ + if (p == NULL) { \ + if (g_switch_loglevel & ERR) { \ + printk( KERN_ERR "%s, %s is NULL.\n", __FUNCTION__, #p); \ + } \ + return -ENOSYS; \ + } \ +} while(0) + +#define check_p(p) check_pfun(p) + +#define to_switch_obj(x) container_of(x, struct switch_obj, kobj) +#define to_switch_attr(x) container_of(x, struct switch_attribute, attr) +#define to_switch_device_attr(x) container_of(x, struct switch_device_attribute, switch_attr) + +#define SWITCH_ATTR(_name, _mode, _show, _store, _type) \ + { .switch_attr = __ATTR(_name, _mode, _show, _store), \ + .type = _type } + +#define SWITCH_DEVICE_ATTR(_name, _mode, _show, _store, _type) \ +struct switch_device_attribute switch_dev_attr_##_name \ + = SWITCH_ATTR(_name, _mode, _show, _store, _type) + +struct switch_obj { + struct kobject kobj; + unsigned int index; +}; + +/* a custom attribute that works just for a struct switch_obj. */ +struct switch_attribute { + struct attribute attr; + ssize_t (*show)(struct switch_obj *foo, struct switch_attribute *attr, char *buf); + ssize_t (*store)(struct switch_obj *foo, struct switch_attribute *attr, const char *buf, size_t count); +}; + +struct switch_device_attribute { + struct switch_attribute switch_attr; + int type; +}; + +struct switch_obj *switch_kobject_create(const char *name, struct kobject *parent); +void switch_kobject_delete(struct switch_obj **obj); + +#endif /* _SWITCH_H_ */ diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/include/syseeprom_sysfs.h b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/syseeprom_sysfs.h new file mode 100644 index 000000000000..c6b2c5c3456f --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/syseeprom_sysfs.h @@ -0,0 +1,12 @@ +#ifndef _SYSEEPROM_SYSFS_H_ +#define _SYSEEPROM_SYSFS_H_ + +struct s3ip_sysfs_syseeprom_drivers_s { + int (*get_syseeprom_size)(void); + ssize_t (*read_syseeprom_data)(char *buf, loff_t offset, size_t count); + ssize_t (*write_syseeprom_data)(char *buf, loff_t offset, size_t count); +}; + +extern int s3ip_sysfs_syseeprom_drivers_register(struct s3ip_sysfs_syseeprom_drivers_s *drv); +extern void s3ip_sysfs_syseeprom_drivers_unregister(void); +#endif /*_SYSEEPROM_SYSFS_H_ */ diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/include/sysled_sysfs.h b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/sysled_sysfs.h new file mode 100644 index 000000000000..e4383a4eea27 --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/sysled_sysfs.h @@ -0,0 +1,19 @@ +#ifndef _SYSLED_SYSFS_H_ +#define _SYSLED_SYSFS_H_ + +struct s3ip_sysfs_sysled_drivers_s { + ssize_t (*get_sys_led_status)(char *buf, size_t count); + int (*set_sys_led_status)(int status); + ssize_t (*get_bmc_led_status)(char *buf, size_t count); + int (*set_bmc_led_status)(int status); + ssize_t (*get_sys_fan_led_status)(char *buf, size_t count); + int (*set_sys_fan_led_status)(int status); + ssize_t (*get_sys_psu_led_status)(char *buf, size_t count); + int (*set_sys_psu_led_status)(int status); + ssize_t (*get_id_led_status)(char *buf, size_t count); + int (*set_id_led_status)(int status); +}; + +extern int s3ip_sysfs_sysled_drivers_register(struct s3ip_sysfs_sysled_drivers_s *drv); +extern void s3ip_sysfs_sysled_drivers_unregister(void); +#endif /*_SYSLED_SYSFS_H_ */ diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/include/temp_sensor_sysfs.h b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/temp_sensor_sysfs.h new file mode 100644 index 000000000000..db03a96a0cba --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/temp_sensor_sysfs.h @@ -0,0 +1,17 @@ +#ifndef _TEMP_SENSOR_SYSFS_H_ +#define _TEMP_SENSOR_SYSFS_H_ + +struct s3ip_sysfs_temp_sensor_drivers_s { + int (*get_main_board_temp_number)(void); + ssize_t (*get_main_board_temp_alias)(unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_main_board_temp_type)(unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_main_board_temp_max)(unsigned int temp_index, char *buf, size_t count); + int (*set_main_board_temp_max)(unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_main_board_temp_min)(unsigned int temp_index, char *buf, size_t count); + int (*set_main_board_temp_min)(unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_main_board_temp_value)(unsigned int temp_index, char *buf, size_t count); +}; + +extern int s3ip_sysfs_temp_sensor_drivers_register(struct s3ip_sysfs_temp_sensor_drivers_s *drv); +extern void s3ip_sysfs_temp_sensor_drivers_unregister(void); +#endif /*_TEMP_SENSOR_SYSFS_H_ */ diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/include/transceiver_sysfs.h b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/transceiver_sysfs.h new file mode 100644 index 000000000000..7e8634c1ef01 --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/transceiver_sysfs.h @@ -0,0 +1,26 @@ +#ifndef _TRANSCEIVER_SYSFS_H_ +#define _TRANSCEIVER_SYSFS_H_ + +struct s3ip_sysfs_transceiver_drivers_s { + int (*get_eth_number)(void); + ssize_t (*get_transceiver_power_on_status)(char *buf, size_t count); + int (*set_transceiver_power_on_status)(int status); + ssize_t (*get_eth_power_on_status)(unsigned int eth_index, char *buf, size_t count); + int (*set_eth_power_on_status)(unsigned int eth_index, int status); + ssize_t (*get_eth_tx_fault_status)(unsigned int eth_index, char *buf, size_t count); + ssize_t (*get_eth_tx_disable_status)(unsigned int eth_index, char *buf, size_t count); + int (*set_eth_tx_disable_status)(unsigned int eth_index, int status); + ssize_t (*get_eth_present_status)(unsigned int eth_index, char *buf, size_t count); + ssize_t (*get_eth_rx_los_status)(unsigned int eth_index, char *buf, size_t count); + ssize_t (*get_eth_reset_status)(unsigned int eth_index, char *buf, size_t count); + int (*set_eth_reset_status)(unsigned int eth_index, int status); + ssize_t (*get_eth_low_power_mode_status)(unsigned int eth_index, char *buf, size_t count); + ssize_t (*get_eth_interrupt_status)(unsigned int eth_index, char *buf, size_t count); + int (*get_eth_eeprom_size)(unsigned int eth_index); + ssize_t (*read_eth_eeprom_data)(unsigned int eth_index, char *buf, loff_t offset, size_t count); + ssize_t (*write_eth_eeprom_data)(unsigned int eth_index, char *buf, loff_t offset, size_t count); +}; + +extern int s3ip_sysfs_sff_drivers_register(struct s3ip_sysfs_transceiver_drivers_s *drv); +extern void s3ip_sysfs_sff_drivers_unregister(void); +#endif /*_TRANSCEIVER_SYSFS_H_ */ diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/include/vol_sensor_sysfs.h b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/vol_sensor_sysfs.h new file mode 100644 index 000000000000..b2d7d615c421 --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/vol_sensor_sysfs.h @@ -0,0 +1,19 @@ +#ifndef _VOL_SENSOR_SYSFS_H_ +#define _VOL_SENSOR_SYSFS_H_ + +struct s3ip_sysfs_vol_sensor_drivers_s { + int (*get_main_board_vol_number)(void); + ssize_t (*get_main_board_vol_alias)(unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_main_board_vol_type)(unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_main_board_vol_max)(unsigned int vol_index, char *buf, size_t count); + int (*set_main_board_vol_max)(unsigned int vol_index, const char *buf, size_t count); + ssize_t (*get_main_board_vol_min)(unsigned int vol_index, char *buf, size_t count); + int (*set_main_board_vol_min)(unsigned int vol_index, const char *buf, size_t count); + ssize_t (*get_main_board_vol_range)(unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_main_board_vol_nominal_value)(unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_main_board_vol_value)(unsigned int vol_index, char *buf, size_t count); +}; + +extern int s3ip_sysfs_vol_sensor_drivers_register(struct s3ip_sysfs_vol_sensor_drivers_s *drv); +extern void s3ip_sysfs_vol_sensor_drivers_unregister(void); +#endif /*_VOL_SENSOR_SYSFS_H_ */ diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/include/watchdog_sysfs.h b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/watchdog_sysfs.h new file mode 100755 index 000000000000..7e86e4c006d9 --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/include/watchdog_sysfs.h @@ -0,0 +1,16 @@ +#ifndef _WATCHDOG_SYSFS_H_ +#define _WATCHDOG_SYSFS_H_ + +struct s3ip_sysfs_watchdog_drivers_s { + ssize_t (*get_watchdog_identify)(char *buf, size_t count); + ssize_t (*get_watchdog_timeleft)(char *buf, size_t count); + ssize_t (*get_watchdog_timeout)(char *buf, size_t count); + int (*set_watchdog_timeout)(int value); + ssize_t (*get_watchdog_enable_status)(char *buf, size_t count); + int (*set_watchdog_enable_status)(int value); + int (*set_watchdog_reset)(int value); +}; + +extern int s3ip_sysfs_watchdog_drivers_register(struct s3ip_sysfs_watchdog_drivers_s *drv); +extern void s3ip_sysfs_watchdog_drivers_unregister(void); +#endif /*_WATCHDOG_SYSFS_H_ */ diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/psu_sysfs.c b/platform/s3ip-sysfs/s3ip_sysfs_frame/psu_sysfs.c new file mode 100755 index 000000000000..50005f875345 --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/psu_sysfs.c @@ -0,0 +1,990 @@ +/* + * psu_sysfs.c + * + * This module create psu kobjects and attributes in /sys/s3ip/psu + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-08-31 S3IP sysfs + */ + +#include + +#include "switch.h" +#include "psu_sysfs.h" + +static int g_psu_loglevel = 0; + +#define PSU_INFO(fmt, args...) do { \ + if (g_psu_loglevel & INFO) { \ + printk(KERN_INFO "[PSU_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define PSU_ERR(fmt, args...) do { \ + if (g_psu_loglevel & ERR) { \ + printk(KERN_ERR "[PSU_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define PSU_DBG(fmt, args...) do { \ + if (g_psu_loglevel & DBG) { \ + printk(KERN_DEBUG "[PSU_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct temp_obj_s { + struct switch_obj *obj; +}; + +struct psu_obj_s { + unsigned int temp_number; + struct temp_obj_s *temp; + struct switch_obj *obj; +}; + +struct psu_s{ + unsigned int psu_number; + struct psu_obj_s *psu; +}; + +static struct psu_s g_psu; +static struct switch_obj *g_psu_obj = NULL; +static struct s3ip_sysfs_psu_drivers_s *g_psu_drv = NULL; + +static ssize_t psu_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_psu.psu_number); +} + +static ssize_t psu_temp_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int index; + + index = obj->index; + PSU_DBG("psu index: %u\n",index); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_psu.psu[index - 1].temp_number); +} + +static ssize_t psu_model_name_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int psu_index; + int ret; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_model_name); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + ret = g_psu_drv->get_psu_model_name(psu_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u model name failed, ret: %d\n", psu_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t psu_hw_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + int ret; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_hardware_version); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + ret = g_psu_drv->get_psu_hardware_version(psu_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u hardware version failed, ret: %d\n", psu_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t psu_sn_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int psu_index; + int ret; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_serial_number); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + ret = g_psu_drv->get_psu_serial_number(psu_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u serial number failed, ret: %d\n", psu_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t psu_pn_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + int ret; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_part_number); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + ret = g_psu_drv->get_psu_part_number(psu_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u part number failed, ret: %d\n", psu_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t psu_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + int ret; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_type); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + ret = g_psu_drv->get_psu_type(psu_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u type failed, ret: %d\n", psu_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t psu_in_curr_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + int ret; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_in_curr); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + ret = g_psu_drv->get_psu_in_curr(psu_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u input current failed, ret: %d\n", psu_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t psu_in_vol_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + int ret; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_in_vol); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + ret = g_psu_drv->get_psu_in_vol(psu_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u input voltage failed, ret: %d\n", psu_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t psu_in_power_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + int ret; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_in_power); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + ret = g_psu_drv->get_psu_in_power(psu_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u input power failed, ret: %d\n", psu_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t psu_out_curr_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + int ret; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_out_curr); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + ret = g_psu_drv->get_psu_out_curr(psu_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u output current failed, ret: %d\n", psu_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t psu_out_vol_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + int ret; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_out_vol); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + ret = g_psu_drv->get_psu_out_vol(psu_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u output voltage failed, ret: %d\n", psu_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t psu_out_power_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + int ret; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_out_power); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + ret = g_psu_drv->get_psu_out_power(psu_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u outout power failed, ret: %d\n", psu_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t psu_out_max_power_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + int ret; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_out_max_power); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + ret = g_psu_drv->get_psu_out_max_power(psu_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u outout max power failed, ret: %d\n", psu_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t psu_present_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + int ret; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_present_status); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + ret = g_psu_drv->get_psu_present_status(psu_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u present status failed, ret: %d\n", psu_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t psu_out_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + int ret; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_out_status); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + ret = g_psu_drv->get_psu_out_status(psu_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u outout status failed, ret: %d\n", psu_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t psu_in_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + int ret; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_in_status); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + ret = g_psu_drv->get_psu_in_status(psu_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u input status failed, ret: %d\n", psu_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t psu_fan_speed_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + int ret; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_fan_speed); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + ret = g_psu_drv->get_psu_fan_speed(psu_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u fan speed failed, ret: %d\n", psu_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +ssize_t psu_fan_ratio_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + int ret; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_fan_ratio); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + ret = g_psu_drv->get_psu_fan_ratio(psu_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u fan ratio failed, ret: %d\n", psu_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t psu_fan_ratio_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int psu_index; + int ret, ratio; + + check_p(g_psu_drv); + check_p(g_psu_drv->set_psu_fan_ratio); + + psu_index = obj->index; + sscanf(buf, "%d", &ratio); + if (ratio < 0 || ratio > 100) { + PSU_ERR("param invalid, can not set ratio: %d.\n", ratio); + return -EINVAL; + } + PSU_DBG("psu index: %u, ratio: %d\n", psu_index, ratio); + ret = g_psu_drv->set_psu_fan_ratio(psu_index, ratio); + if (ret < 0) { + PSU_ERR("set psu%u ratio: %d failed, ret: %d\n", + psu_index, ratio, ret); + return -EIO; + } + PSU_DBG("set psu%u, ratio: %d success\n", psu_index, ratio); + return count; +} + +static ssize_t psu_fan_direction_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + int ret; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_fan_direction); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + ret = g_psu_drv->get_psu_fan_direction(psu_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u fan direction failed, ret: %d\n", psu_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t psu_led_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + int ret; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_led_status); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + ret = g_psu_drv->get_psu_led_status(psu_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u led status failed, ret: %d\n", psu_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t psu_temp_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index, temp_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_temp_value); + + p_obj = to_switch_obj(obj->kobj.parent); + psu_index = p_obj->index; + temp_index = obj->index; + + PSU_DBG("psu index: %u, temp index: %u\n", psu_index, temp_index); + ret = g_psu_drv->get_psu_temp_value(psu_index, temp_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u temp%u value failed, ret: %d\n", psu_index, temp_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t psu_temp_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index, temp_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_temp_alias); + + p_obj = to_switch_obj(obj->kobj.parent); + psu_index = p_obj->index; + temp_index = obj->index; + + PSU_DBG("psu index: %u, temp index: %u\n", psu_index, temp_index); + ret = g_psu_drv->get_psu_temp_alias(psu_index, temp_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u temp%u alias failed, ret: %d\n", psu_index, temp_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t psu_temp_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index, temp_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_temp_type); + + p_obj = to_switch_obj(obj->kobj.parent); + psu_index = p_obj->index; + temp_index = obj->index; + + PSU_DBG("psu index: %u, temp index: %u\n", psu_index, temp_index); + ret = g_psu_drv->get_psu_temp_type(psu_index, temp_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u temp%u type failed, ret: %d\n", psu_index, temp_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t psu_temp_max_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index, temp_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_temp_max); + + p_obj = to_switch_obj(obj->kobj.parent); + psu_index = p_obj->index; + temp_index = obj->index; + + PSU_DBG("psu index: %u, temp index: %u\n", psu_index, temp_index); + ret = g_psu_drv->get_psu_temp_max(psu_index, temp_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u temp%u max threshold failed, ret: %d\n", + psu_index, temp_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t psu_temp_max_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int psu_index, temp_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_psu_drv); + check_p(g_psu_drv->set_psu_temp_max); + + p_obj = to_switch_obj(obj->kobj.parent); + psu_index = p_obj->index; + temp_index = obj->index; + ret = g_psu_drv->set_psu_temp_max(psu_index, temp_index, buf, count); + if (ret < 0) { + PSU_ERR("set psu%u temp%u max threshold failed, value: %s, count: %lu, ret: %d\n", + psu_index, temp_index, buf, count, ret); + return -EIO; + } + PSU_DBG("set psu%u temp%u max threshold success, value: %s, count: %lu, ret: %d\n", + psu_index, temp_index, buf, count, ret); + return count; +} + +static ssize_t psu_temp_min_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index, temp_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_temp_min); + + p_obj = to_switch_obj(obj->kobj.parent); + psu_index = p_obj->index; + temp_index = obj->index; + + PSU_DBG("psu index: %u, temp index: %u\n", psu_index, temp_index); + ret = g_psu_drv->get_psu_temp_min(psu_index, temp_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u temp%u min threshold failed, ret: %d\n", + psu_index, temp_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t psu_temp_min_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int psu_index, temp_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_psu_drv); + check_p(g_psu_drv->set_psu_temp_min); + + p_obj = to_switch_obj(obj->kobj.parent); + psu_index = p_obj->index; + temp_index = obj->index; + ret = g_psu_drv->set_psu_temp_min(psu_index, temp_index, buf, count); + if (ret < 0) { + PSU_ERR("set psu%u temp%u min threshold failed, value: %s, count: %lu, ret: %d\n", + psu_index, temp_index, buf, count, ret); + return -EIO; + } + PSU_DBG("set psu%u temp%u min threshold success, value: %s, count: %lu, ret: %d\n", + psu_index, temp_index, buf, count, ret); + return count; +} + +/************************************psu dir and attrs*******************************************/ +static struct switch_attribute psu_number_att = __ATTR(number, S_IRUGO, psu_number_show, NULL); + +static struct attribute *psu_dir_attrs[] = { + &psu_number_att.attr, + NULL, +}; + +static struct attribute_group psu_root_attr_group = { + .attrs = psu_dir_attrs, +}; + +/*******************************psu[1-n] dir and attrs*******************************************/ +static struct switch_attribute psu_model_name_attr = __ATTR(model_name, S_IRUGO, psu_model_name_show, NULL); +static struct switch_attribute psu_hw_attr = __ATTR(hardware_version, S_IRUGO, psu_hw_show, NULL); +static struct switch_attribute psu_sn_attr = __ATTR(serial_number, S_IRUGO, psu_sn_show, NULL); +static struct switch_attribute psu_pn_attr = __ATTR(part_number, S_IRUGO, psu_pn_show, NULL); +static struct switch_attribute psu_type_attr = __ATTR(type, S_IRUGO, psu_type_show, NULL); +static struct switch_attribute psu_in_curr_attr = __ATTR(in_curr, S_IRUGO, psu_in_curr_show, NULL); +static struct switch_attribute psu_in_vol_attr = __ATTR(in_vol, S_IRUGO, psu_in_vol_show, NULL); +static struct switch_attribute psu_in_power_attr = __ATTR(in_power, S_IRUGO, psu_in_power_show, NULL); +static struct switch_attribute psu_out_curr_attr = __ATTR(out_curr, S_IRUGO, psu_out_curr_show, NULL); +static struct switch_attribute psu_out_vol_attr = __ATTR(out_vol, S_IRUGO, psu_out_vol_show, NULL); +static struct switch_attribute psu_out_power_attr = __ATTR(out_power, S_IRUGO, psu_out_power_show, NULL); +static struct switch_attribute psu_out_max_power_attr = __ATTR(out_max_power, S_IRUGO, psu_out_max_power_show, NULL); +static struct switch_attribute psu_num_temps_attr = __ATTR(num_temp_sensors, S_IRUGO, psu_temp_number_show, NULL); +static struct switch_attribute psu_present_attr = __ATTR(present, S_IRUGO, psu_present_status_show, NULL); +static struct switch_attribute psu_out_status_attr = __ATTR(out_status, S_IRUGO, psu_out_status_show, NULL); +static struct switch_attribute psu_in_status_attr = __ATTR(in_status, S_IRUGO, psu_in_status_show, NULL); +static struct switch_attribute psu_fan_speed_attr = __ATTR(fan_speed, S_IRUGO, psu_fan_speed_show, NULL); +static struct switch_attribute psu_fan_ratio_attr = __ATTR(fan_ratio, S_IRUGO | S_IWUSR, psu_fan_ratio_show, psu_fan_ratio_store); +static struct switch_attribute psu_fan_direction_attr = __ATTR(fan_direction, S_IRUGO, psu_fan_direction_show, NULL); +static struct switch_attribute psu_led_status_attr = __ATTR(led_status, S_IRUGO, psu_led_status_show, NULL); + +static struct attribute *psu_attrs[] = { + &psu_model_name_attr.attr, + &psu_hw_attr.attr, + &psu_sn_attr.attr, + &psu_pn_attr.attr, + &psu_type_attr.attr, + &psu_in_curr_attr.attr, + &psu_in_vol_attr.attr, + &psu_in_power_attr.attr, + &psu_out_curr_attr.attr, + &psu_out_vol_attr.attr, + &psu_out_power_attr.attr, + &psu_out_max_power_attr.attr, + &psu_num_temps_attr.attr, + &psu_present_attr.attr, + &psu_out_status_attr.attr, + &psu_in_status_attr.attr, + &psu_fan_speed_attr.attr, + &psu_fan_ratio_attr.attr, + &psu_fan_direction_attr.attr, + &psu_led_status_attr.attr, + NULL, +}; + +static struct attribute_group psu_attr_group = { + .attrs = psu_attrs, +}; + +/*******************************psu temp[1-n] dir and attrs*******************************************/ +static struct switch_attribute psu_temp_alias_attr = __ATTR(alias, S_IRUGO, psu_temp_alias_show, NULL); +static struct switch_attribute psu_temp_type_attr = __ATTR(type, S_IRUGO, psu_temp_type_show, NULL); +static struct switch_attribute psu_temp_max_attr = __ATTR(max, S_IRUGO | S_IWUSR, psu_temp_max_show, psu_temp_max_store); +static struct switch_attribute psu_temp_min_attr = __ATTR(min, S_IRUGO | S_IWUSR, psu_temp_min_show, psu_temp_min_store); +static struct switch_attribute psu_temp_value_attr = __ATTR(value, S_IRUGO, psu_temp_value_show, NULL); + +static struct attribute *psu_temp_attrs[] = { + &psu_temp_alias_attr.attr, + &psu_temp_type_attr.attr, + &psu_temp_max_attr.attr, + &psu_temp_min_attr.attr, + &psu_temp_value_attr.attr, + NULL, +}; + +static struct attribute_group psu_temp_attr_group = { + .attrs = psu_temp_attrs, +}; + +static void psuindex_single_temp_remove_kobj_and_attrs(struct psu_obj_s *curr_psu, unsigned int temp_index) +{ + struct temp_obj_s *curr_temp; /* point to temp1 temp2...*/ + + curr_temp = &curr_psu->temp[temp_index - 1]; + if (curr_temp->obj) { + sysfs_remove_group(&curr_temp->obj->kobj, &psu_temp_attr_group); + switch_kobject_delete(&curr_temp->obj); + PSU_DBG("delete psu%u temp%u dir and attrs success.\n", curr_psu->obj->index, temp_index); + } + return; +} + +static int psuindex_single_temp_create_kobj_and_attrs(struct psu_obj_s *curr_psu, unsigned int temp_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct temp_obj_s *curr_temp; /* point to temp1 temp2...*/ + + curr_temp = &curr_psu->temp[temp_index - 1]; + memset(name, 0, sizeof(name)); + snprintf(name, sizeof(name), "temp%u", temp_index); + curr_temp->obj = switch_kobject_create(name, &curr_psu->obj->kobj); + if (!curr_temp->obj) { + PSU_ERR("create psu%u, %s object error!\n", curr_psu->obj->index, name); + return -ENOMEM; + } + curr_temp->obj->index = temp_index; + if (sysfs_create_group(&curr_temp->obj->kobj, &psu_temp_attr_group) != 0) { + PSU_ERR("create psu%u, %s attrs error.\n", curr_psu->obj->index, name); + switch_kobject_delete(&curr_temp->obj); + return -EBADRQC; + } + PSU_DBG("create psu%u, %s success.\n", curr_psu->obj->index, name); + return 0; +} + +static int psuindex_temp_create_kobj_and_attrs(struct psu_obj_s *curr_psu) +{ + unsigned int temp_index, i, temp_num; + + temp_num = curr_psu->temp_number; + curr_psu->temp = kzalloc(sizeof(struct temp_obj_s) * temp_num, GFP_KERNEL); + if (!curr_psu->temp) { + PSU_ERR("kzalloc temp error, psu index: %u, temp number: %u.\n", + curr_psu->obj->index, temp_num); + return -ENOMEM; + } + for(temp_index = 1; temp_index <= temp_num; temp_index++) { + if(psuindex_single_temp_create_kobj_and_attrs(curr_psu, temp_index) != 0 ) { + goto temp_error; + } + } + return 0; +temp_error: + for(i = temp_index; i > 0; i--) { + psuindex_single_temp_remove_kobj_and_attrs(curr_psu, i); + } + kfree(curr_psu->temp); + curr_psu->temp = NULL; + return -EBADRQC; +} + +static void psuindex_temp_remove_kobj_and_attrs(struct psu_obj_s *curr_psu) +{ + unsigned int temp_index, temp_num; + + if (curr_psu->temp) { + temp_num = curr_psu->temp_number; + for (temp_index = temp_num; temp_index > 0; temp_index--) { + psuindex_single_temp_remove_kobj_and_attrs(curr_psu, temp_index); + } + kfree(curr_psu->temp); + curr_psu->temp = NULL; + } + return; +} + +/* create psu temp[1-n] directory and attributes*/ +static int psu_temp_create(void) +{ + int psu_num, temp_num; + unsigned int psu_index, i; + struct psu_obj_s *curr_psu; /* point to psu1 psu2...*/ + + psu_num = g_psu.psu_number; + if (psu_num <= 0) { + PSU_DBG("psu number: %d, skip to create temp* dirs and attrs.\n", psu_num); + return 0; + } + + check_p(g_psu_drv->get_psu_temp_number); + for(psu_index = 1; psu_index <= psu_num; psu_index++) { + temp_num = g_psu_drv->get_psu_temp_number(psu_index); + if (temp_num <= 0) { + PSU_DBG("psu%u temp number: %d, don't need to create temp* dirs and attrs.\n", + psu_index, temp_num); + continue; + } + curr_psu = &g_psu.psu[psu_index - 1]; + curr_psu->temp_number = temp_num; + if(psuindex_temp_create_kobj_and_attrs(curr_psu) != 0) { + goto error; + } + } + return 0; +error: + for(i = psu_index; i > 0; i--) { + curr_psu = &g_psu.psu[i - 1]; + psuindex_temp_remove_kobj_and_attrs(curr_psu); + } + return -EBADRQC; +} + +/* delete psu temp[1-n] directory and attributes*/ +static void psu_temp_remove(void) +{ + unsigned int psu_index; + struct psu_obj_s *curr_psu; + + if (g_psu.psu) { + for(psu_index = g_psu.psu_number; psu_index > 0; psu_index--) { + curr_psu = &g_psu.psu[psu_index - 1]; + psuindex_temp_remove_kobj_and_attrs(curr_psu); + curr_psu->temp_number = 0; + } + } + return; +} + +static int psu_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct psu_obj_s *curr_psu; + + curr_psu = &g_psu.psu[index - 1]; + if (curr_psu->obj) { + sysfs_remove_group(&curr_psu->obj->kobj, &psu_attr_group); + switch_kobject_delete(&curr_psu->obj); + PSU_DBG("delete psu%u dir and attrs success.\n", index); + } + return 0; +} + +static int psu_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[DIR_NAME_MAX_LEN]; + struct psu_obj_s *curr_psu; + + curr_psu = &g_psu.psu[index - 1]; + memset(name, 0, sizeof(name)); + snprintf(name, sizeof(name), "psu%u", index); + curr_psu->obj = switch_kobject_create(name, parent); + if (!curr_psu->obj) { + PSU_ERR("create %s object error!\n", name); + return -ENOMEM; + } + curr_psu->obj->index = index; + if (sysfs_create_group(&curr_psu->obj->kobj, &psu_attr_group) != 0) { + PSU_ERR("create %s attrs error.\n", name); + switch_kobject_delete(&curr_psu->obj); + return -EBADRQC; + } + PSU_DBG("create %s dir and attrs success.\n", name); + return 0; +} + +static int psu_sub_create_kobj_and_attrs(struct kobject *parent, int psu_num) +{ + unsigned int psu_index, i; + + g_psu.psu = kzalloc(sizeof(struct psu_obj_s) * psu_num, GFP_KERNEL); + if (!g_psu.psu) { + PSU_ERR("kzalloc psu.psu error, psu number = %d.\n", psu_num); + return -ENOMEM; + } + + for(psu_index = 1; psu_index <= psu_num; psu_index++) { + if(psu_sub_single_create_kobj_and_attrs(parent, psu_index) != 0 ) { + goto error; + } + } + return 0; +error: + for(i = psu_index; i > 0; i--) { + psu_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_psu.psu); + g_psu.psu = NULL; + return -EBADRQC; +} + +/* create psu[1-n] directory and attributes*/ +static int psu_sub_create(void) +{ + int ret; + + ret = psu_sub_create_kobj_and_attrs(&g_psu_obj->kobj, g_psu.psu_number); + return ret; +} + +/* delete psu[1-n] directory and attributes*/ +static void psu_sub_remove(void) +{ + unsigned int psu_index; + + if (g_psu.psu) { + for (psu_index = g_psu.psu_number; psu_index > 0; psu_index--) { + psu_sub_single_remove_kobj_and_attrs(psu_index); + } + kfree(g_psu.psu); + g_psu.psu = NULL; + } + g_psu.psu_number = 0; + return; +} + +/* create psu directory and number attributes*/ +static int psu_root_create(void) +{ + g_psu_obj = switch_kobject_create("psu", NULL); + if (!g_psu_obj) { + PSU_ERR("switch_kobject_create psu error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_psu_obj->kobj, &psu_root_attr_group) != 0) { + switch_kobject_delete(&g_psu_obj); + PSU_ERR("create psu dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete psu directory and number attributes*/ +static void psu_root_remove(void) +{ + if (g_psu_obj) { + sysfs_remove_group(&g_psu_obj->kobj, &psu_root_attr_group); + switch_kobject_delete(&g_psu_obj); + PSU_DBG("delete psu dir and attrs success.\n"); + } + return; +} + +int s3ip_sysfs_psu_drivers_register(struct s3ip_sysfs_psu_drivers_s *drv) +{ + int ret, psu_num; + + PSU_INFO("s3ip_sysfs_psu_drivers_register...\n"); + if (g_psu_drv) { + PSU_ERR("g_psu_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_psu_number); + g_psu_drv = drv; + + psu_num = g_psu_drv->get_psu_number(); + if (psu_num <= 0) { + PSU_ERR("psu number: %d, don't need to create psu dirs and attrs.\n", psu_num); + g_psu_drv = NULL; + return -EINVAL; + } + + memset(&g_psu, 0, sizeof(struct psu_s)); + g_psu.psu_number = psu_num; + ret = psu_root_create(); + if (ret < 0) { + PSU_ERR("create psu root dir and attrs failed, ret: %d\n", ret); + g_psu_drv = NULL; + return ret; + } + + ret = psu_sub_create(); + if (ret < 0) { + PSU_ERR("create psu sub dir and attrs failed, ret: %d\n", ret); + psu_root_remove(); + g_psu_drv = NULL; + return ret; + } + + ret = psu_temp_create(); + if (ret < 0) { + PSU_ERR("create psu temp dir and attrs failed, ret: %d\n", ret); + psu_sub_remove(); + psu_root_remove(); + g_psu_drv = NULL; + return ret; + } + PSU_INFO("s3ip_sysfs_psu_drivers_register success.\n"); + return 0; +} + +void s3ip_sysfs_psu_drivers_unregister(void) +{ + if (g_psu_drv) { + psu_temp_remove(); + psu_sub_remove(); + psu_root_remove(); + g_psu_drv = NULL; + PSU_DBG("s3ip_sysfs_psu_drivers_unregister success.\n"); + } + + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_psu_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_psu_drivers_unregister); +module_param(g_psu_loglevel, int, 0644); +MODULE_PARM_DESC(g_psu_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/slot_sysfs.c b/platform/s3ip-sysfs/s3ip_sysfs_frame/slot_sysfs.c new file mode 100644 index 000000000000..b0186ac6ad29 --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/slot_sysfs.c @@ -0,0 +1,2099 @@ +/* + * slot_sysfs.c + * + * This module create slot kobjects and attributes in /sys/s3ip/slot + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-08-31 S3IP sysfs + */ + +#include + +#include "switch.h" +#include "slot_sysfs.h" + +static int g_slot_loglevel = 0; + +#define SLOT_INFO(fmt, args...) do { \ + if (g_slot_loglevel & INFO) { \ + printk(KERN_INFO "[SLOT_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SLOT_ERR(fmt, args...) do { \ + if (g_slot_loglevel & ERR) { \ + printk(KERN_ERR "[SLOT_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SLOT_DBG(fmt, args...) do { \ + if (g_slot_loglevel & DBG) { \ + printk(KERN_DEBUG "[SLOT_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct slot_temp_obj_s { + struct switch_obj *obj; +}; + +struct slot_vol_obj_s { + struct switch_obj *obj; +}; + +struct slot_curr_obj_s { + struct switch_obj *obj; +}; + +struct slot_fpga_obj_s { + struct switch_obj *obj; +}; + +struct slot_cpld_obj_s { + struct switch_obj *obj; +}; + +struct slot_obj_s { + unsigned int temp_number; + unsigned int vol_number; + unsigned int curr_number; + unsigned int fpga_number; + unsigned int cpld_number; + struct slot_temp_obj_s *temp; + struct slot_vol_obj_s *vol; + struct slot_curr_obj_s *curr; + struct slot_fpga_obj_s *fpga; + struct slot_cpld_obj_s *cpld; + struct switch_obj *obj; +}; + +struct slot_s { + unsigned int slot_number; + struct slot_obj_s *slot; +}; + +static struct slot_s g_slot; +static struct switch_obj *g_slot_obj = NULL; +static struct s3ip_sysfs_slot_drivers_s *g_slot_drv = NULL; + +static ssize_t slot_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_slot.slot_number); +} + +static ssize_t slot_temp_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int index; + + index = obj->index; + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_slot.slot[index - 1].temp_number); +} + +static ssize_t slot_vol_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int index; + + index = obj->index; + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_slot.slot[index - 1].vol_number); +} + +static ssize_t slot_curr_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int index; + + index = obj->index; + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_slot.slot[index - 1].curr_number); +} + +static ssize_t slot_fpga_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int index; + + index = obj->index; + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_slot.slot[index - 1].fpga_number); +} + +static ssize_t slot_cpld_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int index; + + index = obj->index; + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_slot.slot[index - 1].cpld_number); +} + +static ssize_t slot_model_name_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index; + int ret; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_model_name); + + slot_index = obj->index; + SLOT_DBG("slot index: %u\n", slot_index); + ret = g_slot_drv->get_slot_model_name(slot_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u model name failed, ret: %d\n", slot_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_sn_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index; + int ret; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_serial_number); + + slot_index = obj->index; + SLOT_DBG("slot index: %u\n", slot_index); + ret = g_slot_drv->get_slot_serial_number(slot_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u serial number failed, ret: %d\n", slot_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_pn_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index; + int ret; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_part_number); + + slot_index = obj->index; + SLOT_DBG("slot index: %u\n", slot_index); + ret = g_slot_drv->get_slot_part_number(slot_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u part number failed, ret: %d\n", slot_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_hw_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index; + int ret; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_hardware_version); + + slot_index = obj->index; + SLOT_DBG("slot index: %u\n", slot_index); + ret = g_slot_drv->get_slot_hardware_version(slot_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u hardware version failed, ret: %d\n", slot_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index; + int ret; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_status); + + slot_index = obj->index; + SLOT_DBG("slot index: %u\n", slot_index); + ret = g_slot_drv->get_slot_status(slot_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u status failed, ret: %d\n", slot_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_led_status_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index; + int ret; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_led_status); + + slot_index = obj->index; + SLOT_DBG("slot index: %u\n", slot_index); + ret = g_slot_drv->get_slot_led_status(slot_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u led status failed, ret: %d\n", slot_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_led_status_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + unsigned int slot_index; + int ret, led_status; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_led_status); + + slot_index = obj->index; + sscanf(buf, "%d", &led_status); + SLOT_DBG("slot index: %u, led_status: %d\n", slot_index, led_status); + ret = g_slot_drv->set_slot_led_status(slot_index, led_status); + if (ret < 0) { + SLOT_ERR("set slot%u led_status: %d failed, ret: %d\n", slot_index, led_status, ret); + return -EIO; + } + SLOT_DBG("set slot%u led_status: %d success\n", slot_index, led_status); + return count; +} + +/*************************************slot temp*************************************************/ +static ssize_t slot_temp_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, temp_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_temp_value); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + temp_index = obj->index; + + SLOT_DBG("slot index: %u, temp index: %u\n", slot_index, temp_index); + ret = g_slot_drv->get_slot_temp_value(slot_index, temp_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u temp%u value failed, ret: %d\n", slot_index, temp_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_temp_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, temp_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_temp_alias); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + temp_index = obj->index; + + SLOT_DBG("slot index: %u, temp index: %u\n", slot_index, temp_index); + ret = g_slot_drv->get_slot_temp_alias(slot_index, temp_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u temp%u alias failed, ret: %d\n", slot_index, temp_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_temp_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, temp_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_temp_type); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + temp_index = obj->index; + + SLOT_DBG("slot index: %u, temp index: %u\n", slot_index, temp_index); + ret = g_slot_drv->get_slot_temp_type(slot_index, temp_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u temp%u type failed, ret: %d\n", slot_index, temp_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_temp_max_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, temp_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_temp_max); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + temp_index = obj->index; + + SLOT_DBG("slot index: %u, temp index: %u\n", slot_index, temp_index); + ret = g_slot_drv->get_slot_temp_max(slot_index, temp_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u temp%u max threshold failed, ret: %d\n", + slot_index, temp_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_temp_max_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int slot_index, temp_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_temp_max); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + temp_index = obj->index; + ret = g_slot_drv->set_slot_temp_max(slot_index, temp_index, buf, count); + if (ret < 0) { + SLOT_ERR("set slot%u temp%u max threshold failed, value: %s, count: %lu, ret: %d\n", + slot_index, temp_index, buf, count, ret); + return -EIO; + } + SLOT_DBG("set slot%u temp%u max threshold success, value: %s, count: %lu, ret: %d\n", + slot_index, temp_index, buf, count, ret); + return count; +} + +static ssize_t slot_temp_min_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, temp_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_temp_min); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + temp_index = obj->index; + + SLOT_DBG("slot index: %u, temp index: %u\n", slot_index, temp_index); + ret = g_slot_drv->get_slot_temp_min(slot_index, temp_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u temp%u min threshold failed, ret: %d\n", + slot_index, temp_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_temp_min_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int slot_index, temp_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_temp_min); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + temp_index = obj->index; + ret = g_slot_drv->set_slot_temp_min(slot_index, temp_index, buf, count); + if (ret < 0) { + SLOT_ERR("set slot%u temp%u min threshold failed, value: %s, count: %lu, ret: %d\n", + slot_index, temp_index, buf, count, ret); + return -EIO; + } + SLOT_DBG("set slot%u temp%u min threshold success, value: %s, count: %lu, ret: %d\n", + slot_index, temp_index, buf, count, ret); + return count; +} +/**********************************end of slot temp**********************************************/ + +/*************************************slot vol*************************************************/ +static ssize_t slot_vol_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, vol_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_vol_value); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + + SLOT_DBG("slot index: %u, vol index: %u\n", slot_index, vol_index); + ret = g_slot_drv->get_slot_vol_value(slot_index, vol_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u vol%u value failed, ret: %d\n", slot_index, vol_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_vol_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, vol_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_vol_alias); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + + SLOT_DBG("slot index: %u, vol index: %u\n", slot_index, vol_index); + ret = g_slot_drv->get_slot_vol_alias(slot_index, vol_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u vol%u alias failed, ret: %d\n", slot_index, vol_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_vol_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, vol_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_vol_type); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + + SLOT_DBG("slot index: %u, vol index: %u\n", slot_index, vol_index); + ret = g_slot_drv->get_slot_vol_type(slot_index, vol_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u vol%u type failed, ret: %d\n", slot_index, vol_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_vol_max_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, vol_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_vol_max); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + + SLOT_DBG("slot index: %u, vol index: %u\n", slot_index, vol_index); + ret = g_slot_drv->get_slot_vol_max(slot_index, vol_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u vol%u max threshold failed, ret: %d\n", + slot_index, vol_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_vol_max_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int slot_index, vol_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_vol_max); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + ret = g_slot_drv->set_slot_vol_max(slot_index, vol_index, buf, count); + if (ret < 0) { + SLOT_ERR("set slot%u vol%u max threshold failed, value: %s, count: %lu, ret: %d\n", + slot_index, vol_index, buf, count, ret); + return -EIO; + } + SLOT_DBG("set slot%u vol%u max threshold success, value: %s, count: %lu, ret: %d\n", + slot_index, vol_index, buf, count, ret); + return count; +} + +static ssize_t slot_vol_min_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, vol_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_vol_min); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + + SLOT_DBG("slot index: %u, vol index: %u\n", slot_index, vol_index); + ret = g_slot_drv->get_slot_vol_min(slot_index, vol_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u vol%u min threshold failed, ret: %d\n", + slot_index, vol_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_vol_min_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int slot_index, vol_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_vol_min); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + ret = g_slot_drv->set_slot_vol_min(slot_index, vol_index, buf, count); + if (ret < 0) { + SLOT_ERR("set slot%u vol%u min threshold failed, value: %s, count: %lu, ret: %d\n", + slot_index, vol_index, buf, count, ret); + return -EIO; + } + SLOT_DBG("set slot%u vol%u min threshold success, value: %s, count: %lu, ret: %d\n", + slot_index, vol_index, buf, count, ret); + return count; +} + +static ssize_t slot_vol_range_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, vol_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_vol_range); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + + SLOT_DBG("slot index: %u, vol index: %u\n", slot_index, vol_index); + ret = g_slot_drv->get_slot_vol_range(slot_index, vol_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u vol%u voltage range failed, ret: %d\n", + slot_index, vol_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_vol_nominal_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, vol_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_vol_nominal_value); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + + SLOT_DBG("slot index: %u, vol index: %u\n", slot_index, vol_index); + ret = g_slot_drv->get_slot_vol_nominal_value(slot_index, vol_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u vol%u voltage nominal value failed, ret: %d\n", + slot_index, vol_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} +/**********************************end of slot vol**********************************************/ +/*************************************slot curr*************************************************/ +static ssize_t slot_curr_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, curr_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_curr_value); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + curr_index = obj->index; + + SLOT_DBG("slot index: %u, curr index: %u\n", slot_index, curr_index); + ret = g_slot_drv->get_slot_curr_value(slot_index, curr_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u curr%u value failed, ret: %d\n", slot_index, curr_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_curr_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, curr_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_curr_alias); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + curr_index = obj->index; + + SLOT_DBG("slot index: %u, curr index: %u\n", slot_index, curr_index); + ret = g_slot_drv->get_slot_curr_alias(slot_index, curr_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u curr%u alias failed, ret: %d\n", slot_index, curr_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_curr_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, curr_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_curr_type); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + curr_index = obj->index; + + SLOT_DBG("slot index: %u, curr index: %u\n", slot_index, curr_index); + ret = g_slot_drv->get_slot_curr_type(slot_index, curr_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u curr%u type failed, ret: %d\n", slot_index, curr_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_curr_max_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, curr_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_curr_max); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + curr_index = obj->index; + + SLOT_DBG("slot index: %u, curr index: %u\n", slot_index, curr_index); + ret = g_slot_drv->get_slot_curr_max(slot_index, curr_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u curr%u max threshold failed, ret: %d\n", + slot_index, curr_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_curr_max_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int slot_index, curr_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_curr_max); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + curr_index = obj->index; + ret = g_slot_drv->set_slot_curr_max(slot_index, curr_index, buf, count); + if (ret < 0) { + SLOT_ERR("set slot%u curr%u max threshold failed, value: %s, count: %lu, ret: %d\n", + slot_index, curr_index, buf, count, ret); + return -EIO; + } + SLOT_DBG("set slot%u curr%u max threshold success, value: %s, count: %lu, ret: %d\n", + slot_index, curr_index, buf, count, ret); + return count; +} + +static ssize_t slot_curr_min_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, curr_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_curr_min); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + curr_index = obj->index; + + SLOT_DBG("slot index: %u, curr index: %u\n", slot_index, curr_index); + ret = g_slot_drv->get_slot_curr_min(slot_index, curr_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u curr%u min threshold failed, ret: %d\n", + slot_index, curr_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_curr_min_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int slot_index, curr_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_curr_min); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + curr_index = obj->index; + ret = g_slot_drv->set_slot_curr_min(slot_index, curr_index, buf, count); + if (ret < 0) { + SLOT_ERR("set slot%u curr%u min threshold failed, value: %s, count: %lu, ret: %d\n", + slot_index, curr_index, buf, count, ret); + return -EIO; + } + SLOT_DBG("set slot%u curr%u min threshold success, value: %s, count: %lu, ret: %d\n", + slot_index, curr_index, buf, count, ret); + return count; +} +/**********************************end of slot curr**********************************************/ +/*************************************slot fpga*************************************************/ +static ssize_t slot_fpga_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, fpga_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_fpga_alias); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + fpga_index = obj->index; + + SLOT_DBG("slot index: %u, fpga index: %u\n", slot_index, fpga_index); + ret = g_slot_drv->get_slot_fpga_alias(slot_index, fpga_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u fpga%u alias failed, ret: %d\n", slot_index, fpga_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_fpga_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, fpga_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_fpga_type); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + fpga_index = obj->index; + + SLOT_DBG("slot index: %u, fpga index: %u\n", slot_index, fpga_index); + ret = g_slot_drv->get_slot_fpga_type(slot_index, fpga_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u fpga%u type failed, ret: %d\n", slot_index, fpga_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_fpga_fw_version_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index, fpga_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_fpga_firmware_version); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + fpga_index = obj->index; + + SLOT_DBG("slot index: %u, fpga index: %u\n", slot_index, fpga_index); + ret = g_slot_drv->get_slot_fpga_firmware_version(slot_index, fpga_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u fpga%u firmware version failed, ret: %d\n", slot_index, fpga_index, + ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_fpga_board_version_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index, fpga_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_fpga_board_version); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + fpga_index = obj->index; + + SLOT_DBG("slot index: %u, fpga index: %u\n", slot_index, fpga_index); + ret = g_slot_drv->get_slot_fpga_board_version(slot_index, fpga_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u fpga%u board version failed, ret: %d\n", slot_index, fpga_index, + ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_fpga_test_reg_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index, fpga_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_fpga_test_reg); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + fpga_index = obj->index; + + SLOT_DBG("slot index: %u, fpga index: %u\n", slot_index, fpga_index); + ret = g_slot_drv->get_slot_fpga_test_reg(slot_index, fpga_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u fpga%u test register failed, ret: %d\n", slot_index, fpga_index, + ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_fpga_test_reg_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int slot_index, fpga_index, value; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_fpga_test_reg); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + fpga_index = obj->index; + sscanf(buf, "0x%x", &value); + ret = g_slot_drv->set_slot_fpga_test_reg(slot_index, fpga_index, value); + if (ret < 0) { + SLOT_ERR("set slot%u fpga%u test reg failed, value:0x%x, ret: %d.\n", + slot_index, fpga_index, value, ret); + return -EIO; + } + SLOT_DBG("set slot%u fpga%u test reg success, value: 0x%x.\n", slot_index, fpga_index, value); + return count; +} +/**********************************end of slot fpga**********************************************/ +/*************************************slot cpld*************************************************/ +static ssize_t slot_cpld_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, cpld_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_cpld_alias); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + cpld_index = obj->index; + + SLOT_DBG("slot index: %u, cpld index: %u\n", slot_index, cpld_index); + ret = g_slot_drv->get_slot_cpld_alias(slot_index, cpld_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u cpld%u alias failed, ret: %d\n", slot_index, cpld_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_cpld_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, cpld_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_cpld_type); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + cpld_index = obj->index; + + SLOT_DBG("slot index: %u, cpld index: %u\n", slot_index, cpld_index); + ret = g_slot_drv->get_slot_cpld_type(slot_index, cpld_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u cpld%u type failed, ret: %d\n", slot_index, cpld_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_cpld_fw_version_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index, cpld_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_cpld_firmware_version); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + cpld_index = obj->index; + + SLOT_DBG("slot index: %u, cpld index: %u\n", slot_index, cpld_index); + ret = g_slot_drv->get_slot_cpld_firmware_version(slot_index, cpld_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u cpld%u firmware version failed, ret: %d\n", slot_index, cpld_index, + ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_cpld_board_version_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index, cpld_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_cpld_board_version); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + cpld_index = obj->index; + + SLOT_DBG("slot index: %u, cpld index: %u\n", slot_index, cpld_index); + ret = g_slot_drv->get_slot_cpld_board_version(slot_index, cpld_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u cpld%u board version failed, ret: %d\n", slot_index, cpld_index, + ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_cpld_test_reg_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index, cpld_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_cpld_test_reg); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + cpld_index = obj->index; + + SLOT_DBG("slot index: %u, cpld index: %u\n", slot_index, cpld_index); + ret = g_slot_drv->get_slot_cpld_test_reg(slot_index, cpld_index, buf, PAGE_SIZE); + if (ret < 0) { + SLOT_ERR("get slot%u cpld%u test register failed, ret: %d\n", slot_index, cpld_index, + ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t slot_cpld_test_reg_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int slot_index, cpld_index, value; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_cpld_test_reg); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + cpld_index = obj->index; + sscanf(buf, "0x%x", &value); + ret = g_slot_drv->set_slot_cpld_test_reg(slot_index, cpld_index, value); + if (ret < 0) { + SLOT_ERR("set slot%u cpld%u test reg failed, value:0x%x, ret: %d.\n", + slot_index, cpld_index, value, ret); + return -EIO; + } + SLOT_DBG("set slot%u cpld%u test reg success, value: 0x%x.\n", slot_index, cpld_index, value); + return count; +} +/**********************************end of slot cpld**********************************************/ +/**********************************slot dir and attrs********************************************/ +static struct switch_attribute slot_number_attr = __ATTR(number, S_IRUGO, slot_number_show, NULL); + +static struct attribute *slot_dir_attrs[] = { + &slot_number_attr.attr, + NULL, +}; + +static struct attribute_group slot_root_attr_group = { + .attrs = slot_dir_attrs, +}; + +/*******************************slot[1-n] dir and attrs*******************************************/ +static struct switch_attribute slot_model_name_attr = __ATTR(model_name, S_IRUGO, slot_model_name_show, NULL); +static struct switch_attribute slot_hw_attr = __ATTR(hardware_version, S_IRUGO, slot_hw_show, NULL); +static struct switch_attribute slot_sn_attr = __ATTR(serial_number, S_IRUGO, slot_sn_show, NULL); +static struct switch_attribute slot_pn_attr = __ATTR(part_number, S_IRUGO, slot_pn_show, NULL); +static struct switch_attribute slot_status_attr = __ATTR(status, S_IRUGO, slot_status_show, NULL); +static struct switch_attribute slot_led_status_attr = __ATTR(led_status, S_IRUGO | S_IWUSR, slot_led_status_show, slot_led_status_store); +static struct switch_attribute num_temp_sensors_attr = __ATTR(num_temp_sensors, S_IRUGO, slot_temp_number_show, NULL); +static struct switch_attribute num_vol_sensors_attr = __ATTR(num_vol_sensors, S_IRUGO, slot_vol_number_show, NULL); +static struct switch_attribute num_curr_sensors_attr = __ATTR(num_curr_sensors, S_IRUGO, slot_curr_number_show, NULL); +static struct switch_attribute num_fpga_attr = __ATTR(num_fpgas, S_IRUGO, slot_fpga_number_show, NULL); +static struct switch_attribute num_cpld_attr = __ATTR(num_cplds, S_IRUGO, slot_cpld_number_show, NULL); + +static struct attribute *slot_attrs[] = { + &slot_model_name_attr.attr, + &slot_hw_attr.attr, + &slot_sn_attr.attr, + &slot_pn_attr.attr, + &slot_status_attr.attr, + &slot_led_status_attr.attr, + &num_temp_sensors_attr.attr, + &num_vol_sensors_attr.attr, + &num_curr_sensors_attr.attr, + &num_fpga_attr.attr, + &num_cpld_attr.attr, + NULL, +}; + +static struct attribute_group slot_attr_group = { + .attrs = slot_attrs, +}; + +/*******************************slot temp[1-n] dir and attrs*******************************************/ +static struct switch_attribute slot_temp_alias_attr = __ATTR(alias, S_IRUGO, slot_temp_alias_show, NULL); +static struct switch_attribute slot_temp_type_attr = __ATTR(type, S_IRUGO, slot_temp_type_show, NULL); +static struct switch_attribute slot_temp_max_attr = __ATTR(max, S_IRUGO | S_IWUSR, slot_temp_max_show, slot_temp_max_store); +static struct switch_attribute slot_temp_min_attr = __ATTR(min, S_IRUGO | S_IWUSR, slot_temp_min_show, slot_temp_min_store); +static struct switch_attribute slot_temp_value_attr = __ATTR(value, S_IRUGO, slot_temp_value_show, NULL); + +static struct attribute *slot_temp_attrs[] = { + &slot_temp_alias_attr.attr, + &slot_temp_type_attr.attr, + &slot_temp_max_attr.attr, + &slot_temp_min_attr.attr, + &slot_temp_value_attr.attr, + NULL, +}; + +static struct attribute_group slot_temp_attr_group = { + .attrs = slot_temp_attrs, +}; + +/*******************************slot vol[1-n] dir and attrs*******************************************/ +static struct switch_attribute slot_vol_alias_attr = __ATTR(alias, S_IRUGO, slot_vol_alias_show, NULL); +static struct switch_attribute slot_vol_type_attr = __ATTR(type, S_IRUGO, slot_vol_type_show, NULL); +static struct switch_attribute slot_vol_max_attr = __ATTR(max, S_IRUGO | S_IWUSR, slot_vol_max_show, slot_vol_max_store); +static struct switch_attribute slot_vol_min_attr = __ATTR(min, S_IRUGO | S_IWUSR, slot_vol_min_show, slot_vol_min_store); +static struct switch_attribute slot_vol_value_attr = __ATTR(value, S_IRUGO, slot_vol_value_show, NULL); +static struct switch_attribute slot_vol_range_attr = __ATTR(range, S_IRUGO, slot_vol_range_show, NULL); +static struct switch_attribute slot_vol_nominal_value_attr = __ATTR(nominal_value, S_IRUGO, slot_vol_nominal_value_show, NULL); + +static struct attribute *slot_vol_attrs[] = { + &slot_vol_alias_attr.attr, + &slot_vol_type_attr.attr, + &slot_vol_max_attr.attr, + &slot_vol_min_attr.attr, + &slot_vol_value_attr.attr, + &slot_vol_range_attr.attr, + &slot_vol_nominal_value_attr.attr, + NULL, +}; + +static struct attribute_group slot_vol_attr_group = { + .attrs = slot_vol_attrs, +}; + +/*******************************slot curr[1-n] dir and attrs*******************************************/ +static struct switch_attribute slot_curr_alias_attr = __ATTR(alias, S_IRUGO, slot_curr_alias_show, NULL); +static struct switch_attribute slot_curr_type_attr = __ATTR(type, S_IRUGO, slot_curr_type_show, NULL); +static struct switch_attribute slot_curr_max_attr = __ATTR(max, S_IRUGO | S_IWUSR, slot_curr_max_show, slot_curr_max_store); +static struct switch_attribute slot_curr_min_attr = __ATTR(min, S_IRUGO | S_IWUSR, slot_curr_min_show, slot_curr_min_store); +static struct switch_attribute slot_curr_value_attr = __ATTR(value, S_IRUGO, slot_curr_value_show, NULL); + +static struct attribute *slot_curr_attrs[] = { + &slot_curr_alias_attr.attr, + &slot_curr_type_attr.attr, + &slot_curr_max_attr.attr, + &slot_curr_min_attr.attr, + &slot_curr_value_attr.attr, + NULL, +}; + +static struct attribute_group slot_curr_attr_group = { + .attrs = slot_curr_attrs, +}; + +/*******************************slot fpga[1-n] dir and attrs*******************************************/ +static struct switch_attribute slot_fpga_alias_attr = __ATTR(alias, S_IRUGO, slot_fpga_alias_show, NULL); +static struct switch_attribute slot_fpga_type_attr = __ATTR(type, S_IRUGO, slot_fpga_type_show, NULL); +static struct switch_attribute slot_fpga_fw_version_attr = __ATTR(firmware_version, S_IRUGO, slot_fpga_fw_version_show, NULL); +static struct switch_attribute slot_fpga_board_version_attr = __ATTR(board_version, S_IRUGO, slot_fpga_board_version_show, NULL); +static struct switch_attribute slot_fpga_test_reg_attr = __ATTR(reg_test, S_IRUGO | S_IWUSR, slot_fpga_test_reg_show, slot_fpga_test_reg_store); + +static struct attribute *slot_fpga_attrs[] = { + &slot_fpga_alias_attr.attr, + &slot_fpga_type_attr.attr, + &slot_fpga_fw_version_attr.attr, + &slot_fpga_board_version_attr.attr, + &slot_fpga_test_reg_attr.attr, + NULL, +}; + +static struct attribute_group slot_fpga_attr_group = { + .attrs = slot_fpga_attrs, +}; + +/*******************************slot cpld[1-n] dir and attrs*******************************************/ +static struct switch_attribute slot_cpld_alias_attr = __ATTR(alias, S_IRUGO, slot_cpld_alias_show, NULL); +static struct switch_attribute slot_cpld_type_attr = __ATTR(type, S_IRUGO, slot_cpld_type_show, NULL); +static struct switch_attribute slot_cpld_fw_version_attr = __ATTR(firmware_version, S_IRUGO, slot_cpld_fw_version_show, NULL); +static struct switch_attribute slot_cpld_board_version_attr = __ATTR(board_version, S_IRUGO, slot_cpld_board_version_show, NULL); +static struct switch_attribute slot_cpld_test_reg_attr = __ATTR(reg_test, S_IRUGO | S_IWUSR, slot_cpld_test_reg_show, slot_cpld_test_reg_store); + +static struct attribute *slot_cpld_attrs[] = { + &slot_cpld_alias_attr.attr, + &slot_cpld_type_attr.attr, + &slot_cpld_fw_version_attr.attr, + &slot_cpld_board_version_attr.attr, + &slot_cpld_test_reg_attr.attr, + NULL, +}; + +static struct attribute_group slot_cpld_attr_group = { + .attrs = slot_cpld_attrs, +}; + +/***************************************slot cpld*****************************************/ +static void slotindex_single_cpld_remove_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int cpld_index) +{ + struct slot_cpld_obj_s *curr_cpld; + + curr_cpld = &curr_slot->cpld[cpld_index - 1]; + if (curr_cpld->obj) { + sysfs_remove_group(&curr_cpld->obj->kobj, &slot_cpld_attr_group); + switch_kobject_delete(&curr_cpld->obj); + SLOT_DBG("delete slot%u cpld%u dir and attrs success.\n", curr_slot->obj->index, + cpld_index); + } + return; +} + +static int slotindex_single_cpld_create_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int cpld_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct slot_cpld_obj_s *curr_cpld; + + curr_cpld = &curr_slot->cpld[cpld_index - 1]; + memset(name, 0, sizeof(name)); + snprintf(name, sizeof(name), "cpld%u", cpld_index); + curr_cpld->obj = switch_kobject_create(name, &curr_slot->obj->kobj); + if (!curr_cpld->obj) { + SLOT_ERR("create slot%u %s object error!\n", curr_slot->obj->index, name); + return -ENOMEM; + } + curr_cpld->obj->index = cpld_index; + if (sysfs_create_group(&curr_cpld->obj->kobj, &slot_cpld_attr_group) != 0) { + SLOT_ERR("create slot%u %s attrs error.\n", curr_slot->obj->index, name); + switch_kobject_delete(&curr_cpld->obj); + return -EBADRQC; + } + SLOT_DBG("create slot%u %s success.\n", curr_slot->obj->index, name); + return 0; +} + +static void slotindex_cpld_remove_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int cpld_index, cpld_num; + + if (curr_slot->cpld) { + cpld_num = curr_slot->cpld_number; + for (cpld_index = cpld_num; cpld_index > 0; cpld_index--) { + slotindex_single_cpld_remove_kobj_and_attrs(curr_slot, cpld_index); + } + kfree(curr_slot->cpld); + curr_slot->cpld = NULL; + } + return; +} + +static int slotindex_cpld_create_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int cpld_index, i, cpld_num; + + cpld_num = curr_slot->cpld_number; + curr_slot->cpld = kzalloc(sizeof(struct slot_cpld_obj_s) * cpld_num, GFP_KERNEL); + if (!curr_slot->cpld) { + SLOT_ERR("kzalloc slot cpld error, slot index: %u, cpld number: %u.\n", + curr_slot->obj->index, cpld_num); + return -ENOMEM; + } + + for (cpld_index = 1; cpld_index <= cpld_num; cpld_index++) { + if (slotindex_single_cpld_create_kobj_and_attrs(curr_slot, cpld_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = cpld_index; i > 0; i--) { + slotindex_single_cpld_remove_kobj_and_attrs(curr_slot, i); + } + kfree(curr_slot->cpld); + curr_slot->cpld = NULL; + return -EBADRQC; +} + +/* create slot cpld[1-n] directory and attributes*/ +static int slot_cpld_create(void) +{ + int cpld_num; + unsigned int slot_index, i; + struct slot_obj_s *curr_slot; + + check_p(g_slot_drv->get_slot_cpld_number); + for (slot_index = 1; slot_index <= g_slot.slot_number; slot_index++) { + cpld_num = g_slot_drv->get_slot_cpld_number(slot_index); + if (cpld_num <= 0) { + SLOT_DBG("slot%u cpld number: %d, don't need to create cpld* dirs and attrs.\n", + slot_index, cpld_num); + continue; + } + curr_slot = &g_slot.slot[slot_index - 1]; + curr_slot->cpld_number = cpld_num; + if (slotindex_cpld_create_kobj_and_attrs(curr_slot) != 0) { + goto error; + } + } + return 0; +error: + for (i = slot_index; i > 0; i--) { + curr_slot = &g_slot.slot[i - 1]; + slotindex_cpld_remove_kobj_and_attrs(curr_slot); + } + return -EBADRQC; +} + +/* delete slot cpld[1-n] directory and attributes*/ +static void slot_cpld_remove(void) +{ + unsigned int slot_index; + struct slot_obj_s *curr_slot; + + if (g_slot.slot) { + for (slot_index = g_slot.slot_number; slot_index > 0; slot_index--) { + curr_slot = &g_slot.slot[slot_index - 1]; + slotindex_cpld_remove_kobj_and_attrs(curr_slot); + curr_slot->cpld_number = 0; + } + } + return; +} +/************************************end of slot cpld**************************************/ +/***************************************slot fpga*****************************************/ +static void slotindex_single_fpga_remove_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int fpga_index) +{ + struct slot_fpga_obj_s *curr_fpga; + + curr_fpga = &curr_slot->fpga[fpga_index - 1]; + if (curr_fpga->obj) { + sysfs_remove_group(&curr_fpga->obj->kobj, &slot_fpga_attr_group); + switch_kobject_delete(&curr_fpga->obj); + SLOT_DBG("delete slot%u fpga%u dir and attrs success.\n", curr_slot->obj->index, + fpga_index); + } + return; +} + +static int slotindex_single_fpga_create_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int fpga_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct slot_fpga_obj_s *curr_fpga; + + curr_fpga = &curr_slot->fpga[fpga_index - 1]; + memset(name, 0, sizeof(name)); + snprintf(name, sizeof(name), "fpga%u", fpga_index); + curr_fpga->obj = switch_kobject_create(name, &curr_slot->obj->kobj); + if (!curr_fpga->obj) { + SLOT_ERR("create slot%u %s object error!\n", curr_slot->obj->index, name); + return -ENOMEM; + } + curr_fpga->obj->index = fpga_index; + if (sysfs_create_group(&curr_fpga->obj->kobj, &slot_fpga_attr_group) != 0) { + SLOT_ERR("create slot%u %s attrs error.\n", curr_slot->obj->index, name); + switch_kobject_delete(&curr_fpga->obj); + return -EBADRQC; + } + SLOT_DBG("create slot%u %s success.\n", curr_slot->obj->index, name); + return 0; +} + +static void slotindex_fpga_remove_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int fpga_index, fpga_num; + + if (curr_slot->fpga) { + fpga_num = curr_slot->fpga_number; + for (fpga_index = fpga_num; fpga_index > 0; fpga_index--) { + slotindex_single_fpga_remove_kobj_and_attrs(curr_slot, fpga_index); + } + kfree(curr_slot->fpga); + curr_slot->fpga = NULL; + } + return; +} + +static int slotindex_fpga_create_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int fpga_index, i, fpga_num; + + fpga_num = curr_slot->fpga_number; + curr_slot->fpga = kzalloc(sizeof(struct slot_fpga_obj_s) * fpga_num, GFP_KERNEL); + if (!curr_slot->fpga) { + SLOT_ERR("kzalloc slot fpga error, slot index: %u, fpga number: %u.\n", + curr_slot->obj->index, fpga_num); + return -ENOMEM; + } + + for (fpga_index = 1; fpga_index <= fpga_num; fpga_index++) { + if (slotindex_single_fpga_create_kobj_and_attrs(curr_slot, fpga_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = fpga_index; i > 0; i--) { + slotindex_single_fpga_remove_kobj_and_attrs(curr_slot, i); + } + kfree(curr_slot->fpga); + curr_slot->fpga = NULL; + return -EBADRQC; +} + +/* create slot fpga[1-n] directory and attributes*/ +static int slot_fpga_create(void) +{ + int fpga_num; + unsigned int slot_index, i; + struct slot_obj_s *curr_slot; + + check_p(g_slot_drv->get_slot_fpga_number); + for (slot_index = 1; slot_index <= g_slot.slot_number; slot_index++) { + fpga_num = g_slot_drv->get_slot_fpga_number(slot_index); + if (fpga_num <= 0) { + SLOT_DBG("slot%u fpga number: %d, don't need to create fpga* dirs and attrs.\n", + slot_index, fpga_num); + continue; + } + curr_slot = &g_slot.slot[slot_index - 1]; + curr_slot->fpga_number = fpga_num; + if (slotindex_fpga_create_kobj_and_attrs(curr_slot) != 0) { + goto error; + } + } + return 0; +error: + for (i = slot_index; i > 0; i--) { + curr_slot = &g_slot.slot[i - 1]; + slotindex_fpga_remove_kobj_and_attrs(curr_slot); + } + return -EBADRQC; +} + +/* delete slot fpga[1-n] directory and attributes*/ +static void slot_fpga_remove(void) +{ + unsigned int slot_index; + struct slot_obj_s *curr_slot; + + if (g_slot.slot) { + for (slot_index = g_slot.slot_number; slot_index > 0; slot_index--) { + curr_slot = &g_slot.slot[slot_index - 1]; + slotindex_fpga_remove_kobj_and_attrs(curr_slot); + curr_slot->fpga_number = 0; + } + } + return; +} +/************************************end of slot fpga**************************************/ +/*************************************slot current*****************************************/ +static void slotindex_single_curr_remove_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int curr_index) +{ + struct slot_curr_obj_s *curr; + + curr = &curr_slot->curr[curr_index - 1]; + if (curr->obj) { + sysfs_remove_group(&curr->obj->kobj, &slot_curr_attr_group); + switch_kobject_delete(&curr->obj); + SLOT_DBG("delete slot%u curr_sensor%u dir and attrs success.\n", curr_slot->obj->index, + curr_index); + } + return; +} + +static int slotindex_single_curr_create_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int curr_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct slot_curr_obj_s *curr; + + curr = &curr_slot->curr[curr_index - 1]; + memset(name, 0, sizeof(name)); + snprintf(name, sizeof(name), "curr_sensor%u", curr_index); + curr->obj = switch_kobject_create(name, &curr_slot->obj->kobj); + if (!curr->obj) { + SLOT_ERR("create slot%u %s object error!\n", curr_slot->obj->index, name); + return -ENOMEM; + } + curr->obj->index = curr_index; + if (sysfs_create_group(&curr->obj->kobj, &slot_curr_attr_group) != 0) { + SLOT_ERR("create slot%u %s attrs error.\n", curr_slot->obj->index, name); + switch_kobject_delete(&curr->obj); + return -EBADRQC; + } + SLOT_DBG("create slot%u %s success.\n", curr_slot->obj->index, name); + return 0; +} + +static void slotindex_curr_remove_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int curr_index, curr_num; + + if (curr_slot->curr) { + curr_num = curr_slot->curr_number; + for (curr_index = curr_num; curr_index > 0; curr_index--) { + slotindex_single_curr_remove_kobj_and_attrs(curr_slot, curr_index); + } + kfree(curr_slot->curr); + curr_slot->curr = NULL; + } + return; +} + +static int slotindex_curr_create_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int curr_index, i, curr_num; + + curr_num = curr_slot->curr_number; + curr_slot->curr = kzalloc(sizeof(struct slot_curr_obj_s) * curr_num, GFP_KERNEL); + if (!curr_slot->curr) { + SLOT_ERR("kzalloc slot curr error, slot index: %u, curr number: %u.\n", + curr_slot->obj->index, curr_num); + return -ENOMEM; + } + + for (curr_index = 1; curr_index <= curr_num; curr_index++) { + if (slotindex_single_curr_create_kobj_and_attrs(curr_slot, curr_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = curr_index; i > 0; i--) { + slotindex_single_curr_remove_kobj_and_attrs(curr_slot, i); + } + kfree(curr_slot->curr); + curr_slot->curr = NULL; + return -EBADRQC; +} + +/* create slot curr_snesor[1-n] directory and attributes*/ +static int slot_curr_create(void) +{ + int curr_num; + unsigned int slot_index, i; + struct slot_obj_s *curr_slot; + + check_p(g_slot_drv->get_slot_curr_number); + for (slot_index = 1; slot_index <= g_slot.slot_number; slot_index++) { + curr_num = g_slot_drv->get_slot_curr_number(slot_index); + if (curr_num <= 0) { + SLOT_DBG("slot%u curr number: %d, don't need to create curr_sensor* dirs and attrs.\n", + slot_index, curr_num); + continue; + } + curr_slot = &g_slot.slot[slot_index - 1]; + curr_slot->curr_number = curr_num; + if (slotindex_curr_create_kobj_and_attrs(curr_slot) != 0) { + goto error; + } + } + return 0; +error: + for (i = slot_index; i > 0; i--) { + curr_slot = &g_slot.slot[i - 1]; + slotindex_curr_remove_kobj_and_attrs(curr_slot); + } + return -EBADRQC; +} + +/* delete slot curr_sensor[1-n] directory and attributes*/ +static void slot_curr_remove(void) +{ + unsigned int slot_index; + struct slot_obj_s *curr_slot; + + if (g_slot.slot) { + for (slot_index = g_slot.slot_number; slot_index > 0; slot_index--) { + curr_slot = &g_slot.slot[slot_index - 1]; + slotindex_curr_remove_kobj_and_attrs(curr_slot); + curr_slot->curr_number = 0; + } + } + return; +} +/**********************************end of slot current************************************/ +/*************************************slot voltage****************************************/ +static void slotindex_single_vol_remove_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int vol_index) +{ + struct slot_vol_obj_s *curr_vol; + + curr_vol = &curr_slot->vol[vol_index - 1]; + if (curr_vol->obj) { + sysfs_remove_group(&curr_vol->obj->kobj, &slot_vol_attr_group); + switch_kobject_delete(&curr_vol->obj); + SLOT_DBG("delete slot%u vol_sensor%u dir and attrs success.\n", curr_slot->obj->index, + vol_index); + } + return; +} + +static int slotindex_single_vol_create_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int vol_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct slot_vol_obj_s *curr_vol; + + curr_vol = &curr_slot->vol[vol_index - 1]; + memset(name, 0, sizeof(name)); + snprintf(name, sizeof(name), "vol_sensor%u", vol_index); + curr_vol->obj = switch_kobject_create(name, &curr_slot->obj->kobj); + if (!curr_vol->obj) { + SLOT_ERR("create slot%u %s object error!\n", curr_slot->obj->index, name); + return -ENOMEM; + } + curr_vol->obj->index = vol_index; + if (sysfs_create_group(&curr_vol->obj->kobj, &slot_vol_attr_group) != 0) { + SLOT_ERR("create slot%u %s attrs error.\n", curr_slot->obj->index, name); + switch_kobject_delete(&curr_vol->obj); + return -EBADRQC; + } + SLOT_DBG("create slot%u %s success.\n", curr_slot->obj->index, name); + return 0; +} + +static void slotindex_vol_remove_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int vol_index, vol_num; + + if (curr_slot->vol) { + vol_num = curr_slot->vol_number; + for (vol_index = vol_num; vol_index > 0; vol_index--) { + slotindex_single_vol_remove_kobj_and_attrs(curr_slot, vol_index); + } + kfree(curr_slot->vol); + curr_slot->vol = NULL; + } + return; +} + +static int slotindex_vol_create_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int vol_index, i, vol_num; + + vol_num = curr_slot->vol_number; + curr_slot->vol = kzalloc(sizeof(struct slot_vol_obj_s) * vol_num, GFP_KERNEL); + if (!curr_slot->vol) { + SLOT_ERR("kzalloc slot vol error, slot index: %u, vol number: %u.\n", + curr_slot->obj->index, vol_num); + return -ENOMEM; + } + + for (vol_index = 1; vol_index <= vol_num; vol_index++) { + if (slotindex_single_vol_create_kobj_and_attrs(curr_slot, vol_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = vol_index; i > 0; i--) { + slotindex_single_vol_remove_kobj_and_attrs(curr_slot, i); + } + kfree(curr_slot->vol); + curr_slot->vol = NULL; + return -EBADRQC; +} + +/* create slot vol_snesor[1-n] directory and attributes*/ +static int slot_vol_create(void) +{ + int vol_num; + unsigned int slot_index, i; + struct slot_obj_s *curr_slot; + + check_p(g_slot_drv->get_slot_vol_number); + for (slot_index = 1; slot_index <= g_slot.slot_number; slot_index++) { + vol_num = g_slot_drv->get_slot_vol_number(slot_index); + if (vol_num <= 0) { + SLOT_DBG("slot%u vol number: %d, don't need to create vol_sensor* dirs and attrs.\n", + slot_index, vol_num); + continue; + } + curr_slot = &g_slot.slot[slot_index - 1]; + curr_slot->vol_number = vol_num; + if (slotindex_vol_create_kobj_and_attrs(curr_slot) != 0) { + goto error; + } + } + return 0; +error: + for (i = slot_index; i > 0; i--) { + curr_slot = &g_slot.slot[i - 1]; + slotindex_vol_remove_kobj_and_attrs(curr_slot); + } + return -EBADRQC; +} + +/* delete slot vol_sensor[1-n] directory and attributes*/ +static void slot_vol_remove(void) +{ + unsigned int slot_index; + struct slot_obj_s *curr_slot; + + if (g_slot.slot) { + for (slot_index = g_slot.slot_number; slot_index > 0; slot_index--) { + curr_slot = &g_slot.slot[slot_index - 1]; + slotindex_vol_remove_kobj_and_attrs(curr_slot); + curr_slot->vol_number = 0; + } + } + return; +} +/**********************************end of slot voltage************************************/ +/***************************************slot temp*****************************************/ +static void slotindex_single_temp_remove_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int temp_index) +{ + struct slot_temp_obj_s *curr_temp; + + curr_temp = &curr_slot->temp[temp_index - 1]; + if (curr_temp->obj) { + sysfs_remove_group(&curr_temp->obj->kobj, &slot_temp_attr_group); + switch_kobject_delete(&curr_temp->obj); + SLOT_DBG("delete slot%u temp_sensor%u dir and attrs success.\n", curr_slot->obj->index, + temp_index); + } + return; +} + +static int slotindex_single_temp_create_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int temp_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct slot_temp_obj_s *curr_temp; + + curr_temp = &curr_slot->temp[temp_index - 1]; + memset(name, 0, sizeof(name)); + snprintf(name, sizeof(name), "temp_sensor%u", temp_index); + curr_temp->obj = switch_kobject_create(name, &curr_slot->obj->kobj); + if (!curr_temp->obj) { + SLOT_ERR("create slot%u %s object error!\n", curr_slot->obj->index, name); + return -ENOMEM; + } + curr_temp->obj->index = temp_index; + if (sysfs_create_group(&curr_temp->obj->kobj, &slot_temp_attr_group) != 0) { + SLOT_ERR("create slot%u %s attrs error.\n", curr_slot->obj->index, name); + switch_kobject_delete(&curr_temp->obj); + return -EBADRQC; + } + SLOT_DBG("create slot%u %s success.\n", curr_slot->obj->index, name); + return 0; +} + +static void slotindex_temp_remove_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int temp_index, temp_num; + + if (curr_slot->temp) { + temp_num = curr_slot->temp_number; + for (temp_index = temp_num; temp_index > 0; temp_index--) { + slotindex_single_temp_remove_kobj_and_attrs(curr_slot, temp_index); + } + kfree(curr_slot->temp); + curr_slot->temp = NULL; + } + return; +} + +static int slotindex_temp_create_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int temp_index, i, temp_num; + + temp_num = curr_slot->temp_number; + curr_slot->temp = kzalloc(sizeof(struct slot_temp_obj_s) * temp_num, GFP_KERNEL); + if (!curr_slot->temp) { + SLOT_ERR("kzalloc slot temp error, slot index: %u, temp number: %u.\n", + curr_slot->obj->index, temp_num); + return -ENOMEM; + } + + for (temp_index = 1; temp_index <= temp_num; temp_index++) { + if (slotindex_single_temp_create_kobj_and_attrs(curr_slot, temp_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = temp_index; i > 0; i--) { + slotindex_single_temp_remove_kobj_and_attrs(curr_slot, i); + } + kfree(curr_slot->temp); + curr_slot->temp = NULL; + return -EBADRQC; +} + +/* create slot temp_sensor[1-n] directory and attributes*/ +static int slot_temp_create(void) +{ + int temp_num; + unsigned int slot_index, i; + struct slot_obj_s *curr_slot; + + check_p(g_slot_drv->get_slot_temp_number); + for (slot_index = 1; slot_index <= g_slot.slot_number; slot_index++) { + temp_num = g_slot_drv->get_slot_temp_number(slot_index); + if (temp_num <= 0) { + SLOT_DBG("slot%u temp number: %d, don't need to create temp_sensor* dirs and attrs.\n", + slot_index, temp_num); + continue; + } + curr_slot = &g_slot.slot[slot_index - 1]; + curr_slot->temp_number = temp_num; + if (slotindex_temp_create_kobj_and_attrs(curr_slot) != 0) { + goto error; + } + } + return 0; +error: + for (i = slot_index; i > 0; i--) { + curr_slot = &g_slot.slot[i - 1]; + slotindex_temp_remove_kobj_and_attrs(curr_slot); + } + return -EBADRQC; +} + +/* delete slot temp_sensor[1-n] directory and attributes*/ +static void slot_temp_remove(void) +{ + unsigned int slot_index; + struct slot_obj_s *curr_slot; + + if (g_slot.slot) { + for (slot_index = g_slot.slot_number; slot_index > 0; slot_index--) { + curr_slot = &g_slot.slot[slot_index - 1]; + slotindex_temp_remove_kobj_and_attrs(curr_slot); + curr_slot->temp_number = 0; + } + } + return; +} +/************************************end of slot temp**************************************/ + +static int slot_child_obj_create(void) +{ + int ret; + + if (g_slot.slot_number <= 0) { + SLOT_DBG("slot number: %u, skip to create slot child dirs and attrs.\n", + g_slot.slot_number); + return 0; + } + /* temp create */ + ret = slot_temp_create(); + if (ret < 0) { + goto temp_err; + } + /* Voltage create */ + ret = slot_vol_create(); + if(ret < 0) { + goto vol_err; + } + /* current create */ + ret = slot_curr_create(); + if(ret < 0) { + goto curr_err; + } + /* fpga create */ + ret = slot_fpga_create(); + if(ret < 0) { + goto fpga_err; + } + /* cplf create */ + ret = slot_cpld_create(); + if(ret < 0) { + goto cpld_err; + } + return 0; +cpld_err: + slot_fpga_remove(); +fpga_err: + slot_curr_remove(); +curr_err: + slot_vol_remove(); +vol_err: + slot_temp_remove(); +temp_err: + return ret; +} + +static void slot_child_obj_remove(void) +{ + slot_cpld_remove(); + slot_fpga_remove(); + slot_curr_remove(); + slot_vol_remove(); + slot_temp_remove(); + return; +} + +static void slot_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct slot_obj_s *curr_slot; + + curr_slot = &g_slot.slot[index - 1]; + if (curr_slot->obj) { + sysfs_remove_group(&curr_slot->obj->kobj, &slot_attr_group); + switch_kobject_delete(&curr_slot->obj); + SLOT_DBG("delete slot%u dir and attrs success.\n", index); + } + + return; +} + +static int slot_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[DIR_NAME_MAX_LEN]; + struct slot_obj_s * curr_slot; + + curr_slot = &g_slot.slot[index - 1]; + memset(name, 0, sizeof(name)); + snprintf(name, sizeof(name), "slot%u", index); + curr_slot->obj = switch_kobject_create(name, parent); + if (!curr_slot->obj) { + SLOT_ERR("create %s object error!\n", name); + return -EBADRQC; + } + curr_slot->obj->index = index; + if (sysfs_create_group(&curr_slot->obj->kobj, &slot_attr_group) != 0) { + SLOT_ERR("create %s attrs error.\n", name); + switch_kobject_delete(&curr_slot->obj); + return -EBADRQC; + } + SLOT_DBG("create %s dir and attrs success.\n", name); + return 0; +} + +static int slot_sub_create_kobj_and_attrs(struct kobject *parent, int slot_num) +{ + unsigned int slot_index, i; + + g_slot.slot = kzalloc(sizeof(struct slot_obj_s) * slot_num, GFP_KERNEL); + if (!g_slot.slot) { + SLOT_ERR("kzalloc slot.slot error, slot number = %d.\n", slot_num); + return -ENOMEM; + } + + for(slot_index = 1; slot_index <= slot_num; slot_index++) { + if(slot_sub_single_create_kobj_and_attrs(parent, slot_index) != 0 ) { + goto error; + } + } + return 0; +error: + for(i = slot_index; i > 0; i--) { + slot_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_slot.slot); + g_slot.slot = NULL; + return -EBADRQC; +} + +/* create slot[1-n] directory and attributes*/ +static int slot_sub_create(void) +{ + int ret; + + ret = slot_sub_create_kobj_and_attrs(&g_slot_obj->kobj, g_slot.slot_number); + return ret; +} + +/* delete slot[1-n] directory and attributes*/ +static void slot_sub_remove(void) +{ + unsigned int slot_index; + + if (g_slot.slot) { + for (slot_index = g_slot.slot_number; slot_index > 0; slot_index--) { + slot_sub_single_remove_kobj_and_attrs(slot_index); + } + kfree(g_slot.slot); + g_slot.slot = NULL; + } + g_slot.slot_number = 0; + return; +} + +/* create slot directory and number attributes*/ +static int slot_root_create(void) +{ + g_slot_obj = switch_kobject_create("slot", NULL); + if (!g_slot_obj) { + SLOT_ERR("switch_kobject_create slot error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_slot_obj->kobj, &slot_root_attr_group) != 0) { + switch_kobject_delete(&g_slot_obj); + SLOT_ERR("create slot dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete slot directory and number attributes*/ +static void slot_root_remove(void) +{ + if (g_slot_obj) { + sysfs_remove_group(&g_slot_obj->kobj, &slot_root_attr_group); + switch_kobject_delete(&g_slot_obj); + } + + return; +} + +int s3ip_sysfs_slot_drivers_register(struct s3ip_sysfs_slot_drivers_s *drv) +{ + int ret, slot_num; + + SLOT_INFO("s3ip_sysfs_slot_drivers_register...\n"); + if (g_slot_drv) { + SLOT_ERR("g_slot_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_slot_number); + g_slot_drv = drv; + + slot_num = g_slot_drv->get_slot_number(); + if (slot_num <= 0) { + SLOT_ERR("slot number: %d, don't need to create slot dirs and attrs.\n", slot_num); + g_slot_drv = NULL; + return -EINVAL; + } + + memset(&g_slot, 0, sizeof(struct slot_s)); + g_slot.slot_number = slot_num; + ret = slot_root_create(); + if (ret < 0) { + SLOT_ERR("create slot root dir and attrs failed, ret: %d\n", ret); + g_slot_drv = NULL; + return ret; + } + + ret = slot_sub_create(); + if (ret < 0) { + SLOT_ERR("create slot sub dir and attrs failed, ret: %d\n", ret); + slot_root_remove(); + g_slot_drv = NULL; + return ret; + } + + ret = slot_child_obj_create(); + if (ret < 0) { + SLOT_ERR("create slot child dir and attrs failed, ret: %d\n", ret); + slot_sub_remove(); + slot_root_remove(); + g_slot_drv = NULL; + return ret; + } + SLOT_INFO("s3ip_sysfs_slot_drivers_register success.\n"); + return 0; +} + +void s3ip_sysfs_slot_drivers_unregister(void) +{ + if (g_slot_drv) { + slot_child_obj_remove(); + slot_sub_remove(); + slot_root_remove(); + g_slot_drv = NULL; + SLOT_DBG("s3ip_sysfs_slot_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_slot_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_slot_drivers_unregister); +module_param(g_slot_loglevel, int, 0644); +MODULE_PARM_DESC(g_slot_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/switch.c b/platform/s3ip-sysfs/s3ip_sysfs_frame/switch.c new file mode 100644 index 000000000000..6bd07cfa0c65 --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/switch.c @@ -0,0 +1,270 @@ +/* + * switch.c + * + * This module create a kset in sysfs called /sys/s3ip + * Then other switch kobjects are created and assigned to this kset, + * such as "cpld", "fan", "psu", ... + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-08-31 S3IP sysfs + */ + +#include "switch.h" +#include "syseeprom_sysfs.h" + +int g_switch_loglevel = 0; + +#define SWITCH_INFO(fmt, args...) do { \ + if (g_switch_loglevel & INFO) { \ + printk(KERN_INFO "[SWITCH][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SWITCH_ERR(fmt, args...) do { \ + if (g_switch_loglevel & ERR) { \ + printk(KERN_ERR "[SWITCH][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SWITCH_DBG(fmt, args...) do { \ + if (g_switch_loglevel & DBG) { \ + printk(KERN_DEBUG "[SWITCH][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct syseeprom_s { + struct bin_attribute bin; + int creat_eeprom_bin_flag; +}; + +static struct s3ip_sysfs_syseeprom_drivers_s *g_syseeprom_drv = NULL; +static struct kset *switch_kset; +static struct syseeprom_s g_syseeprom; + +static ssize_t switch_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) +{ + struct switch_attribute *attribute; + struct switch_obj *device; + + attribute = to_switch_attr(attr); + device = to_switch_obj(kobj); + + if (!attribute->show) { + return -ENOSYS; + } + + return attribute->show(device, attribute, buf); +} + +static ssize_t switch_attr_store(struct kobject *kobj, struct attribute *attr, const char *buf, + size_t len) +{ + struct switch_attribute *attribute; + struct switch_obj *obj; + + attribute = to_switch_attr(attr); + obj = to_switch_obj(kobj); + + if (!attribute->store) { + return -ENOSYS; + } + + return attribute->store(obj, attribute, buf, len); +} + +static const struct sysfs_ops switch_sysfs_ops = { + .show = switch_attr_show, + .store = switch_attr_store, +}; + +static void switch_obj_release(struct kobject *kobj) +{ + struct switch_obj *obj; + + obj = to_switch_obj(kobj); + kfree(obj); + return; +} + +static struct kobj_type switch_ktype = { + .sysfs_ops = &switch_sysfs_ops, + .release = switch_obj_release, + .default_attrs = NULL, +}; + +static ssize_t syseeprom_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t offset, size_t count) +{ + ssize_t rd_len; + + check_p(g_syseeprom_drv); + check_p(g_syseeprom_drv->read_syseeprom_data); + + memset(buf, 0, count); + rd_len = g_syseeprom_drv->read_syseeprom_data(buf, offset, count); + if (rd_len < 0) { + SWITCH_ERR("read syseeprom data error, offset: 0x%llx, read len: %lu, ret: %ld.\n", + offset, count, rd_len); + return -EIO; + } + SWITCH_DBG("read syseeprom data success, offset:0x%llx, read len:%lu, really read len:%ld.\n", + offset, count, rd_len); + return rd_len; +} + +static ssize_t syseeprom_write(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t offset, size_t count) +{ + ssize_t wr_len; + + check_p(g_syseeprom_drv); + check_p(g_syseeprom_drv->write_syseeprom_data); + + wr_len = g_syseeprom_drv->write_syseeprom_data(buf, offset, count); + if (wr_len < 0) { + SWITCH_ERR("write syseeprom data error, offset: 0x%llx, read len: %lu, ret: %ld.\n", + offset, count, wr_len); + return -EIO; + } + SWITCH_DBG("write syseeprom data success, offset:0x%llx, write len:%lu, really write len:%ld.\n", + offset, count, wr_len); + return wr_len; +} + +static int syseeprom_create_eeprom_attrs(void) +{ + int ret, eeprom_size; + + eeprom_size = g_syseeprom_drv->get_syseeprom_size(); + if (eeprom_size <= 0) { + SWITCH_ERR("syseeprom size: %d, invalid.\n", eeprom_size); + return -EINVAL; + } + + sysfs_bin_attr_init(&g_syseeprom.bin); + g_syseeprom.bin.attr.name = "syseeprom"; + g_syseeprom.bin.attr.mode = 0644; + g_syseeprom.bin.read = syseeprom_read; + g_syseeprom.bin.write = syseeprom_write; + g_syseeprom.bin.size = eeprom_size; + + ret = sysfs_create_bin_file(&switch_kset->kobj, &g_syseeprom.bin); + if (ret) { + SWITCH_ERR("create syseeprom bin error, ret: %d. \n", ret); + return -EBADRQC; + } + SWITCH_DBG("create syseeprom bin file success, eeprom size:%d.\n", eeprom_size); + g_syseeprom.creat_eeprom_bin_flag = 1; + return 0; +} + +static void syseeprom_remove_eeprom_attrs(void) +{ + if (g_syseeprom.creat_eeprom_bin_flag) { + sysfs_remove_bin_file(&switch_kset->kobj, &g_syseeprom.bin); + g_syseeprom.creat_eeprom_bin_flag = 0; + } + + return; +} + +int s3ip_sysfs_syseeprom_drivers_register(struct s3ip_sysfs_syseeprom_drivers_s *drv) +{ + int ret; + + SWITCH_INFO("s3ip_sysfs_syseeprom_drivers_register...\n"); + if (g_syseeprom_drv) { + SWITCH_ERR("g_syseeprom_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_syseeprom_size); + g_syseeprom_drv = drv; + + ret = syseeprom_create_eeprom_attrs(); + if (ret < 0) { + SWITCH_ERR("create syseeprom attributes failed, ret: %d\n", ret); + g_syseeprom_drv = NULL; + return ret; + } + SWITCH_INFO("s3ip_sysfs_syseeprom_drivers_register success.\n"); + return 0; +} + +void s3ip_sysfs_syseeprom_drivers_unregister(void) +{ + if (g_syseeprom_drv) { + syseeprom_remove_eeprom_attrs(); + g_syseeprom_drv = NULL; + SWITCH_DBG("s3ip_sysfs_syseeprom_drivers_unregister success.\n"); + } + + return; +} + +struct switch_obj *switch_kobject_create(const char *name, struct kobject *parent) +{ + struct switch_obj *obj; + int ret; + + obj = kzalloc(sizeof(*obj), GFP_KERNEL); + if (!obj) { + SWITCH_DBG("switch_kobject_create %s kzalloc error", name); + return NULL; + } + + obj->kobj.kset = switch_kset; + + ret = kobject_init_and_add(&obj->kobj, &switch_ktype, parent, "%s", name); + if (ret) { + kobject_put(&obj->kobj); + SWITCH_DBG("kobject_init_and_add %s error", name); + return NULL; + } + + return obj; +} + +void switch_kobject_delete(struct switch_obj **obj) +{ + if (*obj) { + SWITCH_DBG("%s delete %s.\n", (*obj)->kobj.parent->name, (*obj)->kobj.name); + kobject_put(&((*obj)->kobj)); + *obj = NULL; + } +} + +static int __init switch_init(void) +{ + SWITCH_INFO("switch_init...\n"); + + switch_kset = kset_create_and_add("s3ip", NULL, NULL); + if (!switch_kset) { + SWITCH_ERR("create switch_kset error.\n"); + return -ENOMEM; + } + + SWITCH_INFO("switch_init success.\n"); + return 0; +} + +static void __exit switch_exit(void) +{ + if (switch_kset) { + kset_unregister(switch_kset); + } + + SWITCH_INFO("switch_exit success.\n"); +} + +module_init(switch_init); +module_exit(switch_exit); +EXPORT_SYMBOL(s3ip_sysfs_syseeprom_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_syseeprom_drivers_unregister); +module_param(g_switch_loglevel, int, 0644); +MODULE_PARM_DESC(g_switch_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("switch driver"); diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/sysled_sysfs.c b/platform/s3ip-sysfs/s3ip_sysfs_frame/sysled_sysfs.c new file mode 100644 index 000000000000..e42d40a755a2 --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/sysled_sysfs.c @@ -0,0 +1,314 @@ +/* + * sysled_sysfs.c + * + * This module create sysled kobjects and attributes in /sys/s3ip/sysled + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-08-31 S3IP sysfs + */ + +#include + +#include "switch.h" +#include "sysled_sysfs.h" + +static int g_sysled_loglevel = 0; + +#define SYSLED_INFO(fmt, args...) do { \ + if (g_sysled_loglevel & INFO) { \ + printk(KERN_INFO "[SYSLED_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SYSLED_ERR(fmt, args...) do { \ + if (g_sysled_loglevel & ERR) { \ + printk(KERN_ERR "[SYSLED_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SYSLED_DBG(fmt, args...) do { \ + if (g_sysled_loglevel & DBG) { \ + printk(KERN_DEBUG "[SYSLED_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static struct switch_obj *g_sysled_obj = NULL; +static struct s3ip_sysfs_sysled_drivers_s *g_sysled_drv = NULL; + +static ssize_t sys_led_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + int ret; + + check_p(g_sysled_drv); + check_p(g_sysled_drv->get_sys_led_status); + + ret = g_sysled_drv->get_sys_led_status(buf, PAGE_SIZE); + if (ret < 0) { + SYSLED_ERR("get sys led status failed, ret: %d:\n", ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + SYSLED_DBG("get sys led status success:\n"); + return ret; +} + +static ssize_t sys_led_status_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + int ret, value; + + check_p(g_sysled_drv); + check_p(g_sysled_drv->set_sys_led_status); + + sscanf(buf, "%d", &value); + if (value < 0) { + SYSLED_ERR("invaild led status value: %d, can't set sys led status\n", value); + return -EINVAL; + } + ret = g_sysled_drv->set_sys_led_status(value); + if (ret < 0) { + SYSLED_ERR("set sys led status %d faield, ret: %d\n", value, ret); + return -EIO; + } + SYSLED_DBG("set sys led status %d success\n", value); + return count; +} + +static ssize_t bmc_led_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + int ret; + + check_p(g_sysled_drv); + check_p(g_sysled_drv->get_bmc_led_status); + + ret = g_sysled_drv->get_bmc_led_status(buf, PAGE_SIZE); + if (ret < 0) { + SYSLED_ERR("get bmc led status failed, ret: %d:\n", ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + SYSLED_DBG("get bmc led status success:\n"); + return ret; +} + +static ssize_t bmc_led_status_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + int ret, value; + + check_p(g_sysled_drv); + check_p(g_sysled_drv->set_bmc_led_status); + + sscanf(buf, "%d", &value); + if (value < 0) { + SYSLED_ERR("invaild led status value: %d, can't set bmc led status\n", value); + return -EINVAL; + } + ret = g_sysled_drv->set_bmc_led_status(value); + if (ret < 0) { + SYSLED_ERR("set bmc led status %d faield, ret: %d\n", value, ret); + return -EIO; + } + SYSLED_DBG("set bmc led status %d success\n", value); + return count; +} + +static ssize_t sys_fan_led_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + int ret; + + check_p(g_sysled_drv); + check_p(g_sysled_drv->get_sys_fan_led_status); + + ret = g_sysled_drv->get_sys_fan_led_status(buf, PAGE_SIZE); + if (ret < 0) { + SYSLED_ERR("get sys fan led status failed, ret: %d:\n", ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + SYSLED_DBG("get sys fan led status success:\n"); + return ret; +} + +static ssize_t sys_fan_led_status_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + int ret, value; + + check_p(g_sysled_drv); + check_p(g_sysled_drv->set_sys_fan_led_status); + + sscanf(buf, "%d", &value); + if (value < 0) { + SYSLED_ERR("invaild led status value: %d, can't set sys fan led status\n", value); + return -EINVAL; + } + ret = g_sysled_drv->set_sys_fan_led_status(value); + if (ret < 0) { + SYSLED_ERR("set sys fan led status %d faield, ret: %d\n", value, ret); + return -EIO; + } + SYSLED_DBG("set sys fan led status %d success\n", value); + return count; +} + +static ssize_t sys_psu_led_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + int ret; + + check_p(g_sysled_drv); + check_p(g_sysled_drv->get_sys_psu_led_status); + + ret = g_sysled_drv->get_sys_psu_led_status(buf, PAGE_SIZE); + if (ret < 0) { + SYSLED_ERR("get sys psu led status failed, ret: %d:\n", ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + SYSLED_DBG("get sys psu led status success:\n"); + return ret; +} + +static ssize_t sys_psu_led_status_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + int ret, value; + + check_p(g_sysled_drv); + check_p(g_sysled_drv->set_sys_psu_led_status); + + sscanf(buf, "%d", &value); + if (value < 0) { + SYSLED_ERR("invaild led status value: %d, can't set sys psu led status\n", value); + return -EINVAL; + } + ret = g_sysled_drv->set_sys_psu_led_status(value); + if (ret < 0) { + SYSLED_ERR("set sys psu led status %d faield, ret: %d\n", value, ret); + return -EIO; + } + SYSLED_DBG("set sys psu led status %d success\n", value); + return count; +} + +static ssize_t id_led_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + int ret; + + check_p(g_sysled_drv); + check_p(g_sysled_drv->get_id_led_status); + + ret = g_sysled_drv->get_id_led_status(buf, PAGE_SIZE); + if (ret < 0) { + SYSLED_ERR("get id led status failed, ret: %d:\n", ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + SYSLED_DBG("get id led status success:\n"); + return ret; +} + +static ssize_t id_led_status_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + int ret, value; + + check_p(g_sysled_drv); + check_p(g_sysled_drv->set_id_led_status); + + sscanf(buf, "%d", &value); + if (value < 0) { + SYSLED_ERR("invaild led status value: %d, can't set id led status\n", value); + return -EINVAL; + } + ret = g_sysled_drv->set_id_led_status(value); + if (ret < 0) { + SYSLED_ERR("set id led status %d faield, ret: %d\n", value, ret); + return -EIO; + } + SYSLED_DBG("set id led status %d success\n", value); + return count; +} + +/************************************syseeprom dir and attrs*******************************************/ +static struct switch_attribute sys_led_attr = __ATTR(sys_led_status, S_IRUGO | S_IWUSR, sys_led_status_show, sys_led_status_store); +static struct switch_attribute bmc_led_attr = __ATTR(bmc_led_status, S_IRUGO | S_IWUSR, bmc_led_status_show, bmc_led_status_store); +static struct switch_attribute fan_led_attr = __ATTR(fan_led_status, S_IRUGO | S_IWUSR, sys_fan_led_status_show, sys_fan_led_status_store); +static struct switch_attribute psu_led_attr = __ATTR(psu_led_status, S_IRUGO | S_IWUSR, sys_psu_led_status_show, sys_psu_led_status_store); +static struct switch_attribute id_led_attr = __ATTR(id_led_status, S_IRUGO | S_IWUSR, id_led_status_show, id_led_status_store); + +static struct attribute *sysled_dir_attrs[] = { + &sys_led_attr.attr, + &bmc_led_attr.attr, + &fan_led_attr.attr, + &psu_led_attr.attr, + &id_led_attr.attr, + NULL, +}; + +static struct attribute_group sysled_attr_group = { + .attrs = sysled_dir_attrs, +}; + +/* create syseled directory and attributes*/ +static int sysled_root_create(void) +{ + g_sysled_obj = switch_kobject_create("sysled", NULL); + if (!g_sysled_obj) { + SYSLED_ERR("switch_kobject_create sysled error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_sysled_obj->kobj, &sysled_attr_group) != 0) { + switch_kobject_delete(&g_sysled_obj); + SYSLED_ERR("create sysled dir attrs error!\n"); + return -EBADRQC; + } + + return 0; +} + +/* delete syseled directory and attributes*/ +static void sysled_root_remove(void) +{ + if (g_sysled_obj) { + sysfs_remove_group(&g_sysled_obj->kobj, &sysled_attr_group); + switch_kobject_delete(&g_sysled_obj); + } + + return; +} + +int s3ip_sysfs_sysled_drivers_register(struct s3ip_sysfs_sysled_drivers_s *drv) +{ + int ret; + + SYSLED_INFO("s3ip_sysfs_sysled_drivers_register...\n"); + if (g_sysled_drv) { + SYSLED_ERR("g_sysled_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + g_sysled_drv = drv; + + ret = sysled_root_create(); + if (ret < 0) { + SYSLED_ERR("sysled create error.\n"); + g_sysled_drv = NULL; + return ret; + } + SYSLED_INFO("s3ip_sysfs_sysled_drivers_register success\n"); + return 0; +} + +void s3ip_sysfs_sysled_drivers_unregister(void) +{ + if (g_sysled_drv) { + sysled_root_remove(); + g_sysled_drv = NULL; + SYSLED_DBG("s3ip_sysfs_sysled_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_sysled_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_sysled_drivers_unregister); +module_param(g_sysled_loglevel, int, 0644); +MODULE_PARM_DESC(g_sysled_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/temp_sensor_sysfs.c b/platform/s3ip-sysfs/s3ip_sysfs_frame/temp_sensor_sysfs.c new file mode 100644 index 000000000000..0e794dcf19ee --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/temp_sensor_sysfs.c @@ -0,0 +1,392 @@ +/* + * temp_sensor_sysfs.c + * + * This module create temp sensor kobjects and attributes in /sys/s3ip/temp_sensor + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-08-31 S3IP sysfs + */ + +#include + +#include "switch.h" +#include "temp_sensor_sysfs.h" + +static int g_temp_sensor_loglevel = 0; + +#define TEMP_SENSOR_INFO(fmt, args...) do { \ + if (g_temp_sensor_loglevel & INFO) { \ + printk(KERN_INFO "[TEMP_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define TEMP_SENSOR_ERR(fmt, args...) do { \ + if (g_temp_sensor_loglevel & ERR) { \ + printk(KERN_ERR "[TEMP_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define TEMP_SENSOR_DBG(fmt, args...) do { \ + if (g_temp_sensor_loglevel & DBG) { \ + printk(KERN_DEBUG "[TEMP_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct temp_sensor_obj_s { + struct switch_obj *obj; +}; + +struct temp_sensor_s { + unsigned int temp_number; + struct temp_sensor_obj_s *temp; +}; + +static struct s3ip_sysfs_temp_sensor_drivers_s *g_temp_sensor_drv = NULL; +static struct temp_sensor_s g_temp_sensor; +static struct switch_obj *g_temp_sensor_obj = NULL; + +static ssize_t temp_sensor_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_temp_sensor.temp_number); +} + +static ssize_t temp_sensor_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int temp_index; + int ret; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->get_main_board_temp_value); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + ret = g_temp_sensor_drv->get_main_board_temp_value(temp_index, buf, PAGE_SIZE); + if (ret < 0) { + TEMP_SENSOR_ERR("get temp%u value failed, ret: %d\n", temp_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t temp_sensor_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int temp_index; + int ret; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->get_main_board_temp_alias); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + ret = g_temp_sensor_drv->get_main_board_temp_alias(temp_index, buf, PAGE_SIZE); + if (ret < 0) { + TEMP_SENSOR_ERR("get temp%u alias failed, ret: %d\n", temp_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t temp_sensor_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int temp_index; + int ret; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->get_main_board_temp_type); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + ret = g_temp_sensor_drv->get_main_board_temp_type(temp_index, buf, PAGE_SIZE); + if (ret < 0) { + TEMP_SENSOR_ERR("get temp%u type failed, ret: %d\n", temp_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t temp_sensor_max_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int temp_index; + int ret; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->get_main_board_temp_max); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + ret = g_temp_sensor_drv->get_main_board_temp_max(temp_index, buf, PAGE_SIZE); + if (ret < 0) { + TEMP_SENSOR_ERR("get temp%u max threshold failed, ret: %d\n", temp_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t temp_sensor_max_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int temp_index; + int ret; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->set_main_board_temp_max); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + ret = g_temp_sensor_drv->set_main_board_temp_max(temp_index, buf, count); + if (ret < 0) { + TEMP_SENSOR_ERR("set temp%u max threshold failed, value: %s, count: %lu, ret: %d\n", + temp_index, buf, count, ret); + return -EIO; + } + TEMP_SENSOR_DBG("set temp%u max threshold success, value: %s, count: %lu, ret: %d\n", + temp_index, buf, count, ret); + return count; +} + +static ssize_t temp_sensor_min_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int temp_index; + int ret; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->get_main_board_temp_min); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + ret = g_temp_sensor_drv->get_main_board_temp_min(temp_index, buf, PAGE_SIZE); + if (ret < 0) { + TEMP_SENSOR_ERR("get temp%u min threshold failed, ret: %d\n", temp_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t temp_sensor_min_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int temp_index; + int ret; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->set_main_board_temp_min); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + ret = g_temp_sensor_drv->set_main_board_temp_min(temp_index, buf, count); + if (ret < 0) { + TEMP_SENSOR_ERR("set temp%u min threshold failed, value: %s, count: %lu, ret: %d\n", + temp_index, buf, count, ret); + return -EIO; + } + TEMP_SENSOR_DBG("set temp%u min threshold success, value: %s, count: %lu, ret: %d\n", + temp_index, buf, count, ret); + return count; +} + +/************************************temp_sensor dir and attrs*******************************************/ +static struct switch_attribute num_temp_att = __ATTR(number, S_IRUGO, temp_sensor_number_show, NULL); + +static struct attribute *temp_sensor_dir_attrs[] = { + &num_temp_att.attr, + NULL, +}; + +static struct attribute_group temp_sensor_root_attr_group = { + .attrs = temp_sensor_dir_attrs, +}; + +/*******************************temp1 temp2 dir and attrs*******************************************/ +static struct switch_attribute temp_value_attr = __ATTR(value, S_IRUGO, temp_sensor_value_show, NULL); +static struct switch_attribute temp_alias_attr = __ATTR(alias, S_IRUGO, temp_sensor_alias_show, NULL); +static struct switch_attribute temp_type_attr = __ATTR(type, S_IRUGO, temp_sensor_type_show, NULL); +static struct switch_attribute temp_max_attr = __ATTR(max, S_IRUGO | S_IWUSR, temp_sensor_max_show, temp_sensor_max_store); +static struct switch_attribute temp_min_attr = __ATTR(min, S_IRUGO | S_IWUSR, temp_sensor_min_show, temp_sensor_min_store); + +static struct attribute *temp_sensor_attrs[] = { + &temp_value_attr.attr, + &temp_alias_attr.attr, + &temp_type_attr.attr, + &temp_max_attr.attr, + &temp_min_attr.attr, + NULL, +}; + +static struct attribute_group temp_sensor_attr_group = { + .attrs = temp_sensor_attrs, +}; + +static int temp_sensor_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[DIR_NAME_MAX_LEN]; + struct temp_sensor_obj_s *temp_sensor; + + temp_sensor = &g_temp_sensor.temp[index - 1]; + memset(name, 0, sizeof(name)); + snprintf(name, sizeof(name), "temp%u", index); + temp_sensor->obj = switch_kobject_create(name, parent); + if (!temp_sensor->obj) { + TEMP_SENSOR_ERR("create %s object error.\n", name); + return -ENOMEM; + } + temp_sensor->obj->index = index; + if (sysfs_create_group(&temp_sensor->obj->kobj, &temp_sensor_attr_group) != 0) { + TEMP_SENSOR_ERR("create %s attrs error.\n", name); + switch_kobject_delete(&temp_sensor->obj); + return -EBADRQC; + } + TEMP_SENSOR_DBG("create %s dir and attrs success.\n", name); + return 0; +} + +static void temp_sensor_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct temp_sensor_obj_s *temp_sensor; + + temp_sensor = &g_temp_sensor.temp[index - 1]; + if (temp_sensor->obj) { + sysfs_remove_group(&temp_sensor->obj->kobj, &temp_sensor_attr_group); + switch_kobject_delete(&temp_sensor->obj); + TEMP_SENSOR_DBG("delete temp%u dir and attrs success.\n", index); + } + + return; +} + +static int temp_sensor_sub_create_kobj_and_attrs(struct kobject *parent, int temp_num) +{ + unsigned int temp_index, i; + + g_temp_sensor.temp = kzalloc(sizeof(struct temp_sensor_obj_s) * temp_num, GFP_KERNEL); + if (!g_temp_sensor.temp) { + TEMP_SENSOR_ERR("kzalloc g_temp_sensor.temp error, temp number: %d.\n", temp_num); + return -ENOMEM; + } + + for (temp_index = 1; temp_index <= temp_num; temp_index++) { + if (temp_sensor_sub_single_create_kobj_and_attrs(parent, temp_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = temp_index; i > 0; i--) { + temp_sensor_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_temp_sensor.temp); + g_temp_sensor.temp = NULL; + return -EBADRQC; +} + +/* create temp[1-n] directory and attributes*/ +static int temp_sensor_sub_create(void) +{ + int ret; + + ret = temp_sensor_sub_create_kobj_and_attrs(&g_temp_sensor_obj->kobj, + g_temp_sensor.temp_number); + return ret; +} + +/* delete temp[1-n] directory and attributes*/ +static void temp_sensor_sub_remove(void) +{ + unsigned int temp_index; + + if (g_temp_sensor.temp) { + for (temp_index = g_temp_sensor.temp_number; temp_index > 0; temp_index--) { + temp_sensor_sub_single_remove_kobj_and_attrs(temp_index); + } + kfree(g_temp_sensor.temp); + g_temp_sensor.temp = NULL; + } + + return; +} + +/* create temp_sensor directory and number attributes */ +static int temp_sensor_root_create(void) +{ + g_temp_sensor_obj = switch_kobject_create("temp_sensor", NULL); + if (!g_temp_sensor_obj) { + TEMP_SENSOR_ERR("switch_kobject_create temp_sensor error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_temp_sensor_obj->kobj, &temp_sensor_root_attr_group) != 0) { + switch_kobject_delete(&g_temp_sensor_obj); + TEMP_SENSOR_ERR("create temp_sensor dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete temp_sensor directory and number attributes */ +static void temp_sensor_root_remove(void) +{ + if (g_temp_sensor_obj) { + sysfs_remove_group(&g_temp_sensor_obj->kobj, &temp_sensor_root_attr_group); + switch_kobject_delete(&g_temp_sensor_obj); + } + + return; +} + +int s3ip_sysfs_temp_sensor_drivers_register(struct s3ip_sysfs_temp_sensor_drivers_s *drv) +{ + int ret, temp_num; + + TEMP_SENSOR_INFO("s3ip_sysfs_temp_sensor_drivers_register...\n"); + if (g_temp_sensor_drv) { + TEMP_SENSOR_ERR("g_temp_sensor_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_main_board_temp_number); + g_temp_sensor_drv = drv; + + temp_num = g_temp_sensor_drv->get_main_board_temp_number(); + if (temp_num <= 0) { + TEMP_SENSOR_ERR("temp sensor number: %d, don't need to create temp_sensor dirs and attrs.\n", + temp_num); + return -EINVAL; + } + memset(&g_temp_sensor, 0, sizeof(struct temp_sensor_s)); + g_temp_sensor.temp_number = temp_num; + ret = temp_sensor_root_create(); + if (ret < 0) { + TEMP_SENSOR_ERR("create temp_sensor root dir and attrs failed, ret: %d\n", ret); + g_temp_sensor_drv = NULL; + return ret; + } + + ret = temp_sensor_sub_create(); + if (ret < 0) { + TEMP_SENSOR_ERR("create temp_sensor sub dir and attrs failed, ret: %d\n", ret); + temp_sensor_root_remove(); + g_temp_sensor_drv = NULL; + return ret; + } + TEMP_SENSOR_INFO("s3ip_sysfs_temp_sensor_drivers_register success\n"); + return ret; +} + +void s3ip_sysfs_temp_sensor_drivers_unregister(void) +{ + if (g_temp_sensor_drv) { + temp_sensor_sub_remove(); + temp_sensor_root_remove(); + g_temp_sensor_drv = NULL; + TEMP_SENSOR_DBG("s3ip_sysfs_temp_sensor_drivers_unregister success.\n"); + } + return; +} + + +EXPORT_SYMBOL(s3ip_sysfs_temp_sensor_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_temp_sensor_drivers_unregister); +module_param(g_temp_sensor_loglevel, int, 0644); +MODULE_PARM_DESC(g_temp_sensor_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/transceiver_sysfs.c b/platform/s3ip-sysfs/s3ip_sysfs_frame/transceiver_sysfs.c new file mode 100644 index 000000000000..02ad4d7a8688 --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/transceiver_sysfs.c @@ -0,0 +1,618 @@ +/* + * transceiver_sysfs.c + * + * This module create eth kobjects and attributes in /sys/s3ip/transceiver + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-08-31 S3IP sysfs + */ + +#include + +#include "switch.h" +#include "transceiver_sysfs.h" + +static int g_sff_loglevel = 0; + +#define SFF_INFO(fmt, args...) do { \ + if (g_sff_loglevel & INFO) { \ + printk(KERN_INFO "[SFF_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SFF_ERR(fmt, args...) do { \ + if (g_sff_loglevel & ERR) { \ + printk(KERN_ERR "[SFF_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SFF_DBG(fmt, args...) do { \ + if (g_sff_loglevel & DBG) { \ + printk(KERN_DEBUG "[SFF_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct sff_obj_s { + struct switch_obj *sff_obj; + struct bin_attribute bin; + int sff_creat_bin_flag; +}; + +struct sff_s { + unsigned int sff_number; + struct sff_obj_s *sff; +}; + +static struct sff_s g_sff; +static struct switch_obj *g_sff_obj = NULL; +static struct s3ip_sysfs_transceiver_drivers_s *g_sff_drv = NULL; + +static ssize_t transceiver_power_on_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + int ret; + + check_p(g_sff_drv); + check_p(g_sff_drv->get_transceiver_power_on_status); + + ret = g_sff_drv->get_transceiver_power_on_status(buf, PAGE_SIZE); + if (ret < 0) { + SFF_ERR("get transceiver power on status failed, ret: %d\n", ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t transceiver_power_on_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + int ret, value; + + check_p(g_sff_drv); + check_p(g_sff_drv->set_transceiver_power_on_status); + + sscanf(buf, "%d", &value); + if (value < 0 || value > 1) { + SFF_ERR("invalid value: %d, can't set transceiver power on status.\n", value); + return -EINVAL; + } + + ret = g_sff_drv->set_transceiver_power_on_status(value); + if (ret < 0) { + SFF_ERR("set transceiver power on status %d failed, ret: %d\n", value, ret); + return -EIO; + } + return count; +} + +static ssize_t eth_power_on_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eth_index; + int ret; + + check_p(g_sff_drv); + check_p(g_sff_drv->get_eth_power_on_status); + + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + ret = g_sff_drv->get_eth_power_on_status(eth_index, buf, PAGE_SIZE); + if (ret < 0) { + SFF_ERR("get eth%u power on status failed, ret: %d\n", eth_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t eth_power_on_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int eth_index; + int ret, value; + + check_p(g_sff_drv); + check_p(g_sff_drv->set_eth_power_on_status); + + sscanf(buf, "%d", &value); + eth_index = obj->index; + if (value < 0 || value > 1) { + SFF_ERR("invalid value: %d, can't set eth%u power on status.\n", value, eth_index); + return -EINVAL; + } + + ret = g_sff_drv->set_eth_power_on_status(eth_index, value); + if (ret < 0) { + SFF_ERR("set eth%u power on status %d failed, ret: %d\n", eth_index, value, ret); + return -EIO; + } + SFF_DBG("set eth%u power on status %d success\n", eth_index, value); + return count; +} + +static ssize_t eth_tx_fault_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eth_index; + int ret; + + check_p(g_sff_drv); + check_p(g_sff_drv->get_eth_tx_fault_status); + + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + ret = g_sff_drv->get_eth_tx_fault_status(eth_index, buf, PAGE_SIZE); + if (ret < 0) { + SFF_ERR("get eth%u tx fault status failed, ret: %d\n", eth_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t eth_tx_disable_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int eth_index; + int ret; + + check_p(g_sff_drv); + check_p(g_sff_drv->get_eth_tx_disable_status); + + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + ret = g_sff_drv->get_eth_tx_disable_status(eth_index, buf, PAGE_SIZE); + if (ret < 0) { + SFF_ERR("get eth%u tx disable status failed, ret: %d\n", eth_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t eth_tx_disable_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int eth_index; + int ret, value; + + check_p(g_sff_drv); + check_p(g_sff_drv->set_eth_tx_disable_status); + + sscanf(buf, "%d", &value); + eth_index = obj->index; + if (value < 0 || value > 1) { + SFF_ERR("invalid value: %d, can't set eth%u tx disable status.\n", value, eth_index); + return -EINVAL; + } + + ret = g_sff_drv->set_eth_tx_disable_status(eth_index, value); + if (ret < 0) { + SFF_ERR("set eth%u tx disable status %d failed, ret: %d\n", eth_index, value, ret); + return -EIO; + } + SFF_DBG("set eth%u tx disable status %d success\n", eth_index, value); + return count; +} + +static ssize_t eth_present_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eth_index; + int ret; + + check_p(g_sff_drv); + check_p(g_sff_drv->get_eth_present_status); + + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + ret = g_sff_drv->get_eth_present_status(eth_index, buf, PAGE_SIZE); + if (ret < 0) { + SFF_ERR("get eth%u present status failed, ret: %d\n", eth_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t eth_rx_los_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eth_index; + int ret; + + check_p(g_sff_drv); + check_p(g_sff_drv->get_eth_rx_los_status); + + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + ret = g_sff_drv->get_eth_rx_los_status(eth_index, buf, PAGE_SIZE); + if (ret < 0) { + SFF_ERR("get eth%u rx los status failed, ret: %d\n", eth_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t eth_reset_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eth_index; + int ret; + + check_p(g_sff_drv); + check_p(g_sff_drv->get_eth_reset_status); + + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + ret = g_sff_drv->get_eth_reset_status(eth_index, buf, PAGE_SIZE); + if (ret < 0) { + SFF_ERR("get eth%u reset status failed, ret: %d\n", eth_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t eth_reset_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int eth_index; + int ret, value; + + check_p(g_sff_drv); + check_p(g_sff_drv->set_eth_reset_status); + + sscanf(buf, "%d", &value); + eth_index = obj->index; + if (value < 0 || value > 1) { + SFF_ERR("invalid value: %d, can't set eth%u reset status.\n", value, eth_index); + return -EINVAL; + } + + ret = g_sff_drv->set_eth_reset_status(eth_index, value); + if (ret < 0) { + SFF_ERR("set eth%u reset status %d failed, ret: %d\n", eth_index, value, ret); + return -EIO; + } + SFF_DBG("set eth%u reset status %d success\n", eth_index, value); + return count; +} + +static ssize_t eth_low_power_mode_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eth_index; + int ret; + + check_p(g_sff_drv); + check_p(g_sff_drv->get_eth_low_power_mode_status); + + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + ret = g_sff_drv->get_eth_low_power_mode_status(eth_index, buf, PAGE_SIZE); + if (ret < 0) { + SFF_ERR("get eth%u low power mode status failed, ret: %d\n", eth_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t eth_interrupt_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eth_index; + int ret; + + check_p(g_sff_drv); + check_p(g_sff_drv->get_eth_interrupt_status); + + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + ret = g_sff_drv->get_eth_interrupt_status(eth_index, buf, PAGE_SIZE); + if (ret < 0) { + SFF_ERR("get eth%u interrupt status failed, ret: %d\n", eth_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t eth_eeprom_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t offset, size_t count) +{ + struct switch_obj *eth_obj; + ssize_t rd_len; + unsigned int eth_index; + + check_p(g_sff_drv); + check_p(g_sff_drv->read_eth_eeprom_data); + + eth_obj = to_switch_obj(kobj); + eth_index = eth_obj->index; + memset(buf, 0, count); + rd_len = g_sff_drv->read_eth_eeprom_data(eth_index, buf, offset, count); + if (rd_len < 0) { + SFF_ERR("read eth%u eeprom data error, offset: 0x%llx, read len: %lu, ret: %ld.\n", + eth_index, offset, count, rd_len); + return -EIO; + } + + SFF_DBG("read eth%u eeprom data success, offset:0x%llx, read len:%lu, really read len:%ld.\n", + eth_index, offset, count, rd_len); + + return rd_len; +} + +static ssize_t eth_eeprom_write(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t offset, size_t count) +{ + struct switch_obj *eth_obj; + ssize_t wr_len; + unsigned int eth_index; + + check_p(g_sff_drv); + check_p(g_sff_drv->write_eth_eeprom_data); + + eth_obj = to_switch_obj(kobj); + eth_index = eth_obj->index; + wr_len = g_sff_drv->write_eth_eeprom_data(eth_index, buf, offset, count); + if (wr_len < 0) { + SFF_ERR("write eth%u eeprom data error, offset: 0x%llx, read len: %lu, ret: %ld.\n", + eth_index, offset, count, wr_len); + return -EIO; + } + + SFF_DBG("write eth%u eeprom data success, offset:0x%llx, write len:%lu, really write len:%ld.\n", + eth_index, offset, count, wr_len); + + return wr_len; +} + +/************************************eth* signal attrs*******************************************/ +static struct switch_attribute eth_power_on_attr = __ATTR(power_on, S_IRUGO | S_IWUSR, eth_power_on_show, eth_power_on_store); +static struct switch_attribute eth_tx_fault_attr = __ATTR(tx_fault, S_IRUGO, eth_tx_fault_show, NULL); +static struct switch_attribute eth_tx_disable_attr = __ATTR(tx_disable, S_IRUGO | S_IWUSR, eth_tx_disable_show, eth_tx_disable_store); +static struct switch_attribute eth_present_attr = __ATTR(present, S_IRUGO, eth_present_show, NULL); +static struct switch_attribute eth_rx_los_attr = __ATTR(rx_los, S_IRUGO, eth_rx_los_show, NULL); +static struct switch_attribute eth_reset_attr = __ATTR(reset, S_IRUGO | S_IWUSR, eth_reset_show, eth_reset_store); +static struct switch_attribute eth_low_power_mode_attr = __ATTR(low_power_mode, S_IRUGO, eth_low_power_mode_show, NULL); +static struct switch_attribute eth_interrupt_attr = __ATTR(interrupt, S_IRUGO, eth_interrupt_show, NULL); + +static struct attribute *sff_signal_attrs[] = { + ð_power_on_attr.attr, + ð_tx_fault_attr.attr, + ð_tx_disable_attr.attr, + ð_present_attr.attr, + ð_rx_los_attr.attr, + ð_reset_attr.attr, + ð_low_power_mode_attr.attr, + ð_interrupt_attr.attr, + NULL, +}; + +static struct attribute_group sff_signal_attr_group = { + .attrs = sff_signal_attrs, +}; + +/*******************************transceiver dir and attrs*******************************************/ +static struct switch_attribute transceiver_power_on_attr = __ATTR(power_on, S_IRUGO | S_IWUSR, transceiver_power_on_show, transceiver_power_on_store); + +static struct attribute *transceiver_dir_attrs[] = { + &transceiver_power_on_attr.attr, + NULL, +}; + +static struct attribute_group sff_transceiver_attr_group = { + .attrs = transceiver_dir_attrs, +}; + +/* create eth* eeprom attributes */ +static int sff_sub_single_create_eeprom_attrs(unsigned int index) +{ + int ret, eeprom_size; + struct sff_obj_s *curr_sff; + + check_p(g_sff_drv->get_eth_eeprom_size); + eeprom_size = g_sff_drv->get_eth_eeprom_size(index); + if (eeprom_size <= 0) { + SFF_INFO("eth%u, eeprom_size: %d, don't need to creat eeprom attr.\n", + index, eeprom_size); + return 0; + } + + curr_sff = &g_sff.sff[index - 1]; + sysfs_bin_attr_init(&curr_sff->bin); + curr_sff->bin.attr.name = "eeprom"; + curr_sff->bin.attr.mode = 0644; + curr_sff->bin.read = eth_eeprom_read; + curr_sff->bin.write = eth_eeprom_write; + curr_sff->bin.size = eeprom_size; + + ret = sysfs_create_bin_file(&curr_sff->sff_obj->kobj, &curr_sff->bin); + if (ret) { + SFF_ERR("eth%u, create eeprom bin error, ret: %d. \n", index, ret); + return -EBADRQC; + } + + SFF_DBG("eth%u, create bin file success, eeprom size:%d.\n", index, eeprom_size); + curr_sff->sff_creat_bin_flag = 1; + return 0; +} + +static int sff_sub_single_create_kobj(struct kobject *parent, unsigned int index) +{ + struct sff_obj_s *curr_sff; + char sff_dir_name[DIR_NAME_MAX_LEN]; + + curr_sff = &g_sff.sff[index - 1]; + memset(sff_dir_name, 0, sizeof(sff_dir_name)); + snprintf(sff_dir_name, sizeof(sff_dir_name), "eth%d", index); + curr_sff->sff_obj = switch_kobject_create(sff_dir_name, parent); + if (!curr_sff->sff_obj) { + SFF_ERR("create eth%d object error! \n", index); + return -EBADRQC; + } + curr_sff->sff_obj->index = index; + if (sysfs_create_group(&curr_sff->sff_obj->kobj, &sff_signal_attr_group) != 0) { + switch_kobject_delete(&curr_sff->sff_obj); + return -EBADRQC; + } + + SFF_DBG("create eth%d dir and attrs success\n", index); + return 0; +} + +/* remove eth directory and attributes */ +static void sff_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct sff_obj_s *curr_sff; + + curr_sff = &g_sff.sff[index - 1]; + if (curr_sff->sff_obj) { + if (curr_sff->sff_creat_bin_flag) { + sysfs_remove_bin_file(&curr_sff->sff_obj->kobj, &curr_sff->bin); + curr_sff->sff_creat_bin_flag = 0; + } + sysfs_remove_group(&curr_sff->sff_obj->kobj, &sff_signal_attr_group); + switch_kobject_delete(&curr_sff->sff_obj); + } + + return; +} + +static int sff_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + int ret; + + ret = sff_sub_single_create_kobj(parent, index); + if (ret < 0) { + SFF_ERR("create eth%d dir error.\n", index); + return ret; + } + + sff_sub_single_create_eeprom_attrs(index); + return 0; +} + +static int sff_sub_create_kobj_and_attrs(struct kobject *parent, int sff_num) +{ + unsigned int sff_index, i; + + g_sff.sff = kzalloc(sizeof(struct sff_obj_s) * sff_num, GFP_KERNEL); + if (!g_sff.sff) { + SFF_ERR("kzalloc g_sff.sff error, sff number = %d.\n", sff_num); + return -ENOMEM; + } + + for (sff_index = 1; sff_index <= sff_num; sff_index++) { + if (sff_sub_single_create_kobj_and_attrs(parent, sff_index) != 0 ) { + goto error; + } + } + return 0; +error: + for (i = sff_index; i > 0; i--) { + sff_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_sff.sff); + g_sff.sff = NULL; + return -EBADRQC; +} + +/* create eth directory and attributes */ +static int sff_sub_create(void) +{ + int ret; + + ret = sff_sub_create_kobj_and_attrs(&g_sff_obj->kobj, g_sff.sff_number); + return ret; +} + +/* delete eth directory and attributes */ +static void sff_sub_remove(void) +{ + unsigned int sff_index; + + if (g_sff.sff) { + for (sff_index = g_sff.sff_number; sff_index > 0; sff_index--) { + sff_sub_single_remove_kobj_and_attrs(sff_index); + } + kfree(g_sff.sff); + g_sff.sff = NULL; + } + g_sff.sff_number = 0; + return; +} + +/* create transceiver directory and attributes */ +static int sff_transceiver_create(void) +{ + g_sff_obj = switch_kobject_create("transceiver", NULL); + if (!g_sff_obj) { + SFF_ERR("switch_kobject_create transceiver error!\n"); + return -ENOMEM; + } + g_sff_obj->index = 0; + if (sysfs_create_group(&g_sff_obj->kobj, &sff_transceiver_attr_group) != 0) { + switch_kobject_delete(&g_sff_obj); + SFF_ERR("create transceiver dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete transceiver directory and attributes */ +static void sff_transceiver_remove(void) +{ + if (g_sff_obj) { + sysfs_remove_group(&g_sff_obj->kobj, &sff_transceiver_attr_group); + switch_kobject_delete(&g_sff_obj); + } + + return; +} + +int s3ip_sysfs_sff_drivers_register(struct s3ip_sysfs_transceiver_drivers_s *drv) +{ + int ret, sff_num; + + SFF_INFO("s3ip_sysfs_sff_drivers_register...\n"); + if (g_sff_drv) { + SFF_ERR("g_sff_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_eth_number); + g_sff_drv = drv; + + sff_num = g_sff_drv->get_eth_number(); + if (sff_num <= 0) { + SFF_ERR("eth number: %d, don't need to create transceiver dirs and attrs.\n", sff_num); + g_sff_drv = NULL; + return -EINVAL; + } + + memset(&g_sff, 0, sizeof(struct sff_s)); + g_sff.sff_number = sff_num; + ret = sff_transceiver_create(); + if (ret < 0) { + SFF_ERR("create transceiver root dir and attrs failed, ret: %d\n", ret); + g_sff_drv = NULL; + return ret; + } + ret = sff_sub_create(); + if (ret < 0) { + SFF_ERR("create transceiver sub dir and attrs failed, ret: %d\n", ret); + sff_transceiver_remove(); + g_sff_drv = NULL; + return ret; + } + SFF_INFO("s3ip_sysfs_sff_drivers_register success\n"); + return ret; +} + +void s3ip_sysfs_sff_drivers_unregister(void) +{ + if (g_sff_drv) { + sff_sub_remove(); + sff_transceiver_remove(); + g_sff_drv = NULL; + SFF_DBG("s3ip_sysfs_sff_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_sff_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_sff_drivers_unregister); +module_param(g_sff_loglevel, int, 0644); +MODULE_PARM_DESC(g_sff_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/vol_sensor_sysfs.c b/platform/s3ip-sysfs/s3ip_sysfs_frame/vol_sensor_sysfs.c new file mode 100644 index 000000000000..41e21512f0de --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/vol_sensor_sysfs.c @@ -0,0 +1,434 @@ +/* + * vol_sensor_sysfs.c + * + * This module create vol sensor kobjects and attributes in /sys/s3ip/vol_sensor + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-08-31 S3IP sysfs + */ + +#include + +#include "switch.h" +#include "vol_sensor_sysfs.h" + +static int g_vol_sensor_loglevel = 0; + +#define VOL_SENSOR_INFO(fmt, args...) do { \ + if (g_vol_sensor_loglevel & INFO) { \ + printk(KERN_INFO "[VOL_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define VOL_SENSOR_ERR(fmt, args...) do { \ + if (g_vol_sensor_loglevel & ERR) { \ + printk(KERN_ERR "[VOL_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define VOL_SENSOR_DBG(fmt, args...) do { \ + if (g_vol_sensor_loglevel & DBG) { \ + printk(KERN_DEBUG "[VOL_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct vol_sensor_obj_s { + struct switch_obj *obj; +}; + +struct vol_sensor_s { + unsigned int vol_number; + struct vol_sensor_obj_s *vol; +}; + +static struct s3ip_sysfs_vol_sensor_drivers_s *g_vol_sensor_drv = NULL; +static struct vol_sensor_s g_vol_sensor; +static struct switch_obj *g_vol_sensor_obj = NULL; + +static ssize_t vol_sensor_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_vol_sensor.vol_number); +} + +static ssize_t vol_sensor_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int vol_index; + int ret; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->get_main_board_vol_value); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + ret = g_vol_sensor_drv->get_main_board_vol_value(vol_index, buf, PAGE_SIZE); + if (ret < 0) { + VOL_SENSOR_ERR("get vol%u value failed, ret: %d\n", vol_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t vol_sensor_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int vol_index; + int ret; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->get_main_board_vol_alias); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + ret = g_vol_sensor_drv->get_main_board_vol_alias(vol_index, buf, PAGE_SIZE); + if (ret < 0) { + VOL_SENSOR_ERR("get vol%u alias failed, ret: %d\n", vol_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t vol_sensor_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int vol_index; + int ret; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->get_main_board_vol_type); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + ret = g_vol_sensor_drv->get_main_board_vol_type(vol_index, buf, PAGE_SIZE); + if (ret < 0) { + VOL_SENSOR_ERR("get vol%u type failed, ret: %d\n", vol_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t vol_sensor_max_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int vol_index; + int ret; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->get_main_board_vol_max); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + ret = g_vol_sensor_drv->get_main_board_vol_max(vol_index, buf, PAGE_SIZE); + if (ret < 0) { + VOL_SENSOR_ERR("get vol%u max threshold failed, ret: %d\n", vol_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t vol_sensor_max_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int vol_index; + int ret; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->set_main_board_vol_max); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + ret = g_vol_sensor_drv->set_main_board_vol_max(vol_index, buf, count); + if (ret < 0) { + VOL_SENSOR_ERR("set vol%u max threshold failed, value: %s, count: %lu, ret: %d\n", + vol_index, buf, count, ret); + return -EIO; + } + VOL_SENSOR_DBG("set vol%u max threshold success, value: %s, count: %lu, ret: %d\n", + vol_index, buf, count, ret); + return count; +} + +static ssize_t vol_sensor_min_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int vol_index; + int ret; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->get_main_board_vol_min); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + ret = g_vol_sensor_drv->get_main_board_vol_min(vol_index, buf, PAGE_SIZE); + if (ret < 0) { + VOL_SENSOR_ERR("get vol%u min threshold failed, ret: %d\n", vol_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t vol_sensor_min_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int vol_index; + int ret; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->set_main_board_vol_min); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + ret = g_vol_sensor_drv->set_main_board_vol_min(vol_index, buf, count); + if (ret < 0) { + VOL_SENSOR_ERR("set vol%u min threshold failed, value: %s, count: %lu, ret: %d\n", + vol_index, buf, count, ret); + return -EIO; + } + VOL_SENSOR_DBG("set vol%u min threshold success, value: %s, count: %lu, ret: %d\n", + vol_index, buf, count, ret); + return count; +} + +static ssize_t vol_sensor_range_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int vol_index; + int ret; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->get_main_board_vol_range); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + ret = g_vol_sensor_drv->get_main_board_vol_range(vol_index, buf, PAGE_SIZE); + if (ret < 0) { + VOL_SENSOR_ERR("get vol%u range failed, ret: %d\n", vol_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +static ssize_t vol_sensor_nominal_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int vol_index; + int ret; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->get_main_board_vol_nominal_value); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + ret = g_vol_sensor_drv->get_main_board_vol_nominal_value(vol_index, buf, PAGE_SIZE); + if (ret < 0) { + VOL_SENSOR_ERR("get vol%u nominal value failed, ret: %d\n", vol_index, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + return ret; +} + +/************************************vol_sensor dir and attrs*******************************************/ +static struct switch_attribute num_vol_att = __ATTR(number, S_IRUGO, vol_sensor_number_show, NULL); + +static struct attribute *vol_sensor_dir_attrs[] = { + &num_vol_att.attr, + NULL, +}; + +static struct attribute_group vol_sensor_root_attr_group = { + .attrs = vol_sensor_dir_attrs, +}; + +/*******************************vol1 vol2 dir and attrs*******************************************/ +static struct switch_attribute vol_value_attr = __ATTR(value, S_IRUGO, vol_sensor_value_show, NULL); +static struct switch_attribute vol_alias_attr = __ATTR(alias, S_IRUGO, vol_sensor_alias_show, NULL); +static struct switch_attribute vol_type_attr = __ATTR(type, S_IRUGO, vol_sensor_type_show, NULL); +static struct switch_attribute vol_max_attr = __ATTR(max, S_IRUGO | S_IWUSR, vol_sensor_max_show, vol_sensor_max_store); +static struct switch_attribute vol_min_attr = __ATTR(min, S_IRUGO | S_IWUSR, vol_sensor_min_show, vol_sensor_min_store); +static struct switch_attribute vol_range_attr = __ATTR(range, S_IRUGO, vol_sensor_range_show, NULL); +static struct switch_attribute vol_nominal_value_attr = __ATTR(nominal_value, S_IRUGO, vol_sensor_nominal_value_show, NULL); + + +static struct attribute *vol_sensor_attrs[] = { + &vol_value_attr.attr, + &vol_alias_attr.attr, + &vol_type_attr.attr, + &vol_max_attr.attr, + &vol_min_attr.attr, + &vol_range_attr.attr, + &vol_nominal_value_attr.attr, + NULL, +}; + +static struct attribute_group vol_sensor_attr_group = { + .attrs = vol_sensor_attrs, +}; + +static int vol_sensor_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[DIR_NAME_MAX_LEN]; + struct vol_sensor_obj_s *vol_sensor; + + vol_sensor = &g_vol_sensor.vol[index - 1]; + memset(name, 0, sizeof(name)); + snprintf(name, sizeof(name), "vol%u", index); + vol_sensor->obj = switch_kobject_create(name, parent); + if (!vol_sensor->obj) { + VOL_SENSOR_ERR("create %s object error.\n", name); + return -ENOMEM; + } + + vol_sensor->obj->index = index; + if (sysfs_create_group(&vol_sensor->obj->kobj, &vol_sensor_attr_group) != 0) { + VOL_SENSOR_ERR("create %s attrs error.\n", name); + switch_kobject_delete(&vol_sensor->obj); + return -EBADRQC; + } + VOL_SENSOR_DBG("create %s dir and attrs success.\n", name); + + return 0; +} + +static void vol_sensor_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct vol_sensor_obj_s *vol_sensor; + + vol_sensor = &g_vol_sensor.vol[index - 1]; + if (vol_sensor->obj) { + sysfs_remove_group(&vol_sensor->obj->kobj, &vol_sensor_attr_group); + switch_kobject_delete(&vol_sensor->obj); + VOL_SENSOR_DBG("delete vol%u dir and attrs success.\n", index); + } + + return; +} + +static int vol_sensor_sub_create_kobj_and_attrs(struct kobject *parent, int vol_num) +{ + unsigned int vol_index, i; + + g_vol_sensor.vol = kzalloc(sizeof(struct vol_sensor_obj_s) * vol_num, GFP_KERNEL); + if (!g_vol_sensor.vol) { + VOL_SENSOR_ERR("kzalloc g_vol_sensor.vol error, vol number: %d.\n", vol_num); + return -ENOMEM; + } + + for (vol_index = 1; vol_index <= vol_num; vol_index++) { + if (vol_sensor_sub_single_create_kobj_and_attrs(parent, vol_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = vol_index; i > 0; i--) { + vol_sensor_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_vol_sensor.vol); + g_vol_sensor.vol = NULL; + return -EBADRQC; +} + +/* create vol[1-n] directory and attributes*/ +static int vol_sensor_sub_create(void) +{ + int ret; + + ret = vol_sensor_sub_create_kobj_and_attrs(&g_vol_sensor_obj->kobj, g_vol_sensor.vol_number); + return ret; +} + +/* delete vol[1-n] directory and attributes*/ +static void vol_sensor_sub_remove(void) +{ + unsigned int vol_index; + + if (g_vol_sensor.vol) { + for (vol_index = g_vol_sensor.vol_number; vol_index > 0; vol_index--) { + vol_sensor_sub_single_remove_kobj_and_attrs(vol_index); + } + kfree(g_vol_sensor.vol); + g_vol_sensor.vol = NULL; + } + + return; +} + +/* create vol_sensor directory and number attributes */ +static int vol_sensor_root_create(void) +{ + g_vol_sensor_obj = switch_kobject_create("vol_sensor", NULL); + if (!g_vol_sensor_obj) { + VOL_SENSOR_ERR("switch_kobject_create vol_sensor error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_vol_sensor_obj->kobj, &vol_sensor_root_attr_group) != 0) { + switch_kobject_delete(&g_vol_sensor_obj); + VOL_SENSOR_ERR("create vol_sensor dir attrs error!\n"); + return -EBADRQC; + } + + return 0; +} + +/* delete vol_sensor directory and number attributes */ +static void vol_sensor_root_remove(void) +{ + if (g_vol_sensor_obj) { + sysfs_remove_group(&g_vol_sensor_obj->kobj, &vol_sensor_root_attr_group); + switch_kobject_delete(&g_vol_sensor_obj); + } + + return; +} + +int s3ip_sysfs_vol_sensor_drivers_register(struct s3ip_sysfs_vol_sensor_drivers_s *drv) +{ + int ret, vol_num; + + VOL_SENSOR_INFO("s3ip_sysfs_vol_sensor_drivers_register...\n"); + if (g_vol_sensor_drv) { + VOL_SENSOR_ERR("g_vol_sensor_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_main_board_vol_number); + g_vol_sensor_drv = drv; + + vol_num = g_vol_sensor_drv->get_main_board_vol_number(); + if (vol_num <= 0) { + VOL_SENSOR_ERR("vol sensor number: %d, don't need to create vol_sensor dirs and attrs.\n", + vol_num); + return -EINVAL; + } + memset(&g_vol_sensor, 0, sizeof(struct vol_sensor_s)); + g_vol_sensor.vol_number = vol_num; + ret = vol_sensor_root_create(); + if (ret < 0) { + VOL_SENSOR_ERR("create vol_sensor root dir and attrs failed, ret: %d\n", ret); + g_vol_sensor_drv = NULL; + return ret; + } + + ret = vol_sensor_sub_create(); + if (ret < 0) { + VOL_SENSOR_ERR("create vol_sensor sub dir and attrs failed, ret: %d\n", ret); + vol_sensor_root_remove(); + g_vol_sensor_drv = NULL; + return ret; + } + VOL_SENSOR_INFO("s3ip_sysfs_vol_sensor_drivers_register success\n"); + return ret; +} + +void s3ip_sysfs_vol_sensor_drivers_unregister(void) +{ + if (g_vol_sensor_drv) { + vol_sensor_sub_remove(); + vol_sensor_root_remove(); + g_vol_sensor_drv = NULL; + VOL_SENSOR_DBG("s3ip_sysfs_vol_sensor_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_vol_sensor_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_vol_sensor_drivers_unregister); +module_param(g_vol_sensor_loglevel, int, 0644); +MODULE_PARM_DESC(g_vol_sensor_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/s3ip-sysfs/s3ip_sysfs_frame/watchdog_sysfs.c b/platform/s3ip-sysfs/s3ip_sysfs_frame/watchdog_sysfs.c new file mode 100755 index 000000000000..4487d5d19ac7 --- /dev/null +++ b/platform/s3ip-sysfs/s3ip_sysfs_frame/watchdog_sysfs.c @@ -0,0 +1,263 @@ +/* + * watchdog_sysfs.c + * + * This module create watchdog kobjects and attributes in /sys/s3ip/watchdog + * + * History + * [Version] [Date] [Description] + * * v1.0 2021-08-31 S3IP sysfs + */ + +#include + +#include "switch.h" +#include "watchdog_sysfs.h" + +static int g_wdt_loglevel = 0; + +#define WDT_INFO(fmt, args...) do { \ + if (g_wdt_loglevel & INFO) { \ + printk(KERN_INFO "[WDT_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WDT_ERR(fmt, args...) do { \ + if (g_wdt_loglevel & ERR) { \ + printk(KERN_ERR "[WDT_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WDT_DBG(fmt, args...) do { \ + if (g_wdt_loglevel & DBG) { \ + printk(KERN_DEBUG "[WDT_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +typedef enum wdt_enable_status_e { + WDT_DISENABLE = 0, /* close watchdog */ + WDT_ENABLE = 1, /* open watchdog */ +} wdt_enable_status_t; + +static struct switch_obj *g_watchdog_obj = NULL; +static struct s3ip_sysfs_watchdog_drivers_s *g_wdt_drv = NULL; + +static ssize_t watchdog_identify_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + int ret; + + check_p(g_wdt_drv); + check_p(g_wdt_drv->get_watchdog_identify); + + ret = g_wdt_drv->get_watchdog_identify(buf, PAGE_SIZE); + if (ret < 0) { + WDT_ERR("get watchdog identify failed, ret: %d\n", ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + WDT_DBG("get watchdog identify success\n"); + return ret; +} + +static ssize_t watchdog_timeleft_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + int ret; + + check_p(g_wdt_drv); + check_p(g_wdt_drv->get_watchdog_timeleft); + + ret = g_wdt_drv->get_watchdog_timeleft(buf, PAGE_SIZE); + if (ret < 0) { + WDT_ERR("get watchdog timeleft failed, ret: %d\n", ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + WDT_DBG("get watchdog timeleft success\n"); + return ret; +} + +static ssize_t watchdog_timeout_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + int ret; + + check_p(g_wdt_drv); + check_p(g_wdt_drv->get_watchdog_timeout); + + ret = g_wdt_drv->get_watchdog_timeout(buf, PAGE_SIZE); + if (ret < 0) { + WDT_ERR("get watchdog timeout failed, ret: %d\n", ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + WDT_DBG("get watchdog timeout success\n"); + return ret; +} + +static ssize_t watchdog_timeout_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + int ret, value; + + check_p(g_wdt_drv); + check_p(g_wdt_drv->set_watchdog_timeout); + + sscanf(buf, "%d", &value); + if (value < 0) { + WDT_ERR("invaild timeout value: %d, can't set watchdog timeout\n", value); + return -EINVAL; + } + + ret = g_wdt_drv->set_watchdog_timeout(value); + if (ret < 0) { + WDT_ERR("set watchdog timeout value: %d failed, ret: %d\n", value, ret); + return -EIO; + } + WDT_DBG("set watchdog timeout value: %d success\n", ret); + return count; +} + +static ssize_t watchdog_enable_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + int ret; + + check_p(g_wdt_drv); + check_p(g_wdt_drv->get_watchdog_enable_status); + + ret = g_wdt_drv->get_watchdog_enable_status(buf, PAGE_SIZE); + if (ret < 0) { + WDT_ERR("get watchdog enable status failed, ret: %d\n", ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SYSFS_DEV_ERROR); + } + WDT_DBG("get watchdog enable status success\n"); + return ret; +} + +static ssize_t watchdog_enable_status_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + int ret, value; + + check_p(g_wdt_drv); + check_p(g_wdt_drv->set_watchdog_enable_status); + + sscanf(buf, "%d", &value); + if ((value != WDT_DISENABLE) && (value != WDT_ENABLE)) { + WDT_ERR("invaild enable value: %d, can't set watchdog enable status\n", value); + return -EINVAL; + } + + ret = g_wdt_drv->set_watchdog_enable_status(value); + if (ret < 0) { + WDT_ERR("set watchdog enable status %d failed, ret: %d\n", value, ret); + return -EIO; + } + WDT_DBG("set watchdog enable status %d success\n", ret); + return count; +} + +static ssize_t watchdog_reset_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + int ret, value; + + check_p(g_wdt_drv); + check_p(g_wdt_drv->set_watchdog_reset); + + ret = kstrtoint(buf, 0, &value); + if (ret) { + WDT_ERR("invalid value: %s \n", buf); + return -EINVAL; + } + + ret = g_wdt_drv->set_watchdog_reset(value); + if (ret < 0) { + WDT_ERR("set watchdog reset %d failed, ret: %d\n", value, ret); + return -EIO; + } + WDT_DBG("set watchdog reset %d success\n", ret); + return count; +} + +/************************************watchdog*******************************************/ +static struct switch_attribute watchdog_identify_attr = __ATTR(identify, S_IRUGO, watchdog_identify_show, NULL); +static struct switch_attribute watchdog_timeleft_attr = __ATTR(timeleft, S_IRUGO, watchdog_timeleft_show, NULL); +static struct switch_attribute watchdog_timeout_attr = __ATTR(timeout, S_IRUGO | S_IWUSR, watchdog_timeout_show, watchdog_timeout_store); +static struct switch_attribute watchdog_enable_attr = __ATTR(enable, S_IRUGO | S_IWUSR, watchdog_enable_status_show, watchdog_enable_status_store); +static struct switch_attribute watchdog_reset_attr = __ATTR(reset, S_IWUSR, NULL, watchdog_reset_store); + +static struct attribute *watchdog_dir_attrs[] = { + &watchdog_identify_attr.attr, + &watchdog_timeleft_attr.attr, + &watchdog_timeout_attr.attr, + &watchdog_enable_attr.attr, + &watchdog_reset_attr.attr, + NULL, +}; + +static struct attribute_group watchdog_attr_group = { + .attrs = watchdog_dir_attrs, +}; + +/* create watchdog directory and attributes */ +static int watchdog_root_create(void) +{ + g_watchdog_obj = switch_kobject_create("watchdog", NULL); + if (!g_watchdog_obj) { + WDT_ERR("switch_kobject_create watchdog error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_watchdog_obj->kobj, &watchdog_attr_group) != 0) { + switch_kobject_delete(&g_watchdog_obj); + WDT_ERR("create fan dir attrs error!\n"); + return -EBADRQC; + } + + return 0; +} + +/* delete watchdog directory and attributes */ +static void watchdog_root_remove(void) +{ + if (g_watchdog_obj) { + sysfs_remove_group(&g_watchdog_obj->kobj, &watchdog_attr_group); + switch_kobject_delete(&g_watchdog_obj); + } + + return; +} + +int s3ip_sysfs_watchdog_drivers_register(struct s3ip_sysfs_watchdog_drivers_s *drv) +{ + int ret; + + WDT_INFO("s3ip_sysfs_watchdog_drivers_register...\n"); + if (g_wdt_drv) { + WDT_ERR("g_wdt_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + g_wdt_drv = drv; + + ret = watchdog_root_create(); + if (ret < 0) { + WDT_ERR("watchdog create error.\n"); + g_wdt_drv = NULL; + return ret; + } + WDT_INFO("s3ip_sysfs_watchdog_drivers_register success\n"); + return 0; +} + +void s3ip_sysfs_watchdog_drivers_unregister(void) +{ + if (g_wdt_drv) { + watchdog_root_remove(); + g_wdt_drv = NULL; + WDT_DBG("s3ip_sysfs_watchdog_drivers_unregister success.\n"); + } + + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_watchdog_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_watchdog_drivers_unregister); +module_param(g_wdt_loglevel, int, 0644); +MODULE_PARM_DESC(g_wdt_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/s3ip-sysfs/scripts/s3ip-sysfs.service b/platform/s3ip-sysfs/scripts/s3ip-sysfs.service new file mode 100644 index 000000000000..2446df59d7a5 --- /dev/null +++ b/platform/s3ip-sysfs/scripts/s3ip-sysfs.service @@ -0,0 +1,15 @@ +[Unit] +Description=s3ip sysfs service +Wants=network-online.target +After=network-online.target + +[Service] +Type=oneshot +User=root +ExecStart=/usr/bin/s3ip_sysfs_tool.sh start +ExecStop=/usr/bin/s3ip_sysfs_tool.sh stop +RemainAfterExit=yes + +[Install] +WantedBy=default.target + diff --git a/platform/s3ip-sysfs/scripts/s3ip_load.py b/platform/s3ip-sysfs/scripts/s3ip_load.py new file mode 100755 index 000000000000..38ae5fb000a6 --- /dev/null +++ b/platform/s3ip-sysfs/scripts/s3ip_load.py @@ -0,0 +1,32 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- +import json +import os + +if __name__ == '__main__': + os.system("sudo rm -rf /sys_switch;sudo mkdir -p -m 777 /sys_switch") + + with open('/etc/s3ip/s3ip_sysfs_conf.json', 'r') as jsonfile: + json_string = json.load(jsonfile) + for s3ip_sysfs_path in json_string['s3ip_syfs_paths']: + #print('path:' + s3ip_sysfs_path['path']) + #print('type:' + s3ip_sysfs_path['type']) + #print('value:' + s3ip_sysfs_path['value']) + + if s3ip_sysfs_path['type'] == "string" : + (path, file) = os.path.split(s3ip_sysfs_path['path']) + #创建文件 + command = "sudo mkdir -p -m 777 " + path + #print(command) + os.system(command) + command = "sudo echo " + "\"" + s3ip_sysfs_path['value'] + "\"" + " > " + s3ip_sysfs_path['path'] + #print(command) + os.system(command) + elif s3ip_sysfs_path['type'] == "path" : + command = "sudo ln -s " + s3ip_sysfs_path['value'] + " " + s3ip_sysfs_path['path'] + #print(command) + os.system(command) + else: + print('error type:' + s3ip_sysfs_path['type']) + os.system("tree -l /sys_switch") + diff --git a/platform/s3ip-sysfs/scripts/s3ip_sysfs_conf.json b/platform/s3ip-sysfs/scripts/s3ip_sysfs_conf.json new file mode 100755 index 000000000000..8b24957c982c --- /dev/null +++ b/platform/s3ip-sysfs/scripts/s3ip_sysfs_conf.json @@ -0,0 +1,76 @@ +{ + "s3ip_syfs_paths": [ + { + "path": "/sys_switch/temp_sensor", + "type" : "path", + "value" : "/sys/s3ip/temp_sensor", + "description": "温度传感器信息" + }, + { + "path": "/sys_switch/vol_sensor", + "type" : "path", + "value" : "/sys/s3ip/vol_sensor", + "description": "电压传感器信息" + }, + { + "path": "/sys_switch/syseeprom", + "type" : "path", + "value" : "/sys/s3ip/syseeprom", + "description": "ONIE EEPROM" + }, + { + "path": "/sys_switch/fan", + "type" : "path", + "value" : "/sys/s3ip/fan", + "description": "风扇信息" + }, + { + "path": "/sys_switch/psu", + "type" : "path", + "value" : "/sys/s3ip/psu", + "description": "电源信息" + }, + { + "path": "/sys_switch/transceiver", + "type" : "path", + "value" : "/sys/s3ip/transceiver", + "description": "光模块信息" + }, + { + "path": "/sys_switch/sysled", + "type" : "path", + "value" : "/sys/s3ip/sysled", + "description": "指示灯信息" + }, + { + "path": "/sys_switch/fpga", + "type" : "path", + "value" : "/sys/s3ip/fpga", + "description": "FPGA信息" + }, + { + "path": "/sys_switch/cpld", + "type" : "path", + "value" : "/sys/s3ip/cpld", + "description": "CPLD信息" + }, + { + "path": "/sys_switch/watchdog", + "type" : "path", + "value" : "/sys/s3ip/watchdog", + "description": "看门狗信息" + }, + { + "path": "/sys_switch/curr_sensor", + "type" : "path", + "value" : "/sys/s3ip/curr_sensor", + "description": "电流传感器信息" + }, + { + "path": "/sys_switch/slot", + "type" : "path", + "value" : "/sys/s3ip/slot", + "description": "子卡信息" + } + ] +} diff --git a/platform/s3ip-sysfs/scripts/s3ip_sysfs_tool.sh b/platform/s3ip-sysfs/scripts/s3ip_sysfs_tool.sh new file mode 100755 index 000000000000..ed65f0d1d9e8 --- /dev/null +++ b/platform/s3ip-sysfs/scripts/s3ip_sysfs_tool.sh @@ -0,0 +1,59 @@ +#! /bin/bash + +s3ip_start(){ + sudo insmod /lib/modules/s3ip/s3ip_sysfs.ko + sudo insmod /lib/modules/s3ip/syseeprom_device_driver.ko + sudo insmod /lib/modules/s3ip/fan_device_driver.ko + sudo insmod /lib/modules/s3ip/cpld_device_driver.ko + sudo insmod /lib/modules/s3ip/sysled_device_driver.ko + sudo insmod /lib/modules/s3ip/psu_device_driver.ko + sudo insmod /lib/modules/s3ip/transceiver_device_driver.ko + sudo insmod /lib/modules/s3ip/temp_sensor_device_driver.ko + sudo insmod /lib/modules/s3ip/vol_sensor_device_driver.ko + sudo insmod /lib/modules/s3ip/fpga_device_driver.ko + sudo insmod /lib/modules/s3ip/watchdog_device_driver.ko + sudo insmod /lib/modules/s3ip/curr_sensor_device_driver.ko + sudo insmod /lib/modules/s3ip/slot_device_driver.ko + sudo rm -rf /sys_switch + sudo /usr/bin/s3ip_load.py + echo "s3ip service start" +} +s3ip_stop(){ + sudo rmmod slot_device_driver + sudo rmmod curr_sensor_device_driver + sudo rmmod watchdog_device_driver + sudo rmmod fpga_device_driver + sudo rmmod vol_sensor_device_driver + sudo rmmod temp_sensor_device_driver + sudo rmmod transceiver_device_driver + sudo rmmod psu_device_driver + sudo rmmod sysled_device_driver + sudo rmmod cpld_device_driver + sudo rmmod fan_device_driver + sudo rmmod syseeprom_device_driver + sudo rmmod s3ip_sysfs + sudo rm -rf /sys_switch + echo "s3ip service stop" + +} + +case "$1" in + start) + s3ip_start + ;; + stop) + s3ip_stop + ;; + status) + sudo tree -l /sys_switch + ;; + restart) + s3ip_stop + s3ip_start + ;; + *) + echo "Usage: $0 {start|stop|status|restart}" + exit 1 +esac +exit +