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

📄 rtas_flash.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
			wait_time = rtas_extended_busy_delay_time(rc);			udelay(wait_time * 1000);		} else			break;	}	args_buf->status = rc;}static ssize_t manage_flash_read(struct file *file, char *buf,			       size_t count, loff_t *ppos){	struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip;	struct rtas_manage_flash_t *args_buf;	char msg[RTAS_MSG_MAXLEN];	int msglen;	int error;	args_buf = (struct rtas_manage_flash_t *) dp->data;	if (args_buf == NULL)		return 0;	msglen = sprintf(msg, "%d\n", args_buf->status);	if (msglen > count)		msglen = count;	if (ppos && *ppos != 0)		return 0;	/* be cheap */	error = verify_area(VERIFY_WRITE, buf, msglen);	if (error)		return -EINVAL;	if (copy_to_user(buf, msg, msglen))		return -EFAULT;	if (ppos)		*ppos = msglen;	return msglen;}static ssize_t manage_flash_write(struct file *file, const char *buf,				size_t count, loff_t *off){	struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip;	struct rtas_manage_flash_t *args_buf;	const char reject_str[] = "0";	const char commit_str[] = "1";	char stkbuf[10];	int op;	args_buf = (struct rtas_manage_flash_t *) dp->data;	if ((args_buf->status == MANAGE_AUTH) || (count == 0))		return count;	op = -1;	if (buf) {		if (count > 9) count = 9;		if (copy_from_user (stkbuf, buf, count)) {			return -EFAULT;		}		if (strncmp(stkbuf, reject_str, strlen(reject_str)) == 0)			op = RTAS_REJECT_TMP_IMG;		else if (strncmp(stkbuf, commit_str, strlen(commit_str)) == 0)			op = RTAS_COMMIT_TMP_IMG;	}	if (op == -1)   /* buf is empty, or contains invalid string */		return -EINVAL;	args_buf->op = op;	manage_flash(args_buf);	return count;}static void validate_flash(struct rtas_validate_flash_t *args_buf){	int token = rtas_token("ibm,validate-flash-image");	unsigned int wait_time;	long update_results;	s32 rc;	rc = 0;	while(1) {		spin_lock(&rtas_data_buf_lock);		memcpy(rtas_data_buf, args_buf->buf, VALIDATE_BUF_SIZE);		rc = (s32) rtas_call(token, 2, 2, &update_results,				     __pa(rtas_data_buf), args_buf->buf_size);		memcpy(args_buf->buf, rtas_data_buf, VALIDATE_BUF_SIZE);		spin_unlock(&rtas_data_buf_lock);		if (rc == RTAS_RC_BUSY)			udelay(1);		else if (rtas_is_extended_busy(rc)) {			wait_time = rtas_extended_busy_delay_time(rc);			udelay(wait_time * 1000);		} else			break;	}	args_buf->status = rc;	args_buf->update_results = (u32) update_results;}static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf,				   char *msg){	int n;	if (args_buf->status >= VALIDATE_TMP_UPDATE) {		n = sprintf(msg, "%d\n", args_buf->update_results);		if ((args_buf->update_results >= VALIDATE_CUR_UNKNOWN) ||		    (args_buf->update_results == VALIDATE_TMP_UPDATE))			n += sprintf(msg + n, "%s\n", args_buf->buf);	} else {		n = sprintf(msg, "%d\n", args_buf->status);	}	return n;}static ssize_t validate_flash_read(struct file *file, char *buf,			       size_t count, loff_t *ppos){	struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip;	struct rtas_validate_flash_t *args_buf;	char msg[RTAS_MSG_MAXLEN];	int msglen;	int error;	args_buf = (struct rtas_validate_flash_t *) dp->data;	if (ppos && *ppos != 0)		return 0;	/* be cheap */	msglen = get_validate_flash_msg(args_buf, msg);	if (msglen > count)		msglen = count;	error = verify_area(VERIFY_WRITE, buf, msglen);	if (error)		return -EINVAL;	if (copy_to_user(buf, msg, msglen))		return -EFAULT;	if (ppos)		*ppos = msglen;	return msglen;}static ssize_t validate_flash_write(struct file *file, const char *buf,				size_t count, loff_t *off){	struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip;	struct rtas_validate_flash_t *args_buf;	int rc;	args_buf = (struct rtas_validate_flash_t *) dp->data;	if (dp->data == NULL) {		dp->data = kmalloc(sizeof(struct rtas_validate_flash_t),				GFP_KERNEL);		if (dp->data == NULL)			return -ENOMEM;	}	/* We are only interested in the first 4K of the	 * candidate image */	if ((*off >= VALIDATE_BUF_SIZE) ||		(args_buf->status == VALIDATE_AUTH)) {		*off += count;		return count;	}	if (*off + count >= VALIDATE_BUF_SIZE)  {		count = VALIDATE_BUF_SIZE - *off;		args_buf->status = VALIDATE_READY;	} else {		args_buf->status = VALIDATE_INCOMPLETE;	}	if (verify_area(VERIFY_READ, buf, count)) {		rc = -EFAULT;		goto done;	}	if (copy_from_user(args_buf->buf + *off, buf, count)) {		rc = -EFAULT;		goto done;	}	*off += count;	rc = count;done:	if (rc < 0) {		kfree(dp->data);		dp->data = NULL;	}	return rc;}static int validate_flash_release(struct inode *inode, struct file *file){	struct proc_dir_entry *dp = file->f_dentry->d_inode->u.generic_ip;	struct rtas_validate_flash_t *args_buf;	args_buf = (struct rtas_validate_flash_t *) dp->data;	if (args_buf->status == VALIDATE_READY) {		args_buf->buf_size = VALIDATE_BUF_SIZE;		validate_flash(args_buf);	}	atomic_dec(&dp->count);	return 0;}static inline void remove_flash_pde(struct proc_dir_entry *dp){	if (dp) {		if (dp->data != NULL)			kfree(dp->data);		remove_proc_entry(dp->name, rtas_proc_dir);	}}static inline int initialize_flash_pde_data(const char *rtas_call_name,					    size_t buf_size,					    struct proc_dir_entry *dp){	int *status;	int token;	dp->data = kmalloc(buf_size, GFP_KERNEL);	if (dp->data == NULL) {		remove_flash_pde(dp);		return -ENOMEM;	}	memset(dp->data, 0, buf_size);	/* This code assumes that the status int is the first member of the	 * struct	 */	status = (int *) dp->data;	token = rtas_token(rtas_call_name);	if (token == RTAS_UNKNOWN_SERVICE)		*status = FLASH_AUTH;	else		*status = FLASH_NO_OP;	return 0;}static inline struct proc_dir_entry * create_flash_pde(const char *filename,					struct file_operations *fops){	struct proc_dir_entry *ent = NULL;	ent = create_proc_entry(filename, S_IRUSR | S_IWUSR, rtas_proc_dir);	if (ent != NULL) {		ent->nlink = 1;		ent->proc_fops = fops;		ent->owner = THIS_MODULE;	}	return ent;}static struct file_operations rtas_flash_operations = {	read:		rtas_flash_read,	write:		rtas_flash_write,	open:		rtas_excl_open,	release:	rtas_flash_release,};static struct file_operations manage_flash_operations = {	read:		manage_flash_read,	write:		manage_flash_write,	open:		rtas_excl_open,	release:	rtas_excl_release,};static struct file_operations validate_flash_operations = {	read:		validate_flash_read,	write:		validate_flash_write,	open:		rtas_excl_open,	release:	validate_flash_release,};int __init rtas_flash_init(void){	int rc;	if (!rtas_proc_dir) {		printk(KERN_WARNING "rtas proc dir does not already exist");		return -ENOENT;	}	firmware_flash_pde = create_flash_pde(FIRMWARE_FLASH_NAME,					      &rtas_flash_operations);	rc = initialize_flash_pde_data("ibm,update-flash-64-and-reboot",				       sizeof(struct rtas_update_flash_t),				       firmware_flash_pde);	if (rc != 0)		return rc;	firmware_update_pde = create_flash_pde(FIRMWARE_UPDATE_NAME,					       &rtas_flash_operations);	rc = initialize_flash_pde_data("ibm,update-flash-64-and-reboot",				       sizeof(struct rtas_update_flash_t),				       firmware_update_pde);	if (rc != 0)		return rc;	validate_pde = create_flash_pde(VALIDATE_FLASH_NAME,					&validate_flash_operations);	rc = initialize_flash_pde_data("ibm,validate-flash-image",				       sizeof(struct rtas_validate_flash_t),				       validate_pde);	if (rc != 0)		return rc;	manage_pde = create_flash_pde(MANAGE_FLASH_NAME,				      &manage_flash_operations);	rc = initialize_flash_pde_data("ibm,manage-flash-image",				       sizeof(struct rtas_manage_flash_t),				       manage_pde);	if (rc != 0)		return rc;	return 0;}void __exit rtas_flash_cleanup(void){	if (!rtas_proc_dir)		return;	remove_flash_pde(firmware_flash_pde);	remove_flash_pde(firmware_update_pde);	remove_flash_pde(validate_pde);	remove_flash_pde(manage_pde);}module_init(rtas_flash_init);module_exit(rtas_flash_cleanup);MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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