]> git.pld-linux.org Git - packages/kernel.git/blob - 2.6.x-IBM-RAS-service-procesor-2of2-lkml.patch
- statically allocate "dynamic" minors for dm and fbsplash
[packages/kernel.git] / 2.6.x-IBM-RAS-service-procesor-2of2-lkml.patch
1 diff -urN linux-2.6.1/drivers/misc/ibmasm/ibmasmfs.c linux-2.6.1-ibmasm/drivers/misc/ibmasm/ibmasmfs.c
2 --- linux-2.6.1/drivers/misc/ibmasm/ibmasmfs.c  1969-12-31 16:00:00.000000000 -0800
3 +++ linux-2.6.1-ibmasm/drivers/misc/ibmasm/ibmasmfs.c   2004-01-23 15:39:00.000000000 -0800
4 @@ -0,0 +1,734 @@
5 +/*
6 + * IBM ASM Service Processor Device Driver
7 + *
8 + * This program is free software; you can redistribute it and/or modify
9 + * it under the terms of the GNU General Public License as published by
10 + * the Free Software Foundation; either version 2 of the License, or
11 + * (at your option) any later version.
12 + *
13 + * This program is distributed in the hope that it will be useful,
14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 + * GNU General Public License for more details.
17 + *
18 + * You should have received a copy of the GNU General Public License
19 + * along with this program; if not, write to the Free Software
20 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 + *
22 + * Copyright (C) IBM Corporation, 2004
23 + *
24 + * Author: Max Asböck <amax@us.ibm.com> 
25 + *
26 + */
27 +
28 +/*
29 + * Parts of this code are based on an article by Jonathan Corbet 
30 + * that appeared in Linux Weekly News.
31 + */
32 +
33 +
34 +/*
35 + * The IBMASM file virtual filesystem. It creates the following hierarchy
36 + * dymamically when mounted from user space:
37 + *
38 + *    /ibmasm
39 + *    |-- 0
40 + *    |   |-- command
41 + *    |   |-- event
42 + *    |   |-- reverse_heartbeat
43 + *    |   `-- remote_video
44 + *    |       |-- connected
45 + *    |       |-- depth
46 + *    |       |-- events
47 + *    |       |-- height
48 + *    |       `-- width
49 + *    .
50 + *    .
51 + *    .
52 + *    `-- n
53 + *        |-- command
54 + *        |-- event
55 + *        |-- reverse_heartbeat
56 + *        `-- remote_video
57 + *            |-- connected
58 + *            |-- depth
59 + *            |-- events
60 + *            |-- height
61 + *            `-- width
62 + *
63 + * For each service processor the following files are created:
64 + *
65 + * command: execute dot commands
66 + *     write: execute a dot command on the service processor
67 + *     read: return the result of a previously executed dot command
68 + *
69 + * events: listen for service processor events
70 + *     read: sleep (interruptible) until an event occurs
71 + *
72 + * reverse_heartbeat: send a heartbeat to the service processor
73 + *     read: sleep (interruptible) until the reverse heartbeat fails
74 + *
75 + * remote_video/width
76 + * remote_video/height
77 + * remote_video/width: control remote display settings
78 + *     write: set value
79 + *     read: read value
80 + *
81 + * remote_video/connected
82 + *     read: return "1" if web browser VNC java applet is connected, 
83 + *             "0" otherwise
84 + *
85 + * remote_video/events
86 + *     read: sleep until a remote mouse or keyboard event occurs, then return
87 + *             then event.
88 + */
89 +
90 +#include <linux/fs.h>
91 +#include <linux/pagemap.h>
92 +#include <asm/uaccess.h>
93 +#include <asm/io.h>
94 +#include "ibmasm.h"
95 +#include "remote.h"
96 +#include "dot_command.h"
97 +
98 +#define IBMASMFS_MAGIC 0x66726f67
99 +
100 +static LIST_HEAD(service_processors);
101 +
102 +static struct inode *ibmasmfs_make_inode(struct super_block *sb, int mode);
103 +static void ibmasmfs_create_files (struct super_block *sb, struct dentry *root);
104 +static int ibmasmfs_fill_super (struct super_block *sb, void *data, int silent);
105 +
106 +
107 +static struct super_block *ibmasmfs_get_super(struct file_system_type *fst,
108 +                       int flags, const char *name, void *data)
109 +{
110 +       return get_sb_single(fst, flags, data, ibmasmfs_fill_super);
111 +}
112 +
113 +static struct super_operations ibmasmfs_s_ops = {
114 +       .statfs         = simple_statfs,
115 +       .drop_inode     = generic_delete_inode,
116 +};
117 +
118 +static struct file_operations *ibmasmfs_dir_ops = &simple_dir_operations;
119 +
120 +static struct file_system_type ibmasmfs_type = {
121 +       .owner          = THIS_MODULE,
122 +       .name           = "ibmasmfs",
123 +       .get_sb         = ibmasmfs_get_super,
124 +       .kill_sb        = kill_litter_super,
125 +};
126 +
127 +static int ibmasmfs_fill_super (struct super_block *sb, void *data, int silent)
128 +{
129 +       struct inode *root;
130 +       struct dentry *root_dentry;
131 +
132 +       sb->s_blocksize = PAGE_CACHE_SIZE;
133 +       sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
134 +       sb->s_magic = IBMASMFS_MAGIC;
135 +       sb->s_op = &ibmasmfs_s_ops;
136 +
137 +       root = ibmasmfs_make_inode (sb, S_IFDIR | 0500);
138 +       if (!root)
139 +               return -ENOMEM;
140 +
141 +       root->i_op = &simple_dir_inode_operations;
142 +       root->i_fop = ibmasmfs_dir_ops;
143 +
144 +       root_dentry = d_alloc_root(root);
145 +       if (!root_dentry) {
146 +               iput(root);
147 +               return -ENOMEM;
148 +       }
149 +       sb->s_root = root_dentry;
150 +
151 +       ibmasmfs_create_files(sb, root_dentry);
152 +       return 0;
153 +}
154 +
155 +static struct inode *ibmasmfs_make_inode(struct super_block *sb, int mode)
156 +{
157 +       struct inode *ret = new_inode(sb);
158 +
159 +       if (ret) {
160 +               ret->i_mode = mode;
161 +               ret->i_uid = ret->i_gid = 0;
162 +               ret->i_blksize = PAGE_CACHE_SIZE;
163 +               ret->i_blocks = 0;
164 +               ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME;
165 +       }
166 +       return ret;
167 +}
168 +
169 +static struct dentry *ibmasmfs_create_file (struct super_block *sb,
170 +                       struct dentry *parent,
171 +                       const char *name,
172 +                       struct file_operations *fops,
173 +                       void *data,
174 +                       int mode)
175 +{
176 +       struct dentry *dentry;
177 +       struct inode *inode;
178 +       struct qstr qname;
179 +
180 +       qname.name = name;
181 +       qname.len = strlen (name);
182 +       qname.hash = full_name_hash(name, qname.len);
183 +
184 +       dentry = d_alloc(parent, &qname);
185 +       if (!dentry)
186 +               return NULL;
187 +
188 +       inode = ibmasmfs_make_inode(sb, S_IFREG | mode);
189 +       if (!inode) {
190 +               dput(dentry);
191 +               return NULL;
192 +       }
193 +
194 +       inode->i_fop = fops;
195 +       inode->u.generic_ip = data;
196 +
197 +       d_add(dentry, inode);
198 +       return dentry;
199 +}
200 +
201 +static struct dentry *ibmasmfs_create_dir (struct super_block *sb,
202 +                               struct dentry *parent,
203 +                               const char *name)
204 +{
205 +       struct dentry *dentry;
206 +       struct inode *inode;
207 +       struct qstr qname;
208 +
209 +       qname.name = name;
210 +       qname.len = strlen (name);
211 +       qname.hash = full_name_hash(name, qname.len);
212 +       dentry = d_alloc(parent, &qname);
213 +       if (!dentry)
214 +               return NULL;
215 +
216 +       inode = ibmasmfs_make_inode(sb, S_IFDIR | 0500);
217 +       if (!inode) {
218 +               dput(dentry);
219 +               return NULL;
220 +       }
221 +
222 +       inode->i_op = &simple_dir_inode_operations;
223 +       inode->i_fop = ibmasmfs_dir_ops;
224 +
225 +       d_add(dentry, inode);
226 +       return dentry;
227 +}
228 +
229 +int ibmasmfs_register()
230 +{
231 +       return register_filesystem(&ibmasmfs_type);
232 +}
233 +
234 +void ibmasmfs_unregister()
235 +{
236 +       unregister_filesystem(&ibmasmfs_type);
237 +}
238 +
239 +void ibmasmfs_add_sp(struct service_processor *sp)
240 +{
241 +       list_add(&sp->node, &service_processors);
242 +}
243 +
244 +/* struct to save state between command file operations */
245 +struct ibmasmfs_command_data {
246 +       struct service_processor        *sp;
247 +       struct command                  *command;
248 +};
249 +
250 +/* struct to save state between event file operations */
251 +struct ibmasmfs_event_data {
252 +       struct service_processor        *sp;
253 +       struct event_reader             reader;
254 +       int                             active;
255 +};
256 +
257 +/* struct to save state between reverse heartbeat file operations */
258 +struct ibmasmfs_heartbeat_data {
259 +       struct service_processor        *sp;
260 +       struct reverse_heartbeat        heartbeat;
261 +       int                             active;
262 +       spinlock_t                      lock;
263 +};
264 +
265 +static int command_file_open(struct inode *inode, struct file *file)
266 +{
267 +       struct ibmasmfs_command_data *command_data;
268 +
269 +       if ( !inode->u.generic_ip )
270 +               return -ENODEV;
271 +
272 +       command_data = kmalloc(sizeof(struct ibmasmfs_command_data), GFP_KERNEL);
273 +       if ( !command_data )
274 +               return -ENOMEM;
275 +
276 +       command_data->command = NULL;
277 +       command_data->sp = inode->u.generic_ip;
278 +       file->private_data = command_data;
279 +       return 0;
280 +}
281 +
282 +static int command_file_close(struct inode *inode, struct file *file)
283 +{
284 +       struct ibmasmfs_command_data *command_data = file->private_data;
285 +
286 +       if (command_data->command)
287 +               command_put(command_data->command);     
288 +
289 +       kfree(command_data);
290 +       return 0;
291 +}
292 +
293 +static ssize_t command_file_read(struct file *file, char *buf, size_t count, loff_t *offset)
294 +{
295 +       struct ibmasmfs_command_data *command_data = file->private_data;
296 +       struct command *cmd;
297 +       int len;
298 +       unsigned long flags;
299 +
300 +       if (*offset < 0)
301 +               return -EINVAL;
302 +       if (count == 0 || count > IBMASM_CMD_MAX_BUFFER_SIZE)
303 +               return 0;
304 +       if (*offset != 0)
305 +               return 0;
306 +
307 +       spin_lock_irqsave(&command_data->sp->lock, flags);
308 +       cmd = command_data->command;
309 +       if (cmd == NULL) {
310 +               spin_unlock_irqrestore(&command_data->sp->lock, flags);
311 +               return 0;
312 +       }
313 +       command_data->command = NULL;
314 +       spin_unlock_irqrestore(&command_data->sp->lock, flags);
315 +
316 +       if (cmd->status != IBMASM_CMD_COMPLETE) {
317 +               command_put(cmd);
318 +               return -EIO;
319 +       }
320 +       len = min(count, cmd->buffer_size);
321 +       if ( copy_to_user(buf, cmd->buffer, len) ) {
322 +               command_put(cmd);
323 +               return -EFAULT;
324 +       }
325 +       command_put(cmd);
326 +
327 +       return len;
328 +}
329 +
330 +static ssize_t command_file_write(struct file *file, const char *ubuff, size_t count, loff_t *offset)
331 +{
332 +       struct ibmasmfs_command_data *command_data = file->private_data;
333 +       struct command *cmd;
334 +       unsigned long flags;
335 +
336 +       if (*offset < 0)
337 +               return -EINVAL;
338 +       if (count == 0 || count > IBMASM_CMD_MAX_BUFFER_SIZE)
339 +               return 0;
340 +       if (*offset != 0)
341 +               return 0;
342 +
343 +       /* commands are executed sequentially, only one command at a time */
344 +       if (command_data->command)
345 +               return -EAGAIN;
346 +
347 +       cmd = ibmasm_new_command(count);
348 +       if (!cmd)
349 +               return -ENOMEM;
350 +
351 +       if ( copy_from_user((void *)cmd->buffer, (void *)ubuff, count) ) {
352 +               command_put(cmd);
353 +               return -EFAULT;
354 +       }
355 +
356 +       spin_lock_irqsave(&command_data->sp->lock, flags);
357 +       if (command_data->command) {
358 +               spin_unlock_irqrestore(&command_data->sp->lock, flags);
359 +               command_put(cmd);
360 +               return -EAGAIN;
361 +       }
362 +       command_data->command = cmd;
363 +       spin_unlock_irqrestore(&command_data->sp->lock, flags);
364 +
365 +       ibmasm_exec_command(command_data->sp, cmd);
366 +       ibmasm_wait_for_response(cmd, get_dot_command_timeout(cmd->buffer));
367 +
368 +       return count;
369 +}
370 +
371 +static int command_file_ioctl(struct inode *inode, struct file *file, unsigned int ioctl_cmd, unsigned long arg)
372 +{
373 +       struct ibmasmfs_command_data *command_data = file->private_data;
374 +       struct command *cmd;
375 +       unsigned long flags;
376 +
377 +       if (ioctl_cmd != IBMASM_IO_CANCEL)
378 +               return -ENOTTY;
379 +
380 +       spin_lock_irqsave(&command_data->sp->lock, flags);
381 +       cmd = command_data->command;
382 +       if (cmd == NULL) {
383 +               spin_unlock_irqrestore(&command_data->sp->lock, flags);
384 +               return 0;
385 +       }
386 +       wake_up_interruptible(&cmd->wait);
387 +       spin_lock_irqsave(&command_data->sp->lock, flags);
388 +       return 0;
389 +}
390 +
391 +
392 +static int event_file_open(struct inode *inode, struct file *file)
393 +{
394 +       struct ibmasmfs_event_data *event_data;
395 +       struct service_processor *sp; 
396 +
397 +       if ( !inode->u.generic_ip )
398 +               return -ENODEV;
399 +
400 +       sp = inode->u.generic_ip;
401 +
402 +       event_data = kmalloc(sizeof(struct ibmasmfs_event_data), GFP_KERNEL);
403 +       if (!event_data)
404 +               return -ENOMEM;
405 +
406 +       ibmasm_event_reader_register(sp, &event_data->reader);
407 +
408 +       event_data->sp = sp;
409 +       file->private_data = event_data;
410 +       return 0;
411 +}
412 +
413 +static int event_file_close(struct inode *inode, struct file *file)
414 +{
415 +       struct ibmasmfs_event_data *event_data = file->private_data;
416 +
417 +       ibmasm_event_reader_unregister(event_data->sp, &event_data->reader);
418 +       kfree(event_data);
419 +       return 0;
420 +}
421 +
422 +static ssize_t event_file_read(struct file *file, char *buf, size_t count, loff_t *offset)
423 +{
424 +       struct ibmasmfs_event_data *event_data = file->private_data;
425 +       struct event_reader *reader = &event_data->reader;
426 +       int ret;
427 +
428 +       if (*offset < 0)
429 +               return -EINVAL;
430 +       if (count == 0 || count > IBMASM_EVENT_MAX_SIZE)
431 +               return 0;
432 +       if (*offset != 0)
433 +               return 0;
434 +
435 +       ret = ibmasm_get_next_event(event_data->sp, reader);
436 +       if (ret <= 0)
437 +               return ret;
438 +
439 +       if (count < reader->data_size)
440 +               return -EINVAL;
441 +
442 +        if (copy_to_user(buf, reader->data, reader->data_size))
443 +               return -EFAULT;
444 +
445 +       return reader->data_size;
446 +}
447 +
448 +static int event_file_ioctl(struct inode *inode, struct file *file, unsigned int ioctl_cmd, unsigned long arg)
449 +{
450 +       struct ibmasmfs_event_data *event_data = file->private_data;
451 +
452 +       if (ioctl_cmd != IBMASM_IO_CANCEL)
453 +               return -ENOTTY;
454 +
455 +       wake_up_interruptible(&event_data->reader.wait);
456 +       return 0;
457 +}
458 +
459 +static int r_heartbeat_file_open(struct inode *inode, struct file *file)
460 +{
461 +       struct ibmasmfs_heartbeat_data *rhbeat;
462 +
463 +       if ( !inode->u.generic_ip )
464 +               return -ENODEV;
465 +
466 +       rhbeat = kmalloc(sizeof(struct ibmasmfs_heartbeat_data), GFP_KERNEL);
467 +       if (!rhbeat)
468 +               return -ENOMEM;
469 +
470 +       rhbeat->sp = (struct service_processor *)inode->u.generic_ip;
471 +       rhbeat->lock = SPIN_LOCK_UNLOCKED;
472 +       rhbeat->active = 0;
473 +       ibmasm_init_reverse_heartbeat(rhbeat->sp, &rhbeat->heartbeat);
474 +       file->private_data = rhbeat;
475 +       return 0;
476 +}
477 +
478 +static int r_heartbeat_file_close(struct inode *inode, struct file *file)
479 +{
480 +       struct ibmasmfs_heartbeat_data *rhbeat = file->private_data;
481 +
482 +       kfree(rhbeat);
483 +       return 0;
484 +}
485 +
486 +static ssize_t r_heartbeat_file_read(struct file *file, char *buf, size_t count, loff_t *offset)
487 +{
488 +       struct ibmasmfs_heartbeat_data *rhbeat = file->private_data;
489 +       unsigned long flags;
490 +       int result;
491 +
492 +       if (*offset < 0)
493 +               return -EINVAL;
494 +       if (count == 0 || count > 1024)
495 +               return 0;
496 +       if (*offset != 0)
497 +               return 0;
498 +
499 +       /* allow only one reverse heartbeat per process */
500 +       spin_lock_irqsave(&rhbeat->lock, flags);
501 +       if (rhbeat->active) {
502 +               spin_unlock_irqrestore(&rhbeat->lock, flags);
503 +               return -EBUSY;
504 +       }
505 +       rhbeat->active = 1;
506 +       spin_unlock_irqrestore(&rhbeat->lock, flags);
507 +
508 +       result = ibmasm_start_reverse_heartbeat(rhbeat->sp, &rhbeat->heartbeat);
509 +
510 +       spin_lock_irqsave(&rhbeat->lock, flags);
511 +       rhbeat->active = 0;
512 +       ibmasm_init_reverse_heartbeat(rhbeat->sp, &rhbeat->heartbeat);
513 +       spin_unlock_irqrestore(&rhbeat->lock, flags);
514 +
515 +       return result;
516 +}
517 +
518 +static int r_heartbeat_file_ioctl(struct inode *inode, struct file *file, unsigned int ioctl_cmd, unsigned long arg)
519 +{
520 +       struct ibmasmfs_heartbeat_data *rhbeat = file->private_data;
521 +       unsigned long flags;
522 +
523 +       if (ioctl_cmd != IBMASM_IO_CANCEL)
524 +               return -ENOTTY;
525 +
526 +       spin_lock_irqsave(&rhbeat->lock, flags);
527 +       if (!rhbeat->active) {
528 +               spin_unlock_irqrestore(&rhbeat->lock, flags);
529 +               return 0;
530 +       }
531 +       spin_unlock_irqrestore(&rhbeat->lock, flags);
532 +
533 +       ibmasm_stop_reverse_heartbeat(&rhbeat->heartbeat);
534 +       return 0;
535 +}
536 +
537 +static int remote_settings_file_open(struct inode *inode, struct file *file)
538 +{
539 +       file->private_data = inode->u.generic_ip;
540 +       return 0;
541 +}
542 +
543 +static int remote_settings_file_close(struct inode *inode, struct file *file)
544 +{
545 +       return 0;
546 +}
547 +
548 +static ssize_t remote_settings_file_read(struct file *file, char *buf, size_t count, loff_t *offset)
549 +{
550 +       unsigned long address = (unsigned long)file->private_data;
551 +       unsigned char *page;
552 +       int retval;
553 +       int len = 0;
554 +       unsigned int value;
555 +
556 +       if (*offset < 0)
557 +               return -EINVAL;
558 +       if (count == 0 || count > 1024)
559 +               return 0;
560 +       if (*offset != 0)
561 +               return 0;
562 +
563 +       page = (unsigned char *)__get_free_page(GFP_KERNEL);
564 +       if (!page)
565 +               return -ENOMEM;
566 +
567 +       value = readl(address);
568 +       len = sprintf(page, "%d\n", value);
569 +
570 +       if (copy_to_user(buf, page, len)) {
571 +               retval = -EFAULT;
572 +               goto exit;
573 +       }
574 +       *offset += len;
575 +       retval = len;
576 +
577 +exit:
578 +       free_page((unsigned long)page);
579 +       return retval;
580 +}
581 +
582 +static ssize_t remote_settings_file_write(struct file *file, const char *ubuff, size_t count, loff_t *offset)
583 +{
584 +       unsigned long address = (unsigned long)file->private_data;
585 +       char *buff;
586 +       unsigned int value;
587 +
588 +       if (*offset < 0)
589 +               return -EINVAL;
590 +       if (count == 0 || count > 1024)
591 +               return 0;
592 +       if (*offset != 0)
593 +               return 0;
594 +
595 +       buff = kmalloc (count + 1, GFP_KERNEL);
596 +       if (!buff)
597 +               return -ENOMEM;
598 +
599 +       memset(buff, 0x0, count + 1);
600 +
601 +       if ( copy_from_user((void *)buff, (void *)ubuff, count) ) {
602 +               kfree(buff);
603 +               return -EFAULT;
604 +       }
605 +       
606 +       value = simple_strtoul(buff, NULL, 10);
607 +       writel(value, address);
608 +       kfree(buff);
609 +
610 +       return count;
611 +}
612 +
613 +static int remote_event_file_open(struct inode *inode, struct file *file)
614 +{
615 +       struct service_processor *sp;
616 +       unsigned long flags;
617 +       struct remote_queue *q;
618 +       
619 +       file->private_data = inode->u.generic_ip;
620 +       sp = file->private_data;
621 +       q = &sp->remote_queue;
622 +
623 +       /* allow only one event reader */
624 +       spin_lock_irqsave(&sp->lock, flags);
625 +       if (q->open) {
626 +               spin_unlock_irqrestore(&sp->lock, flags);
627 +               return -EBUSY;
628 +       }
629 +       q->open = 1;
630 +       spin_unlock_irqrestore(&sp->lock, flags);
631 +
632 +       enable_mouse_interrupts(sp);
633 +       
634 +       return 0;
635 +}
636 +
637 +static int remote_event_file_close(struct inode *inode, struct file *file)
638 +{
639 +       struct service_processor *sp = file->private_data;
640 +
641 +       disable_mouse_interrupts(sp);
642 +       wake_up_interruptible(&sp->remote_queue.wait);
643 +       sp->remote_queue.open = 0;
644 +
645 +       return 0;
646 +}
647 +
648 +static ssize_t remote_event_file_read(struct file *file, char *buf, size_t count, loff_t *offset)
649 +{
650 +       struct service_processor *sp = file->private_data;
651 +       struct remote_queue *q = &sp->remote_queue;
652 +       size_t data_size;
653 +       struct remote_event *reader = q->reader;
654 +       size_t num_events;
655 +
656 +       if (wait_event_interruptible(q->wait, q->reader != q->writer))
657 +               return -ERESTARTSYS;
658 +
659 +       /* only get multiples of struct remote_event */
660 +       num_events = min((count/sizeof(struct remote_event)), ibmasm_events_available(q));
661 +       if (!num_events)
662 +               return 0;
663 +
664 +       data_size = num_events * sizeof(struct remote_event);
665 +
666 +       if (copy_to_user(buf, reader, data_size))
667 +               return -EFAULT;
668 +
669 +       ibmasm_advance_reader(q, num_events);
670 +
671 +       return data_size;
672 +}
673 +
674 +
675 +static struct file_operations command_fops = {
676 +       .open =         command_file_open,
677 +       .release =      command_file_close,
678 +       .read =         command_file_read,
679 +       .write =        command_file_write,
680 +       .ioctl =        command_file_ioctl,
681 +};
682 +
683 +static struct file_operations event_fops = {
684 +       .open =         event_file_open,
685 +       .release =      event_file_close,
686 +       .read =         event_file_read,
687 +       .ioctl          event_file_ioctl,
688 +};
689 +
690 +static struct file_operations r_heartbeat_fops = {
691 +       .open =         r_heartbeat_file_open,
692 +       .release =      r_heartbeat_file_close,
693 +       .read =         r_heartbeat_file_read,
694 +       .ioctl =        r_heartbeat_file_ioctl,
695 +};
696 +
697 +static struct file_operations remote_settings_fops = {
698 +       .open =         remote_settings_file_open,
699 +       .release =      remote_settings_file_close,
700 +       .read =         remote_settings_file_read,
701 +       .write =        remote_settings_file_write,
702 +};
703 +
704 +static struct file_operations remote_event_fops = {
705 +       .open =         remote_event_file_open,
706 +       .release =      remote_event_file_close,
707 +       .read =         remote_event_file_read,
708 +};
709 +
710 +
711 +static void ibmasmfs_create_files (struct super_block *sb, struct dentry *root)
712 +{
713 +       struct list_head *entry;
714 +       struct service_processor *sp;
715 +
716 +       list_for_each(entry, &service_processors) {
717 +               struct dentry *dir;
718 +               struct dentry *remote_dir;
719 +               sp = list_entry(entry, struct service_processor, node);
720 +               dir = ibmasmfs_create_dir(sb, root, sp->dirname);
721 +               if (!dir)
722 +                       continue;
723 +
724 +               ibmasmfs_create_file(sb, dir, "command", &command_fops, sp, 0600);
725 +               ibmasmfs_create_file(sb, dir, "event", &event_fops, sp, 0400);
726 +               ibmasmfs_create_file(sb, dir, "reverse_heartbeat", &r_heartbeat_fops, sp, 0400);
727 +
728 +               remote_dir = ibmasmfs_create_dir(sb, dir, "remote_video");
729 +               if (!remote_dir)
730 +                       continue;
731 +
732 +               ibmasmfs_create_file(sb, remote_dir, "width", &remote_settings_fops, (void *)display_width(sp), 0600);
733 +               ibmasmfs_create_file(sb, remote_dir, "height", &remote_settings_fops, (void *)display_height(sp), 0600);
734 +               ibmasmfs_create_file(sb, remote_dir, "depth", &remote_settings_fops, (void *)display_depth(sp), 0600);
735 +               ibmasmfs_create_file(sb, remote_dir, "connected", &remote_settings_fops, (void *)vnc_status(sp), 0400);
736 +               ibmasmfs_create_file(sb, remote_dir, "events", &remote_event_fops, (void *)sp, 0400);
737 +       }
738 +}
This page took 0.084973 seconds and 3 git commands to generate.