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

📄 ibmasmfs.c

📁 h内核
💻 C
📖 第 1 页 / 共 2 页
字号:
	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;	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;	int ret;	if (*offset < 0)		return -EINVAL;	if (count == 0 || count > IBMASM_EVENT_MAX_SIZE)		return 0;	if (*offset != 0)		return 0;	ret = ibmasm_get_next_event(event_data->sp, reader);	if (ret <= 0)		return ret;	if (count < reader->data_size)		return -EINVAL;        if (copy_to_user(buf, reader->data, reader->data_size))		return -EFAULT;	return reader->data_size;}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;	wake_up_interruptible(&event_data->reader.wait);	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 int remote_event_file_open(struct inode *inode, struct file *file){	struct service_processor *sp;	unsigned long flags;	struct remote_queue *q;		file->private_data = inode->u.generic_ip;	sp = file->private_data;	q = &sp->remote_queue;	/* allow only one event reader */	spin_lock_irqsave(&sp->lock, flags);	if (q->open) {		spin_unlock_irqrestore(&sp->lock, flags);		return -EBUSY;	}	q->open = 1;	spin_unlock_irqrestore(&sp->lock, flags);	enable_mouse_interrupts(sp);		return 0;}static int remote_event_file_close(struct inode *inode, struct file *file){	struct service_processor *sp = file->private_data;	disable_mouse_interrupts(sp);	wake_up_interruptible(&sp->remote_queue.wait);	sp->remote_queue.open = 0;	return 0;}static ssize_t remote_event_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset){	struct service_processor *sp = file->private_data;	struct remote_queue *q = &sp->remote_queue;	size_t data_size;	struct remote_event *reader = q->reader;	size_t num_events;	if (*offset < 0)		return -EINVAL;	if (count == 0 || count > 1024)		return 0;	if (*offset != 0)		return 0;	if (wait_event_interruptible(q->wait, q->reader != q->writer))		return -ERESTARTSYS;	/* only get multiples of struct remote_event */	num_events = min((count/sizeof(struct remote_event)), ibmasm_events_available(q));	if (!num_events)		return 0;	data_size = num_events * sizeof(struct remote_event);	if (copy_to_user(buf, reader, data_size))		return -EFAULT;	ibmasm_advance_reader(q, num_events);	return data_size;}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 struct file_operations remote_event_fops = {	.open =		remote_event_file_open,	.release =	remote_event_file_close,	.read =		remote_event_file_read,};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);		ibmasmfs_create_file(sb, remote_dir, "connected", &remote_settings_fops, (void *)vnc_status(sp), S_IRUSR);		ibmasmfs_create_file(sb, remote_dir, "events", &remote_event_fops, (void *)sp, S_IRUSR);	}}

⌨️ 快捷键说明

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