mirror of
				https://github.com/Telecominfraproject/ols-nos.git
				synced 2025-11-04 03:57:57 +00:00 
			
		
		
		
	The slot and switch_rootsysfs driver framework module complies with s3ip sysfs specification (#12893)
Why I did it Provide slot and switch_rootsysfs driver framework that complies with s3ip sysfs specification How I did it 1、 The framework module provides register and unregister interface and implementation. 2、 The framework will help you create the sysfs node How to verify it A demo driver base on this framework will display the sysfs node wich conform to the s3ip sysfs specification
This commit is contained in:
		
							
								
								
									
										57
									
								
								platform/s3ip-sysfs/s3ip_sysfs_frame/include/slot_sysfs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								platform/s3ip-sysfs/s3ip_sysfs_frame/include/slot_sysfs.h
									
									
									
									
									
										Normal file
									
								
							@@ -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_ */
 | 
				
			||||||
							
								
								
									
										68
									
								
								platform/s3ip-sysfs/s3ip_sysfs_frame/include/switch.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								platform/s3ip-sysfs/s3ip_sysfs_frame/include/switch.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
				
			|||||||
 | 
					#ifndef _SWITCH_H_
 | 
				
			||||||
 | 
					#define _SWITCH_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <linux/module.h>
 | 
				
			||||||
 | 
					#include <linux/kernel.h>
 | 
				
			||||||
 | 
					#include <linux/sysfs.h>
 | 
				
			||||||
 | 
					#include <linux/slab.h>
 | 
				
			||||||
 | 
					#include <linux/device.h>
 | 
				
			||||||
 | 
					#include <linux/workqueue.h>
 | 
				
			||||||
 | 
					#include <linux/kobject.h>
 | 
				
			||||||
 | 
					#include <linux/delay.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#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_ */
 | 
				
			||||||
@@ -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_ */
 | 
				
			||||||
							
								
								
									
										2099
									
								
								platform/s3ip-sysfs/s3ip_sysfs_frame/slot_sysfs.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2099
									
								
								platform/s3ip-sysfs/s3ip_sysfs_frame/slot_sysfs.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										270
									
								
								platform/s3ip-sysfs/s3ip_sysfs_frame/switch.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										270
									
								
								platform/s3ip-sysfs/s3ip_sysfs_frame/switch.c
									
									
									
									
									
										Normal file
									
								
							@@ -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");
 | 
				
			||||||
		Reference in New Issue
	
	Block a user