📄 ibmasmfs.c
字号:
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 + -