⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtas-proc.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
}/* ****************************************************************** */int ppc_rtas_find_all_sensors (void){	unsigned int *utmp;	int len, i;	utmp = (unsigned int *) get_property(rtas_node, "rtas-sensors", &len);	if (utmp == NULL) {		printk (KERN_ERR "error: could not get rtas-sensors\n");		return 1;	}	sensors.quant = len / 8;      /* int + int */	for (i=0; i<sensors.quant; i++) {		sensors.sensor[i].token = *utmp++;		sensors.sensor[i].quant = *utmp++;	}	return 0;}/* ****************************************************************** *//* * Builds a string of what rtas returned */char * ppc_rtas_process_error(int error){	switch (error) {		case SENSOR_CRITICAL_HIGH:			return "(critical high)";		case SENSOR_WARNING_HIGH:			return "(warning high)";		case SENSOR_NORMAL:			return "(normal)";		case SENSOR_WARNING_LOW:			return "(warning low)";		case SENSOR_CRITICAL_LOW:			return "(critical low)";		case SENSOR_SUCCESS:			return "(read ok)";		case SENSOR_HW_ERROR:			return "(hardware error)";		case SENSOR_BUSY:			return "(busy)";		case SENSOR_NOT_EXIST:			return "(non existant)";		case SENSOR_DR_ENTITY:			return "(dr entity removed)";		default:			return "(UNKNOWN)";	}}/* ****************************************************************** *//* * Builds a string out of what the sensor said */int ppc_rtas_process_sensor(struct individual_sensor s, int state, 		int error, char * buf) {	/* Defined return vales */	const char * key_switch[]        = { "Off", "Normal", "Secure", "Maintenance" };	const char * enclosure_switch[]  = { "Closed", "Open" };	const char * lid_status[]        = { " ", "Open", "Closed" };	const char * power_source[]      = { "AC", "Battery", "AC & Battery" };	const char * battery_remaining[] = { "Very Low", "Low", "Mid", "High" };	const char * epow_sensor[]       = { 		"EPOW Reset", "Cooling warning", "Power warning",		"System shutdown", "System halt", "EPOW main enclosure",		"EPOW power off" };	const char * battery_cyclestate[]  = { "None", "In progress", "Requested" };	const char * battery_charging[]    = { "Charging", "Discharching", "No current flow" };	const char * ibm_drconnector[]     = { "Empty", "Present" };	const char * ibm_intqueue[]        = { "Disabled", "Enabled" };	int temperature = 0;	int unknown = 0;	int n = 0;	char *label_string = NULL;	const char **value_arr = NULL;	int value_arrsize = 0;	/* What kind of sensor do we have here? */		switch (s.token) {		case KEY_SWITCH:			label_string = "Key switch:";			value_arrsize = sizeof(key_switch)/sizeof(char *);			value_arr = key_switch;			break;		case ENCLOSURE_SWITCH:			label_string = "Enclosure switch:";			value_arrsize = sizeof(enclosure_switch)/sizeof(char *);			value_arr = enclosure_switch;			break;		case THERMAL_SENSOR:			label_string = "Temp. (癈/癋):";			temperature = 1;			break;		case LID_STATUS:			label_string = "Lid status:";			value_arrsize = sizeof(lid_status)/sizeof(char *);			value_arr = lid_status;			break;		case POWER_SOURCE:			label_string = "Power source:";			value_arrsize = sizeof(power_source)/sizeof(char *);			value_arr = power_source;			break;		case BATTERY_VOLTAGE:			label_string = "Battery voltage:";			break;		case BATTERY_REMAINING:			label_string = "Battery remaining:";			value_arrsize = sizeof(battery_remaining)/sizeof(char *);			value_arr = battery_remaining;			break;		case BATTERY_PERCENTAGE:			label_string = "Battery percentage:";			break;		case EPOW_SENSOR:			label_string = "EPOW Sensor:";			value_arrsize = sizeof(epow_sensor)/sizeof(char *);			value_arr = epow_sensor;			break;		case BATTERY_CYCLESTATE:			label_string = "Battery cyclestate:";			value_arrsize = sizeof(battery_cyclestate)/sizeof(char *);			value_arr = battery_cyclestate;			break;		case BATTERY_CHARGING:			label_string = "Battery Charging:";			value_arrsize = sizeof(battery_charging)/sizeof(char *);			value_arr = battery_charging;			break;		case IBM_SURVEILLANCE:			label_string = "Surveillance:";			break;		case IBM_FANRPM:			label_string = "Fan (rpm):";			break;		case IBM_VOLTAGE:			label_string = "Voltage (mv):";			break;		case IBM_DRCONNECTOR:			label_string = "DR connector:";			value_arrsize = sizeof(ibm_drconnector)/sizeof(char *);			value_arr = ibm_drconnector;			break;		case IBM_POWERSUPPLY:			label_string = "Powersupply:";			break;		case IBM_INTQUEUE:			label_string = "Interrupt queue:";			value_arrsize = sizeof(ibm_intqueue)/sizeof(char *);			value_arr = ibm_intqueue;			break;		default:			n += sprintf(buf+n,  "Unkown sensor (type %d), ignoring it\n",					s.token);			unknown = 1;			break;	}	if (label_string)		n += sprintf(buf+n, "%-17s\t", label_string);	if (value_arr && state >= 0 && state < value_arrsize) {		n += sprintf(buf+n, "%-15s\t", value_arr[state]);	} else {		if (temperature) {			n += sprintf(buf+n, "%2d / %2d  \t", state, cel_to_fahr(state));		} else			n += sprintf(buf+n, "%-10d\t", state);	}	if (unknown == 0) {		n += sprintf ( buf+n, "%-15s\t", ppc_rtas_process_error(error));		n += get_location_code(s, buf+n);	}	return n;}/* ****************************************************************** */int check_location (char *c, int idx, char * buf){	int n = 0;	switch (*(c+idx)) {		case LOC_PLANAR:			n += sprintf ( buf, "Planar #%c", *(c+idx+1));			break;		case LOC_CPU:			n += sprintf ( buf, "CPU #%c", *(c+idx+1));			break;		case LOC_FAN:			n += sprintf ( buf, "Fan #%c", *(c+idx+1));			break;		case LOC_RACKMOUNTED:			n += sprintf ( buf, "Rack #%c", *(c+idx+1));			break;		case LOC_VOLTAGE:			n += sprintf ( buf, "Voltage #%c", *(c+idx+1));			break;		case LOC_LCD:			n += sprintf ( buf, "LCD #%c", *(c+idx+1));			break;		case '.':			n += sprintf ( buf, "- %c", *(c+idx+1));		default:			n += sprintf ( buf, "Unknown location");			break;	}	return n;}/* ****************************************************************** *//*  * Format:  * ${LETTER}${NUMBER}[[-/]${LETTER}${NUMBER} [ ... ] ] * the '.' may be an abbrevation */int check_location_string (char *c, char *buf){	int n=0,i=0;	while (c[i]) {		if (isalpha(c[i]) || c[i] == '.') {			 n += check_location(c, i, buf+n);		}		else if (c[i] == '/' || c[i] == '-')			n += sprintf(buf+n, " at ");		i++;	}	return n;}/* ****************************************************************** */int get_location_code(struct individual_sensor s, char * buffer){	char rstr[512], tmp[10], tmp2[10];	int n=0, i=0, llen, len;	/* char *buf = kmalloc(MAX_LINELENGTH, GFP_KERNEL); */	char *ret;	static int pos = 0; /* remember position where buffer was */	/* construct the sensor number like 0003 */	/* fill with zeros */	n = sprintf(tmp, "%d", s.token);	len = strlen(tmp);	while (strlen(tmp) < 4)		n += sprintf (tmp+n, "0");		/* invert the string */	while (tmp[i]) {		if (i<len)			tmp2[4-len+i] = tmp[i];		else			tmp2[3-i] = tmp[i];		i++;	}	tmp2[4] = '\0';	sprintf (rstr, SENSOR_PREFIX"%s", tmp2);	ret = (char *) get_property(rtas_node, rstr, &llen);	n=0;	if (ret == NULL || ret[0] == '\0') {		n += sprintf ( buffer+n, "--- ");/* does not have a location */	} else {		char t[50];		ret += pos;		n += check_location_string(ret, buffer + n);		n += sprintf ( buffer+n, " ");		/* see how many characters we have printed */		snprintf( t, 50, "%s ", ret);		pos += strlen(t);		if (pos >= llen) pos=0;	}	return n;}/* ****************************************************************** *//* INDICATORS - Tone Frequency                                        *//* ****************************************************************** */static ssize_t ppc_rtas_tone_freq_write(struct file * file, const char * buf,		size_t count, loff_t *ppos){	char stkbuf[40];  /* its small, its on stack */	unsigned long freq;	char *dest;	int error;	if (39 < count)		count = 39;	if (copy_from_user(stkbuf, buf, count))		return -EFAULT;	stkbuf[count] = 0;	freq = simple_strtoul(stkbuf, &dest, 10);	if (*dest != '\0' && *dest != '\n') {		printk("ppc_rtas_tone_freq_write: Invalid tone freqency\n");		return count;	}	if (freq < 0) freq = 0;	rtas_tone_frequency = freq; /* save it for later */	error = rtas_call(set_indicator, 3, 1, NULL,			TONE_FREQUENCY, 0, freq);	if (error != 0)		printk(KERN_WARNING "error: setting tone frequency returned: %s\n", 				ppc_rtas_process_error(error));	return count;}/* ****************************************************************** */static ssize_t ppc_rtas_tone_freq_read(struct file * file, char * buf,		size_t count, loff_t *ppos){	int n, sn;	char stkbuf[40];  /* its small, its on stack */	loff_t pos = *ppos;	n = snprintf(stkbuf, 40, "%lu\n", rtas_tone_frequency);	sn = strlen(stkbuf) +1;	if (pos != (unsigned)pos || pos >= sn)		return 0;	if (n > sn - pos)		n = sn - pos;	if (n > count)		n = count;	if (copy_to_user(buf, stkbuf + pos, n))		return -EFAULT;	*ppos = pos + n;	return n;}/* ****************************************************************** *//* INDICATORS - Tone Volume                                           *//* ****************************************************************** */static ssize_t ppc_rtas_tone_volume_write(struct file * file, const char * buf,		size_t count, loff_t *ppos){	char stkbuf[40];  /* its small, its on stack */	unsigned long volume;	char *dest;	int error;	if (39 < count)		count = 39;	if (copy_from_user(stkbuf, buf, count))		return -EFAULT;	stkbuf[count] = 0;	volume = simple_strtoul(stkbuf, &dest, 10);	if (*dest != '\0' && *dest != '\n') {		printk("ppc_rtas_tone_volume_write: Invalid tone volume\n");		return count;	}	if (volume < 0) volume = 0;	if (volume > 100) volume = 100;	        rtas_tone_volume = volume; /* save it for later */	error = rtas_call(set_indicator, 3, 1, NULL,			TONE_VOLUME, 0, volume);	if (error != 0)		printk(KERN_WARNING "error: setting tone volume returned: %s\n", 				ppc_rtas_process_error(error));	return count;}/* ****************************************************************** */static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf,		size_t count, loff_t *ppos){	int n, sn;	char stkbuf[40];  /* its small, its on stack */	loff_t pos = *ppos;	n = snprintf(stkbuf, 40, "%lu\n", rtas_tone_volume);	sn = strlen(stkbuf) +1;	if (pos != (unsigned)pos || pos >= sn)		return 0;	if (n > sn - pos)		n = sn - pos;	if (n > count)		n = count;	if (copy_to_user(buf, stkbuf + pos, n))		return -EFAULT;	*ppos = pos + n;	return n;}/* ****************************************************************** *//* ERRINJCT			                                      *//* ****************************************************************** */static int ppc_rtas_errinjct_open(struct inode *inode, struct file *file){	int rc;	/* We will only allow one process to use error inject at a	   time.  Since errinjct is usually only used for testing,	   this shouldn't be an issue */	if (open_token) {		return -EAGAIN;	}	rc = rtas_errinjct_open();	if (rc < 0) {		return -EIO;	}	open_token = rc;	return 0;}static ssize_t ppc_rtas_errinjct_write(struct file * file, const char * buf,				       size_t count, loff_t *ppos){ 	char * tmpbuf;	char * ei_token;	char * workspace = NULL;	size_t max_len;	int token_len;	int rc;	/* Verify the errinjct token length */	if (count < ERRINJCT_TOKEN_LEN) {		max_len = count;	} else {		max_len = ERRINJCT_TOKEN_LEN;	}	tmpbuf = (char *) kmalloc(max_len, GFP_KERNEL);	if (!tmpbuf) {		printk(KERN_WARNING "error: kmalloc failed\n");		return -ENOMEM;	}	if (copy_from_user (tmpbuf, buf, max_len)) {		kfree(tmpbuf);		return -EFAULT;	}	token_len = strnlen(tmpbuf, max_len);	token_len++; /* Add one for the null termination */    	ei_token = (char *)kmalloc(token_len, GFP_KERNEL);	if (!ei_token) {		printk(KERN_WARNING "error: kmalloc failed\n");		kfree(tmpbuf);		return -ENOMEM;	}	strncpy(ei_token, tmpbuf, token_len);    	if (count > token_len + WORKSPACE_SIZE) {		count = token_len + WORKSPACE_SIZE;	}    	buf += token_len;	/* check if there is a workspace */	if (count > token_len) {		/* Verify the workspace size */		if ((count - token_len) > WORKSPACE_SIZE) {			max_len = WORKSPACE_SIZE;		} else {			max_len = count - token_len;		}		workspace = (char *)kmalloc(max_len, GFP_KERNEL);		if (!workspace) {			printk(KERN_WARNING "error: failed kmalloc\n");			kfree(tmpbuf);			kfree(ei_token);			return -ENOMEM;		}			memcpy(workspace, tmpbuf, max_len);	}	rc = rtas_errinjct(open_token, ei_token, workspace);	if (count > token_len) {		kfree(workspace);	}	kfree(ei_token);	kfree(tmpbuf);	return rc < 0 ? rc : count;}static int ppc_rtas_errinjct_release(struct inode *inode, struct file *file){	int rc;    	rc = rtas_errinjct_close(open_token);	if (rc) {		return rc;	}	open_token = 0;	return 0;}static ssize_t ppc_rtas_errinjct_read(struct file *file, char *buf,				      size_t count, loff_t *ppos) {	char * buffer;	int i, sn;	int n = 0;	loff_t pos = *ppos;	int m = MAX_ERRINJCT_TOKENS * (ERRINJCT_TOKEN_LEN+1);	buffer = (char *)kmalloc(m, GFP_KERNEL);	if (!buffer) {		printk(KERN_ERR "error: kmalloc failed\n");		return -ENOMEM;	}	for (i = 0; i < MAX_ERRINJCT_TOKENS && ei_token_list[i].value; i++) {		n += snprintf(buffer+n, m-n, ei_token_list[i].name);		n += snprintf(buffer+n, m-n, "\n");	}	sn = strlen(buffer) +1;	if (pos != (unsigned)pos || pos >= sn) {		kfree(buffer);		return 0;	}	if (n > sn - pos)		n = sn - pos;	if (n > count)		n = count;	if (copy_to_user(buf, buffer + pos, n)) {		kfree(buffer);		return -EFAULT;	}	*ppos = pos + n;	kfree(buffer);	return n;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -