2 * drivers/s390/char/vmlogrdr.c
3 * character device driver for reading z/VM system service records
6 * Copyright (C) 2004 IBM Corporation
7 * character device driver for reading z/VM system service records,
9 * Author(s): Xenia Tkatschow <xenia@us.ibm.com>
10 * Stefan Weinhuber <wein@de.ibm.com>
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <linux/errno.h>
16 #include <linux/types.h>
17 #include <linux/interrupt.h>
18 #include <linux/spinlock.h>
19 #include <asm/atomic.h>
20 #include <asm/uaccess.h>
21 #include <asm/cpcmd.h>
22 #include <asm/debug.h>
23 #include <asm/ebcdic.h>
24 #include "../net/iucv.h"
25 #include <linux/kmod.h>
26 #include <linux/cdev.h>
27 #include <linux/device.h>
28 #include <linux/string.h>
33 ("(C) 2004 IBM Corporation by Xenia Tkatschow (xenia@us.ibm.com)\n"
34 " Stefan Weinhuber (wein@de.ibm.com)");
35 MODULE_DESCRIPTION ("Character device driver for reading z/VM "
36 "system service records.");
37 MODULE_LICENSE("GPL");
41 * The size of the buffer for iucv data transfer is one page,
42 * but in addition to the data we read from iucv we also
43 * place an integer and some characters into that buffer,
44 * so the maximum size for record data is a little less then
47 #define NET_BUFFER_SIZE (PAGE_SIZE - sizeof(int) - sizeof(FENCE))
50 * The elements that are concurrently accessed by bottom halves are
51 * connection_established, iucv_path_severed, local_interrupt_buffer
52 * and receive_ready. The first three can be protected by
53 * priv_lock. receive_ready is atomic, so it can be incremented and
54 * decremented without holding a lock.
55 * The variable dev_in_use needs to be protected by the lock, since
56 * it's a flag used by open to make sure that the device is opened only
57 * by one user at the same time.
59 struct vmlogrdr_priv_t {
60 char system_service[8];
61 char internal_name[8];
62 char recording_name[8];
64 int connection_established;
65 int iucv_path_severed;
66 iucv_MessagePending local_interrupt_buffer;
67 atomic_t receive_ready;
68 iucv_handle_t iucv_handle;
71 char * current_position;
73 ulong residual_length;
75 int dev_in_use; /* 1: already opened, 0: not opened*/
77 struct device *device;
78 struct class_device *class_device;
85 * File operation structure for vmlogrdr devices
87 static int vmlogrdr_open(struct inode *, struct file *);
88 static int vmlogrdr_release(struct inode *, struct file *);
89 static ssize_t vmlogrdr_read (struct file *filp, char __user *data,
90 size_t count, loff_t * ppos);
92 static struct file_operations vmlogrdr_fops = {
94 .open = vmlogrdr_open,
95 .release = vmlogrdr_release,
96 .read = vmlogrdr_read,
100 static u8 iucvMagic[16] = {
101 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
102 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
107 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
108 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
109 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
110 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
114 static u8 iucv_host[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
118 vmlogrdr_iucv_ConnectionComplete(iucv_ConnectionComplete *eib, void *pgm_data);
120 vmlogrdr_iucv_ConnectionSevered(iucv_ConnectionSevered *eib, void *pgm_data);
122 vmlogrdr_iucv_MessagePending(iucv_MessagePending *eib, void *pgm_data);
125 static iucv_interrupt_ops_t vmlogrdr_iucvops = {
126 .ConnectionComplete = vmlogrdr_iucv_ConnectionComplete,
127 .ConnectionSevered = vmlogrdr_iucv_ConnectionSevered,
128 .MessagePending = vmlogrdr_iucv_MessagePending,
131 static DECLARE_WAIT_QUEUE_HEAD(conn_wait_queue);
132 static DECLARE_WAIT_QUEUE_HEAD(read_wait_queue);
135 * pointer to system service private structure
136 * minor number 0 --> logrec
137 * minor number 1 --> account
138 * minor number 2 --> symptom
141 static struct vmlogrdr_priv_t sys_ser[] = {
142 { .system_service = "*LOGREC ",
143 .internal_name = "logrec",
144 .recording_name = "EREP",
147 .priv_lock = SPIN_LOCK_UNLOCKED,
151 { .system_service = "*ACCOUNT",
152 .internal_name = "account",
153 .recording_name = "ACCOUNT",
156 .priv_lock = SPIN_LOCK_UNLOCKED,
160 { .system_service = "*SYMPTOM",
161 .internal_name = "symptom",
162 .recording_name = "SYMPTOM",
165 .priv_lock = SPIN_LOCK_UNLOCKED,
171 #define MAXMINOR (sizeof(sys_ser)/sizeof(struct vmlogrdr_priv_t))
173 static char FENCE[] = {"EOR"};
174 static int vmlogrdr_major = 0;
175 static struct cdev *vmlogrdr_cdev = NULL;
176 static int recording_class_AB;
180 vmlogrdr_iucv_ConnectionComplete (iucv_ConnectionComplete * eib,
183 struct vmlogrdr_priv_t * logptr = pgm_data;
184 spin_lock(&logptr->priv_lock);
185 logptr->connection_established = 1;
186 spin_unlock(&logptr->priv_lock);
187 wake_up(&conn_wait_queue);
193 vmlogrdr_iucv_ConnectionSevered (iucv_ConnectionSevered * eib, void * pgm_data)
195 u8 reason = (u8) eib->ipuser[8];
196 struct vmlogrdr_priv_t * logptr = pgm_data;
198 printk (KERN_ERR "vmlogrdr: connection severed with"
199 " reason %i\n", reason);
201 spin_lock(&logptr->priv_lock);
202 logptr->connection_established = 0;
203 logptr->iucv_path_severed = 1;
204 spin_unlock(&logptr->priv_lock);
206 wake_up(&conn_wait_queue);
207 /* just in case we're sleeping waiting for a record */
208 wake_up_interruptible(&read_wait_queue);
213 vmlogrdr_iucv_MessagePending (iucv_MessagePending * eib, void * pgm_data)
215 struct vmlogrdr_priv_t * logptr = pgm_data;
218 * This function is the bottom half so it should be quick.
219 * Copy the external interrupt data into our local eib and increment
222 spin_lock(&logptr->priv_lock);
223 memcpy(&(logptr->local_interrupt_buffer), eib, sizeof(*eib));
224 atomic_inc(&logptr->receive_ready);
225 spin_unlock(&logptr->priv_lock);
226 wake_up_interruptible(&read_wait_queue);
231 vmlogrdr_get_recording_class_AB(void) {
232 char cp_command[]="QUERY COMMAND RECORDING ";
233 char cp_response[80];
237 printk (KERN_DEBUG "vmlogrdr: query command: %s\n", cp_command);
238 cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
239 printk (KERN_DEBUG "vmlogrdr: response: %s", cp_response);
240 len = strnlen(cp_response,sizeof(cp_response));
242 tail=strnchr(cp_response,len,'=');
246 if (!strncmp("ANY",tail,3))
248 if (!strncmp("NONE",tail,4))
251 * expect comma separated list of classes here, if one of them
252 * is A or B return 1 otherwise 0
254 for (i=tail-cp_response; i<len; i++)
255 if ( cp_response[i]=='A' || cp_response[i]=='B' )
262 vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, int action, int purge) {
265 char cp_response[160];
266 char *onoff, *qid_string;
268 memset(cp_command, 0x00, sizeof(cp_command));
269 memset(cp_response, 0x00, sizeof(cp_response));
271 onoff = ((action == 1) ? "ON" : "OFF");
272 qid_string = ((recording_class_AB == 1) ? " QID * " : "");
275 * The recording commands needs to be called with option QID
276 * for guests that have previlege classes A or B.
277 * Purging has to be done as separate step, because recording
278 * can't be switched on as long as records are on the queue.
279 * Doing both at the same time doesn't work.
283 snprintf(cp_command, sizeof(cp_command),
284 "RECORDING %s PURGE %s",
285 logptr->recording_name,
288 printk (KERN_DEBUG "vmlogrdr: recording command: %s\n",
290 cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
291 printk (KERN_DEBUG "vmlogrdr: recording response: %s",
295 memset(cp_command, 0x00, sizeof(cp_command));
296 memset(cp_response, 0x00, sizeof(cp_response));
297 snprintf(cp_command, sizeof(cp_command), "RECORDING %s %s %s",
298 logptr->recording_name,
302 printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", cp_command);
303 cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
304 printk (KERN_DEBUG "vmlogrdr: recording response: %s",
306 /* The recording command will usually answer with 'Command complete'
307 * on success, but when the specific service was never connected
308 * before then there might be an additional informational message
309 * 'HCPCRC8072I Recording entry not found' before the
310 * 'Command complete'. So I use strstr rather then the strncmp.
312 if (strstr(cp_response,"Command complete"))
321 vmlogrdr_open (struct inode *inode, struct file *filp)
324 struct vmlogrdr_priv_t * logptr = NULL;
328 dev_num = iminor(inode);
329 if (dev_num > MAXMINOR)
332 logptr = &sys_ser[dev_num];
337 * only allow for blocking reads to be open
339 if (filp->f_flags & O_NONBLOCK)
342 /* Besure this device hasn't already been opened */
343 spin_lock_bh(&logptr->priv_lock);
344 if (logptr->dev_in_use) {
345 spin_unlock_bh(&logptr->priv_lock);
348 logptr->dev_in_use = 1;
349 spin_unlock_bh(&logptr->priv_lock);
352 atomic_set(&logptr->receive_ready, 0);
353 logptr->buffer_free = 1;
355 /* set the file options */
356 filp->private_data = logptr;
357 filp->f_op = &vmlogrdr_fops;
359 /* start recording for this service*/
361 if (logptr->autorecording)
362 ret = vmlogrdr_recording(logptr,1,logptr->autopurge);
364 printk (KERN_WARNING "vmlogrdr: failed to start "
365 "recording automatically\n");
367 /* Register with iucv driver */
368 logptr->iucv_handle = iucv_register_program(iucvMagic,
369 logptr->system_service, mask, &vmlogrdr_iucvops,
372 if (logptr->iucv_handle == NULL) {
373 printk (KERN_ERR "vmlogrdr: failed to register with"
378 /* create connection to the system service */
379 spin_lock_bh(&logptr->priv_lock);
380 logptr->connection_established = 0;
381 logptr->iucv_path_severed = 0;
382 spin_unlock_bh(&logptr->priv_lock);
384 connect_rc = iucv_connect (&(logptr->pathid), 10, iucvMagic,
385 logptr->system_service, iucv_host, 0,
387 logptr->iucv_handle, NULL);
389 printk (KERN_ERR "vmlogrdr: iucv connection to %s "
390 "failed with rc %i \n", logptr->system_service,
395 /* We've issued the connect and now we must wait for a
396 * ConnectionComplete or ConnectinSevered Interrupt
397 * before we can continue to process.
399 wait_event(conn_wait_queue, (logptr->connection_established)
400 || (logptr->iucv_path_severed));
401 if (logptr->iucv_path_severed) {
405 return nonseekable_open(inode, filp);
408 iucv_unregister_program(logptr->iucv_handle);
409 logptr->iucv_handle = NULL;
411 if (logptr->autorecording)
412 vmlogrdr_recording(logptr,0,logptr->autopurge);
413 logptr->dev_in_use = 0;
421 vmlogrdr_release (struct inode *inode, struct file *filp)
425 struct vmlogrdr_priv_t * logptr = filp->private_data;
427 iucv_unregister_program(logptr->iucv_handle);
428 logptr->iucv_handle = NULL;
430 if (logptr->autorecording) {
431 ret = vmlogrdr_recording(logptr,0,logptr->autopurge);
433 printk (KERN_WARNING "vmlogrdr: failed to stop "
434 "recording automatically\n");
436 logptr->dev_in_use = 0;
443 vmlogrdr_receive_data(struct vmlogrdr_priv_t *priv) {
445 /* we need to keep track of two data sizes here:
446 * The number of bytes we need to receive from iucv and
447 * the total number of bytes we actually write into the buffer.
449 int user_data_count, iucv_data_count;
452 if (atomic_read(&priv->receive_ready)) {
453 spin_lock_bh(&priv->priv_lock);
454 if (priv->residual_length){
455 /* receive second half of a record */
456 iucv_data_count = priv->residual_length;
458 buffer = priv->buffer;
460 /* receive a new record:
461 * We need to return the total length of the record
462 * + size of FENCE in the first 4 bytes of the buffer.
465 priv->local_interrupt_buffer.ln1msg2.ipbfln1f;
466 user_data_count = sizeof(int);
467 temp = (int*)priv->buffer;
468 *temp= iucv_data_count + sizeof(FENCE);
469 buffer = priv->buffer + sizeof(int);
472 * If the record is bigger then our buffer, we receive only
473 * a part of it. We can get the rest later.
475 if (iucv_data_count > NET_BUFFER_SIZE)
476 iucv_data_count = NET_BUFFER_SIZE;
477 rc = iucv_receive(priv->pathid,
478 priv->local_interrupt_buffer.ipmsgid,
479 priv->local_interrupt_buffer.iptrgcls,
484 &priv->residual_length);
485 spin_unlock_bh(&priv->priv_lock);
486 /* An rc of 5 indicates that the record was bigger then
487 * the buffer, which is OK for us. A 9 indicates that the
488 * record was purged befor we could receive it.
493 atomic_set(&priv->receive_ready, 0);
498 priv->buffer_free = 0;
499 user_data_count += iucv_data_count;
500 priv->current_position = priv->buffer;
501 if (priv->residual_length == 0){
502 /* the whole record has been captured,
503 * now add the fence */
504 atomic_dec(&priv->receive_ready);
505 buffer = priv->buffer + user_data_count;
506 memcpy(buffer, FENCE, sizeof(FENCE));
507 user_data_count += sizeof(FENCE);
509 priv->remaining = user_data_count;
517 vmlogrdr_read(struct file *filp, char __user *data, size_t count, loff_t * ppos)
520 struct vmlogrdr_priv_t * priv = filp->private_data;
522 while (priv->buffer_free) {
523 rc = vmlogrdr_receive_data(priv);
525 rc = wait_event_interruptible(read_wait_queue,
526 atomic_read(&priv->receive_ready));
531 /* copy only up to end of record */
532 if (count > priv->remaining)
533 count = priv->remaining;
535 if (copy_to_user(data, priv->current_position, count))
539 priv->current_position += count;
540 priv->remaining -= count;
542 /* if all data has been transferred, set buffer free */
543 if (priv->remaining == 0)
544 priv->buffer_free = 1;
550 vmlogrdr_autopurge_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t count) {
551 struct vmlogrdr_priv_t *priv = dev->driver_data;
569 vmlogrdr_autopurge_show(struct device *dev, struct device_attribute *attr, char *buf) {
570 struct vmlogrdr_priv_t *priv = dev->driver_data;
571 return sprintf(buf, "%u\n", priv->autopurge);
575 static DEVICE_ATTR(autopurge, 0644, vmlogrdr_autopurge_show,
576 vmlogrdr_autopurge_store);
580 vmlogrdr_purge_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t count) {
583 char cp_response[80];
584 struct vmlogrdr_priv_t *priv = dev->driver_data;
589 memset(cp_command, 0x00, sizeof(cp_command));
590 memset(cp_response, 0x00, sizeof(cp_response));
593 * The recording command needs to be called with option QID
594 * for guests that have previlege classes A or B.
595 * Other guests will not recognize the command and we have to
596 * issue the same command without the QID parameter.
599 if (recording_class_AB)
600 snprintf(cp_command, sizeof(cp_command),
601 "RECORDING %s PURGE QID * ",
602 priv->recording_name);
604 snprintf(cp_command, sizeof(cp_command),
605 "RECORDING %s PURGE ",
606 priv->recording_name);
608 printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", cp_command);
609 cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
610 printk (KERN_DEBUG "vmlogrdr: recording response: %s",
617 static DEVICE_ATTR(purge, 0200, NULL, vmlogrdr_purge_store);
621 vmlogrdr_autorecording_store(struct device *dev, struct device_attribute *attr, const char *buf,
623 struct vmlogrdr_priv_t *priv = dev->driver_data;
628 priv->autorecording=0;
631 priv->autorecording=1;
641 vmlogrdr_autorecording_show(struct device *dev, struct device_attribute *attr, char *buf) {
642 struct vmlogrdr_priv_t *priv = dev->driver_data;
643 return sprintf(buf, "%u\n", priv->autorecording);
647 static DEVICE_ATTR(autorecording, 0644, vmlogrdr_autorecording_show,
648 vmlogrdr_autorecording_store);
652 vmlogrdr_recording_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t count) {
654 struct vmlogrdr_priv_t *priv = dev->driver_data;
659 ret = vmlogrdr_recording(priv,0,0);
662 ret = vmlogrdr_recording(priv,1,0);
675 static DEVICE_ATTR(recording, 0200, NULL, vmlogrdr_recording_store);
679 vmlogrdr_recording_status_show(struct device_driver *driver, char *buf) {
681 char cp_command[] = "QUERY RECORDING ";
684 cpcmd(cp_command, buf, 4096, NULL);
690 static DRIVER_ATTR(recording_status, 0444, vmlogrdr_recording_status_show,
693 static struct attribute *vmlogrdr_attrs[] = {
694 &dev_attr_autopurge.attr,
695 &dev_attr_purge.attr,
696 &dev_attr_autorecording.attr,
697 &dev_attr_recording.attr,
701 static struct attribute_group vmlogrdr_attr_group = {
702 .attrs = vmlogrdr_attrs,
705 static struct class *vmlogrdr_class;
706 static struct device_driver vmlogrdr_driver = {
713 vmlogrdr_register_driver(void) {
716 ret = driver_register(&vmlogrdr_driver);
718 printk(KERN_ERR "vmlogrdr: failed to register driver.\n");
722 ret = driver_create_file(&vmlogrdr_driver,
723 &driver_attr_recording_status);
725 printk(KERN_ERR "vmlogrdr: failed to add driver attribute.\n");
729 vmlogrdr_class = class_create(THIS_MODULE, "vmlogrdr");
730 if (IS_ERR(vmlogrdr_class)) {
731 printk(KERN_ERR "vmlogrdr: failed to create class.\n");
732 ret=PTR_ERR(vmlogrdr_class);
739 driver_remove_file(&vmlogrdr_driver, &driver_attr_recording_status);
741 driver_unregister(&vmlogrdr_driver);
747 vmlogrdr_unregister_driver(void) {
748 class_destroy(vmlogrdr_class);
749 vmlogrdr_class = NULL;
750 driver_remove_file(&vmlogrdr_driver, &driver_attr_recording_status);
751 driver_unregister(&vmlogrdr_driver);
757 vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) {
761 dev = kzalloc(sizeof(struct device), GFP_KERNEL);
763 snprintf(dev->bus_id, BUS_ID_SIZE, "%s",
764 priv->internal_name);
765 dev->bus = &iucv_bus;
766 dev->parent = iucv_root;
767 dev->driver = &vmlogrdr_driver;
769 * The release function could be called after the
770 * module has been unloaded. It's _only_ task is to
771 * free the struct. Therefore, we specify kfree()
772 * directly here. (Probably a little bit obfuscating
775 dev->release = (void (*)(struct device *))kfree;
778 ret = device_register(dev);
782 ret = sysfs_create_group(&dev->kobj, &vmlogrdr_attr_group);
784 device_unregister(dev);
787 priv->class_device = class_device_create(
790 MKDEV(vmlogrdr_major, priv->minor_num),
793 if (IS_ERR(priv->class_device)) {
794 ret = PTR_ERR(priv->class_device);
795 priv->class_device=NULL;
796 sysfs_remove_group(&dev->kobj, &vmlogrdr_attr_group);
797 device_unregister(dev);
800 dev->driver_data = priv;
807 vmlogrdr_unregister_device(struct vmlogrdr_priv_t *priv ) {
808 class_device_destroy(vmlogrdr_class, MKDEV(vmlogrdr_major, priv->minor_num));
809 if (priv->device != NULL) {
810 sysfs_remove_group(&priv->device->kobj, &vmlogrdr_attr_group);
811 device_unregister(priv->device);
819 vmlogrdr_register_cdev(dev_t dev) {
821 vmlogrdr_cdev = cdev_alloc();
822 if (!vmlogrdr_cdev) {
825 vmlogrdr_cdev->owner = THIS_MODULE;
826 vmlogrdr_cdev->ops = &vmlogrdr_fops;
827 vmlogrdr_cdev->dev = dev;
828 rc = cdev_add(vmlogrdr_cdev, vmlogrdr_cdev->dev, MAXMINOR);
832 // cleanup: cdev is not fully registered, no cdev_del here!
833 kobject_put(&vmlogrdr_cdev->kobj);
840 vmlogrdr_cleanup(void) {
843 cdev_del(vmlogrdr_cdev);
846 for (i=0; i < MAXMINOR; ++i ) {
847 vmlogrdr_unregister_device(&sys_ser[i]);
848 free_page((unsigned long)sys_ser[i].buffer);
850 vmlogrdr_unregister_driver();
851 if (vmlogrdr_major) {
852 unregister_chrdev_region(MKDEV(vmlogrdr_major, 0), MAXMINOR);
865 if (! MACHINE_IS_VM) {
866 printk (KERN_ERR "vmlogrdr: not running under VM, "
867 "driver not loaded.\n");
871 recording_class_AB = vmlogrdr_get_recording_class_AB();
873 rc = alloc_chrdev_region(&dev, 0, MAXMINOR, "vmlogrdr");
876 vmlogrdr_major = MAJOR(dev);
878 rc=vmlogrdr_register_driver();
882 for (i=0; i < MAXMINOR; ++i ) {
883 sys_ser[i].buffer = (char *) get_zeroed_page(GFP_KERNEL);
884 if (!sys_ser[i].buffer) {
888 sys_ser[i].current_position = sys_ser[i].buffer;
889 rc=vmlogrdr_register_device(&sys_ser[i]);
896 rc = vmlogrdr_register_cdev(dev);
899 printk (KERN_INFO "vmlogrdr: driver loaded\n");
904 printk (KERN_ERR "vmlogrdr: driver not loaded.\n");
913 printk (KERN_INFO "vmlogrdr: driver unloaded\n");
918 module_init(vmlogrdr_init);
919 module_exit(vmlogrdr_exit);