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

📄 ibmasmfs.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (command_data->command)		return -EAGAIN;	cmd = ibmasm_new_command(command_data->sp, count);	if (!cmd)		return -ENOMEM;	if (copy_from_user(cmd->buffer, ubuff, count)) {		command_put(cmd);		return -EFAULT;	}	spin_lock_irqsave(&command_data->sp->lock, flags);	if (command_data->command) {		spin_unlock_irqrestore(&command_data->sp->lock, flags);		command_put(cmd);		return -EAGAIN;	}	command_data->command = cmd;	spin_unlock_irqrestore(&command_data->sp->lock, flags);	ibmasm_exec_command(command_data->sp, cmd);	ibmasm_wait_for_response(cmd, get_dot_command_timeout(cmd->buffer));	return count;}static int event_file_open(struct inode *inode, struct file *file){	struct ibmasmfs_event_data *event_data;	struct service_processor *sp; 	if (!inode->u.generic_ip)		return -ENODEV;	sp = inode->u.generic_ip;	event_data = kmalloc(sizeof(struct ibmasmfs_event_data), GFP_KERNEL);	if (!event_data)		return -ENOMEM;	ibmasm_event_reader_register(sp, &event_data->reader);	event_data->sp = sp;	event_data->active = 0;	file->private_data = event_data;	return 0;}static int event_file_close(struct inode *inode, struct file *file){	struct ibmasmfs_event_data *event_data = file->private_data;	ibmasm_event_reader_unregister(event_data->sp, &event_data->reader);	kfree(event_data);	return 0;}static ssize_t event_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset){	struct ibmasmfs_event_data *event_data = file->private_data;	struct event_reader *reader = &event_data->reader;	struct service_processor *sp = event_data->sp;	int ret;	unsigned long flags;	if (*offset < 0)		return -EINVAL;	if (count == 0 || count > IBMASM_EVENT_MAX_SIZE)		return 0;	if (*offset != 0)		return 0;	spin_lock_irqsave(&sp->lock, flags);	if (event_data->active) {		spin_unlock_irqrestore(&sp->lock, flags);		return -EBUSY;	}	event_data->active = 1;	spin_unlock_irqrestore(&sp->lock, flags);	ret = ibmasm_get_next_event(sp, reader);	if (ret <= 0)		goto out;	if (count < reader->data_size) {		ret = -EINVAL;		goto out;	}        if (copy_to_user(buf, reader->data, reader->data_size)) {		ret = -EFAULT;		goto out;	}	ret = reader->data_size;out:	event_data->active = 0;	return ret;}static ssize_t event_file_write(struct file *file, const char __user *buf, size_t count, loff_t *offset){	struct ibmasmfs_event_data *event_data = file->private_data;	if (*offset < 0)		return -EINVAL;	if (count != 1)		return 0;	if (*offset != 0)		return 0;	ibmasm_cancel_next_event(&event_data->reader);	return 0;}static int r_heartbeat_file_open(struct inode *inode, struct file *file){	struct ibmasmfs_heartbeat_data *rhbeat;	if (!inode->u.generic_ip)		return -ENODEV;	rhbeat = kmalloc(sizeof(struct ibmasmfs_heartbeat_data), GFP_KERNEL);	if (!rhbeat)		return -ENOMEM;	rhbeat->sp = (struct service_processor *)inode->u.generic_ip;	rhbeat->active = 0;	ibmasm_init_reverse_heartbeat(rhbeat->sp, &rhbeat->heartbeat);	file->private_data = rhbeat;	return 0;}static int r_heartbeat_file_close(struct inode *inode, struct file *file){	struct ibmasmfs_heartbeat_data *rhbeat = file->private_data;	kfree(rhbeat);	return 0;}static ssize_t r_heartbeat_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset){	struct ibmasmfs_heartbeat_data *rhbeat = file->private_data;	unsigned long flags;	int result;	if (*offset < 0)		return -EINVAL;	if (count == 0 || count > 1024)		return 0;	if (*offset != 0)		return 0;	/* allow only one reverse heartbeat per process */	spin_lock_irqsave(&rhbeat->sp->lock, flags);	if (rhbeat->active) {		spin_unlock_irqrestore(&rhbeat->sp->lock, flags);		return -EBUSY;	}	rhbeat->active = 1;	spin_unlock_irqrestore(&rhbeat->sp->lock, flags);	result = ibmasm_start_reverse_heartbeat(rhbeat->sp, &rhbeat->heartbeat);	rhbeat->active = 0;	return result;}static ssize_t r_heartbeat_file_write(struct file *file, const char __user *buf, size_t count, loff_t *offset){	struct ibmasmfs_heartbeat_data *rhbeat = file->private_data;	if (*offset < 0)		return -EINVAL;	if (count != 1)		return 0;	if (*offset != 0)		return 0;	if (rhbeat->active)		ibmasm_stop_reverse_heartbeat(&rhbeat->heartbeat);	return 1;}static int remote_settings_file_open(struct inode *inode, struct file *file){	file->private_data = inode->u.generic_ip;	return 0;}static int remote_settings_file_close(struct inode *inode, struct file *file){	return 0;}static ssize_t remote_settings_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset){	void __iomem *address = (void __iomem *)file->private_data;	unsigned char *page;	int retval;	int len = 0;	unsigned int value;	if (*offset < 0)		return -EINVAL;	if (count == 0 || count > 1024)		return 0;	if (*offset != 0)		return 0;	page = (unsigned char *)__get_free_page(GFP_KERNEL);	if (!page)		return -ENOMEM;	value = readl(address);	len = sprintf(page, "%d\n", value);	if (copy_to_user(buf, page, len)) {		retval = -EFAULT;		goto exit;	}	*offset += len;	retval = len;exit:	free_page((unsigned long)page);	return retval;}static ssize_t remote_settings_file_write(struct file *file, const char __user *ubuff, size_t count, loff_t *offset){	void __iomem *address = (void __iomem *)file->private_data;	char *buff;	unsigned int value;	if (*offset < 0)		return -EINVAL;	if (count == 0 || count > 1024)		return 0;	if (*offset != 0)		return 0;	buff = kmalloc (count + 1, GFP_KERNEL);	if (!buff)		return -ENOMEM;	memset(buff, 0x0, count + 1);	if (copy_from_user(buff, ubuff, count)) {		kfree(buff);		return -EFAULT;	}		value = simple_strtoul(buff, NULL, 10);	writel(value, address);	kfree(buff);	return count;}static struct file_operations command_fops = {	.open =		command_file_open,	.release =	command_file_close,	.read =		command_file_read,	.write =	command_file_write,};static struct file_operations event_fops = {	.open =		event_file_open,	.release =	event_file_close,	.read =		event_file_read,	.write =	event_file_write,};static struct file_operations r_heartbeat_fops = {	.open =		r_heartbeat_file_open,	.release =	r_heartbeat_file_close,	.read =		r_heartbeat_file_read,	.write =	r_heartbeat_file_write,};static struct file_operations remote_settings_fops = {	.open =		remote_settings_file_open,	.release =	remote_settings_file_close,	.read =		remote_settings_file_read,	.write =	remote_settings_file_write,};static void ibmasmfs_create_files (struct super_block *sb, struct dentry *root){	struct list_head *entry;	struct service_processor *sp;	list_for_each(entry, &service_processors) {		struct dentry *dir;		struct dentry *remote_dir;		sp = list_entry(entry, struct service_processor, node);		dir = ibmasmfs_create_dir(sb, root, sp->dirname);		if (!dir)			continue;		ibmasmfs_create_file(sb, dir, "command", &command_fops, sp, S_IRUSR|S_IWUSR);		ibmasmfs_create_file(sb, dir, "event", &event_fops, sp, S_IRUSR|S_IWUSR);		ibmasmfs_create_file(sb, dir, "reverse_heartbeat", &r_heartbeat_fops, sp, S_IRUSR|S_IWUSR);		remote_dir = ibmasmfs_create_dir(sb, dir, "remote_video");		if (!remote_dir)			continue;		ibmasmfs_create_file(sb, remote_dir, "width", &remote_settings_fops, (void *)display_width(sp), S_IRUSR|S_IWUSR);		ibmasmfs_create_file(sb, remote_dir, "height", &remote_settings_fops, (void *)display_height(sp), S_IRUSR|S_IWUSR);		ibmasmfs_create_file(sb, remote_dir, "depth", &remote_settings_fops, (void *)display_depth(sp), S_IRUSR|S_IWUSR);	}}

⌨️ 快捷键说明

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