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

📄 envctrl.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
        /* Read data from address and port. */	data = envctrl_i2c_read_8591((unsigned char)pchild->addr,				     (unsigned char)pchild->chnl_array[i].chnl_no);	/* Find decoding table. */	tbl = pchild->tables + pchild->tblprop_array[i].offset;	return envctrl_i2c_data_translate(data, pchild->tblprop_array[i].type,					  pchild->tblprop_array[i].scale,					  tbl, bufdata);}/* Function Description: Read noncpu-related data such as motherboard  *                       temperature. * Return: Number of read bytes. Data is stored in bufdata in ascii format. */static int envctrl_read_noncpu_info(struct i2c_child_t *pchild,				    char mon_type, unsigned char *bufdata){	unsigned char data;	int i;	char *tbl = NULL;	for (i = 0; i < PCF8584_MAX_CHANNELS; i++) {		if (pchild->mon_type[i] == mon_type)			break;	}	if (i >= PCF8584_MAX_CHANNELS)		return 0;        /* Read data from address and port. */	data = envctrl_i2c_read_8591((unsigned char)pchild->addr,				     (unsigned char)pchild->chnl_array[i].chnl_no);	/* Find decoding table. */	tbl = pchild->tables + pchild->tblprop_array[i].offset;	return envctrl_i2c_data_translate(data, pchild->tblprop_array[i].type,					  pchild->tblprop_array[i].scale,					  tbl, bufdata);}/* Function Description: Read fan status. * Return : Always 1 byte. Status stored in bufdata. */static int envctrl_i2c_fan_status(struct i2c_child_t *pchild,				  unsigned char data,				  char *bufdata){	unsigned char tmp, ret = 0;	int i, j = 0;	tmp = data & pchild->fan_mask;	if (tmp == pchild->fan_mask) {		/* All bits are on. All fans are functioning. */		ret = ENVCTRL_ALL_FANS_GOOD;	} else if (tmp == 0) {		/* No bits are on. No fans are functioning. */		ret = ENVCTRL_ALL_FANS_BAD;	} else {		/* Go through all channels, mark 'on' the matched bits.		 * Notice that fan_mask may have discontiguous bits but		 * return mask are always contiguous. For example if we		 * monitor 4 fans at channels 0,1,2,4, the return mask		 * should be 00010000 if only fan at channel 4 is working.		 */		for (i = 0; i < PCF8584_MAX_CHANNELS;i++) {			if (pchild->fan_mask & chnls_mask[i]) {				if (!(chnls_mask[i] & tmp))					ret |= chnls_mask[j];				j++;			}		}	}	bufdata[0] = ret;	return 1;}/* Function Description: Read global addressing line. * Return : Always 1 byte. Status stored in bufdata. */static int envctrl_i2c_globaladdr(struct i2c_child_t *pchild,				  unsigned char data,				  char *bufdata){	/* Translatation table is not necessary, as global	 * addr is the integer value of the GA# bits.	 *	 * NOTE: MSB is documented as zero, but I see it as '1' always....	 *	 * -----------------------------------------------	 * | 0 | FAL | DEG | GA4 | GA3 | GA2 | GA1 | GA0 |	 * -----------------------------------------------	 * GA0 - GA4	integer value of Global Address (backplane slot#)	 * DEG			0 = cPCI Power supply output is starting to degrade	 * 				1 = cPCI Power supply output is OK	 * FAL			0 = cPCI Power supply has failed	 * 				1 = cPCI Power supply output is OK	 */	bufdata[0] = (data & ENVCTRL_GLOBALADDR_ADDR_MASK);	return 1;}/* Function Description: Read standard voltage and power supply status. * Return : Always 1 byte. Status stored in bufdata. */static unsigned char envctrl_i2c_voltage_status(struct i2c_child_t *pchild,						unsigned char data,						char *bufdata){	unsigned char tmp, ret = 0;	int i, j = 0;	tmp = data & pchild->voltage_mask;	/* Two channels are used to monitor voltage and power supply. */	if (tmp == pchild->voltage_mask) {		/* All bits are on. Voltage and power supply are okay. */		ret = ENVCTRL_VOLTAGE_POWERSUPPLY_GOOD;	} else if (tmp == 0) {		/* All bits are off. Voltage and power supply are bad */		ret = ENVCTRL_VOLTAGE_POWERSUPPLY_BAD;	} else {		/* Either voltage or power supply has problem. */		for (i = 0; i < PCF8584_MAX_CHANNELS; i++) {			if (pchild->voltage_mask & chnls_mask[i]) {				j++;				/* Break out when there is a mismatch. */				if (!(chnls_mask[i] & tmp))					break; 			}		}		/* Make a wish that hardware will always use the		 * first channel for voltage and the second for		 * power supply.		 */		if (j == 1)			ret = ENVCTRL_VOLTAGE_BAD;		else			ret = ENVCTRL_POWERSUPPLY_BAD;	}	bufdata[0] = ret;	return 1;}/* Function Description: Read a byte from /dev/envctrl. Mapped to user read(). * Return: Number of read bytes. 0 for error. */static ssize_tenvctrl_read(struct file *file, char __user *buf, size_t count, loff_t *ppos){	struct i2c_child_t *pchild;	unsigned char data[10];	int ret = 0;	/* Get the type of read as decided in ioctl() call.	 * Find the appropriate i2c child.	 * Get the data and put back to the user buffer.	 */	switch ((int)(long)file->private_data) {	case ENVCTRL_RD_WARNING_TEMPERATURE:		if (warning_temperature == 0)			return 0;		data[0] = (unsigned char)(warning_temperature);		ret = 1;		if (copy_to_user(buf, data, ret))			ret = -EFAULT;		break;	case ENVCTRL_RD_SHUTDOWN_TEMPERATURE:		if (shutdown_temperature == 0)			return 0;		data[0] = (unsigned char)(shutdown_temperature);		ret = 1;		if (copy_to_user(buf, data, ret))			ret = -EFAULT;		break;	case ENVCTRL_RD_MTHRBD_TEMPERATURE:		if (!(pchild = envctrl_get_i2c_child(ENVCTRL_MTHRBDTEMP_MON)))			return 0;		ret = envctrl_read_noncpu_info(pchild, ENVCTRL_MTHRBDTEMP_MON, data);		if (copy_to_user(buf, data, ret))			ret = -EFAULT;		break;	case ENVCTRL_RD_CPU_TEMPERATURE:		if (!(pchild = envctrl_get_i2c_child(ENVCTRL_CPUTEMP_MON)))			return 0;		ret = envctrl_read_cpu_info(read_cpu, pchild, ENVCTRL_CPUTEMP_MON, data);		/* Reset cpu to the default cpu0. */		if (copy_to_user(buf, data, ret))			ret = -EFAULT;		break;	case ENVCTRL_RD_CPU_VOLTAGE:		if (!(pchild = envctrl_get_i2c_child(ENVCTRL_CPUVOLTAGE_MON)))			return 0;		ret = envctrl_read_cpu_info(read_cpu, pchild, ENVCTRL_CPUVOLTAGE_MON, data);		/* Reset cpu to the default cpu0. */		if (copy_to_user(buf, data, ret))			ret = -EFAULT;		break;	case ENVCTRL_RD_SCSI_TEMPERATURE:		if (!(pchild = envctrl_get_i2c_child(ENVCTRL_SCSITEMP_MON)))			return 0;		ret = envctrl_read_noncpu_info(pchild, ENVCTRL_SCSITEMP_MON, data);		if (copy_to_user(buf, data, ret))			ret = -EFAULT;		break;	case ENVCTRL_RD_ETHERNET_TEMPERATURE:		if (!(pchild = envctrl_get_i2c_child(ENVCTRL_ETHERTEMP_MON)))			return 0;		ret = envctrl_read_noncpu_info(pchild, ENVCTRL_ETHERTEMP_MON, data);		if (copy_to_user(buf, data, ret))			ret = -EFAULT;		break;	case ENVCTRL_RD_FAN_STATUS:		if (!(pchild = envctrl_get_i2c_child(ENVCTRL_FANSTAT_MON)))			return 0;		data[0] = envctrl_i2c_read_8574(pchild->addr);		ret = envctrl_i2c_fan_status(pchild,data[0], data);		if (copy_to_user(buf, data, ret))			ret = -EFAULT;		break;		case ENVCTRL_RD_GLOBALADDRESS:		if (!(pchild = envctrl_get_i2c_child(ENVCTRL_GLOBALADDR_MON)))			return 0;		data[0] = envctrl_i2c_read_8574(pchild->addr);		ret = envctrl_i2c_globaladdr(pchild, data[0], data);		if (copy_to_user(buf, data, ret))			ret = -EFAULT;		break;	case ENVCTRL_RD_VOLTAGE_STATUS:		if (!(pchild = envctrl_get_i2c_child(ENVCTRL_VOLTAGESTAT_MON)))			/* If voltage monitor not present, check for CPCI equivalent */			if (!(pchild = envctrl_get_i2c_child(ENVCTRL_GLOBALADDR_MON)))				return 0;		data[0] = envctrl_i2c_read_8574(pchild->addr);		ret = envctrl_i2c_voltage_status(pchild, data[0], data);		if (copy_to_user(buf, data, ret))			ret = -EFAULT;		break;	default:		break;	};	return ret;}/* Function Description: Command what to read.  Mapped to user ioctl(). * Return: Gives 0 for implemented commands, -EINVAL otherwise. */static longenvctrl_ioctl(struct file *file, unsigned int cmd, unsigned long arg){	char __user *infobuf;	switch (cmd) {	case ENVCTRL_RD_WARNING_TEMPERATURE:	case ENVCTRL_RD_SHUTDOWN_TEMPERATURE:	case ENVCTRL_RD_MTHRBD_TEMPERATURE:	case ENVCTRL_RD_FAN_STATUS:	case ENVCTRL_RD_VOLTAGE_STATUS:	case ENVCTRL_RD_ETHERNET_TEMPERATURE:	case ENVCTRL_RD_SCSI_TEMPERATURE:	case ENVCTRL_RD_GLOBALADDRESS:		file->private_data = (void *)(long)cmd;		break;	case ENVCTRL_RD_CPU_TEMPERATURE:	case ENVCTRL_RD_CPU_VOLTAGE:		/* Check to see if application passes in any cpu number,		 * the default is cpu0.		 */		infobuf = (char __user *) arg;		if (infobuf == NULL) {			read_cpu = 0;		}else {			get_user(read_cpu, infobuf);		}		/* Save the command for use when reading. */		file->private_data = (void *)(long)cmd;		break;	default:		return -EINVAL;	};	return 0;}/* Function Description: open device. Mapped to user open(). * Return: Always 0. */static intenvctrl_open(struct inode *inode, struct file *file){	file->private_data = NULL;	return 0;}/* Function Description: Open device. Mapped to user close(). * Return: Always 0. */static intenvctrl_release(struct inode *inode, struct file *file){	return 0;}static struct file_operations envctrl_fops = {	.owner =		THIS_MODULE,	.read =			envctrl_read,	.unlocked_ioctl =	envctrl_ioctl,#ifdef CONFIG_COMPAT	.compat_ioctl =		envctrl_ioctl,#endif	.open =			envctrl_open,	.release =		envctrl_release,};	static struct miscdevice envctrl_dev = {	ENVCTRL_MINOR,	"envctrl",	&envctrl_fops};/* Function Description: Set monitor type based on firmware description. * Return: None. */static void envctrl_set_mon(struct i2c_child_t *pchild,			    char *chnl_desc,			    int chnl_no){	/* Firmware only has temperature type.  It does not distinguish	 * different kinds of temperatures.  We use channel description	 * to disinguish them.	 */	if (!(strcmp(chnl_desc,"temp,cpu")) ||	    !(strcmp(chnl_desc,"temp,cpu0")) ||	    !(strcmp(chnl_desc,"temp,cpu1")) ||	    !(strcmp(chnl_desc,"temp,cpu2")) ||	    !(strcmp(chnl_desc,"temp,cpu3")))		pchild->mon_type[chnl_no] = ENVCTRL_CPUTEMP_MON;	if (!(strcmp(chnl_desc,"vddcore,cpu0")) ||	    !(strcmp(chnl_desc,"vddcore,cpu1")) ||	    !(strcmp(chnl_desc,"vddcore,cpu2")) ||	    !(strcmp(chnl_desc,"vddcore,cpu3")))		pchild->mon_type[chnl_no] = ENVCTRL_CPUVOLTAGE_MON;	if (!(strcmp(chnl_desc,"temp,motherboard")))		pchild->mon_type[chnl_no] = ENVCTRL_MTHRBDTEMP_MON;	if (!(strcmp(chnl_desc,"temp,scsi")))		pchild->mon_type[chnl_no] = ENVCTRL_SCSITEMP_MON;	if (!(strcmp(chnl_desc,"temp,ethernet")))		pchild->mon_type[chnl_no] = ENVCTRL_ETHERTEMP_MON;}/* Function Description: Initialize monitor channel with channel desc, *                       decoding tables, monitor type, optional properties.

⌨️ 快捷键说明

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