1 /* 2 * drivers/s390/char/vmlogrdr.c 3 * character device driver for reading z/VM system service records 4 * 5 * 6 * Copyright 2004 IBM Corporation 7 * character device driver for reading z/VM system service records, 8 * Version 1.0 9 * Author(s): Xenia Tkatschow <xenia@us.ibm.com> 10 * Stefan Weinhuber <wein@de.ibm.com> 11 * 12 */ 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/iucv.h> 25 #include <linux/kmod.h> 26 #include <linux/cdev.h> 27 #include <linux/device.h> 28 #include <linux/string.h> 29 30 31 32 MODULE_AUTHOR 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"); 38 39 40 /* 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 45 * one page. 46 */ 47 #define NET_BUFFER_SIZE (PAGE_SIZE - sizeof(int) - sizeof(FENCE)) 48 49 /* 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. 58 */ 59 struct vmlogrdr_priv_t { 60 char system_service[8]; 61 char internal_name[8]; 62 char recording_name[8]; 63 struct iucv_path *path; 64 int connection_established; 65 int iucv_path_severed; 66 struct iucv_message local_interrupt_buffer; 67 atomic_t receive_ready; 68 int minor_num; 69 char * buffer; 70 char * current_position; 71 int remaining; 72 ulong residual_length; 73 int buffer_free; 74 int dev_in_use; /* 1: already opened, 0: not opened*/ 75 spinlock_t priv_lock; 76 struct device *device; 77 struct class_device *class_device; 78 int autorecording; 79 int autopurge; 80 }; 81 82 83 /* 84 * File operation structure for vmlogrdr devices 85 */ 86 static int vmlogrdr_open(struct inode *, struct file *); 87 static int vmlogrdr_release(struct inode *, struct file *); 88 static ssize_t vmlogrdr_read (struct file *filp, char __user *data, 89 size_t count, loff_t * ppos); 90 91 static const struct file_operations vmlogrdr_fops = { 92 .owner = THIS_MODULE, 93 .open = vmlogrdr_open, 94 .release = vmlogrdr_release, 95 .read = vmlogrdr_read, 96 }; 97 98 99 static void vmlogrdr_iucv_path_complete(struct iucv_path *, u8 ipuser[16]); 100 static void vmlogrdr_iucv_path_severed(struct iucv_path *, u8 ipuser[16]); 101 static void vmlogrdr_iucv_message_pending(struct iucv_path *, 102 struct iucv_message *); 103 104 105 static struct iucv_handler vmlogrdr_iucv_handler = { 106 .path_complete = vmlogrdr_iucv_path_complete, 107 .path_severed = vmlogrdr_iucv_path_severed, 108 .message_pending = vmlogrdr_iucv_message_pending, 109 }; 110 111 112 static DECLARE_WAIT_QUEUE_HEAD(conn_wait_queue); 113 static DECLARE_WAIT_QUEUE_HEAD(read_wait_queue); 114 115 /* 116 * pointer to system service private structure 117 * minor number 0 --> logrec 118 * minor number 1 --> account 119 * minor number 2 --> symptom 120 */ 121 122 static struct vmlogrdr_priv_t sys_ser[] = { 123 { .system_service = "*LOGREC ", 124 .internal_name = "logrec", 125 .recording_name = "EREP", 126 .minor_num = 0, 127 .buffer_free = 1, 128 .priv_lock = __SPIN_LOCK_UNLOCKED(sys_ser[0].priv_lock), 129 .autorecording = 1, 130 .autopurge = 1, 131 }, 132 { .system_service = "*ACCOUNT", 133 .internal_name = "account", 134 .recording_name = "ACCOUNT", 135 .minor_num = 1, 136 .buffer_free = 1, 137 .priv_lock = __SPIN_LOCK_UNLOCKED(sys_ser[1].priv_lock), 138 .autorecording = 1, 139 .autopurge = 1, 140 }, 141 { .system_service = "*SYMPTOM", 142 .internal_name = "symptom", 143 .recording_name = "SYMPTOM", 144 .minor_num = 2, 145 .buffer_free = 1, 146 .priv_lock = __SPIN_LOCK_UNLOCKED(sys_ser[2].priv_lock), 147 .autorecording = 1, 148 .autopurge = 1, 149 } 150 }; 151 152 #define MAXMINOR (sizeof(sys_ser)/sizeof(struct vmlogrdr_priv_t)) 153 154 static char FENCE[] = {"EOR"}; 155 static int vmlogrdr_major = 0; 156 static struct cdev *vmlogrdr_cdev = NULL; 157 static int recording_class_AB; 158 159 160 static void vmlogrdr_iucv_path_complete(struct iucv_path *path, u8 ipuser[16]) 161 { 162 struct vmlogrdr_priv_t * logptr = path->private; 163 164 spin_lock(&logptr->priv_lock); 165 logptr->connection_established = 1; 166 spin_unlock(&logptr->priv_lock); 167 wake_up(&conn_wait_queue); 168 } 169 170 171 static void vmlogrdr_iucv_path_severed(struct iucv_path *path, u8 ipuser[16]) 172 { 173 struct vmlogrdr_priv_t * logptr = path->private; 174 u8 reason = (u8) ipuser[8]; 175 176 printk (KERN_ERR "vmlogrdr: connection severed with" 177 " reason %i\n", reason); 178 179 iucv_path_sever(path, NULL); 180 kfree(path); 181 logptr->path = NULL; 182 183 spin_lock(&logptr->priv_lock); 184 logptr->connection_established = 0; 185 logptr->iucv_path_severed = 1; 186 spin_unlock(&logptr->priv_lock); 187 188 wake_up(&conn_wait_queue); 189 /* just in case we're sleeping waiting for a record */ 190 wake_up_interruptible(&read_wait_queue); 191 } 192 193 194 static void vmlogrdr_iucv_message_pending(struct iucv_path *path, 195 struct iucv_message *msg) 196 { 197 struct vmlogrdr_priv_t * logptr = path->private; 198 199 /* 200 * This function is the bottom half so it should be quick. 201 * Copy the external interrupt data into our local eib and increment 202 * the usage count 203 */ 204 spin_lock(&logptr->priv_lock); 205 memcpy(&logptr->local_interrupt_buffer, msg, sizeof(*msg)); 206 atomic_inc(&logptr->receive_ready); 207 spin_unlock(&logptr->priv_lock); 208 wake_up_interruptible(&read_wait_queue); 209 } 210 211 212 static int vmlogrdr_get_recording_class_AB(void) 213 { 214 char cp_command[]="QUERY COMMAND RECORDING "; 215 char cp_response[80]; 216 char *tail; 217 int len,i; 218 219 printk (KERN_DEBUG "vmlogrdr: query command: %s\n", cp_command); 220 cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); 221 printk (KERN_DEBUG "vmlogrdr: response: %s", cp_response); 222 len = strnlen(cp_response,sizeof(cp_response)); 223 // now the parsing 224 tail=strnchr(cp_response,len,'='); 225 if (!tail) 226 return 0; 227 tail++; 228 if (!strncmp("ANY",tail,3)) 229 return 1; 230 if (!strncmp("NONE",tail,4)) 231 return 0; 232 /* 233 * expect comma separated list of classes here, if one of them 234 * is A or B return 1 otherwise 0 235 */ 236 for (i=tail-cp_response; i<len; i++) 237 if ( cp_response[i]=='A' || cp_response[i]=='B' ) 238 return 1; 239 return 0; 240 } 241 242 243 static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, 244 int action, int purge) 245 { 246 247 char cp_command[80]; 248 char cp_response[160]; 249 char *onoff, *qid_string; 250 251 memset(cp_command, 0x00, sizeof(cp_command)); 252 memset(cp_response, 0x00, sizeof(cp_response)); 253 254 onoff = ((action == 1) ? "ON" : "OFF"); 255 qid_string = ((recording_class_AB == 1) ? " QID * " : ""); 256 257 /* 258 * The recording commands needs to be called with option QID 259 * for guests that have previlege classes A or B. 260 * Purging has to be done as separate step, because recording 261 * can't be switched on as long as records are on the queue. 262 * Doing both at the same time doesn't work. 263 */ 264 265 if (purge) { 266 snprintf(cp_command, sizeof(cp_command), 267 "RECORDING %s PURGE %s", 268 logptr->recording_name, 269 qid_string); 270 271 printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", 272 cp_command); 273 cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); 274 printk (KERN_DEBUG "vmlogrdr: recording response: %s", 275 cp_response); 276 } 277 278 memset(cp_command, 0x00, sizeof(cp_command)); 279 memset(cp_response, 0x00, sizeof(cp_response)); 280 snprintf(cp_command, sizeof(cp_command), "RECORDING %s %s %s", 281 logptr->recording_name, 282 onoff, 283 qid_string); 284 285 printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", cp_command); 286 cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); 287 printk (KERN_DEBUG "vmlogrdr: recording response: %s", 288 cp_response); 289 /* The recording command will usually answer with 'Command complete' 290 * on success, but when the specific service was never connected 291 * before then there might be an additional informational message 292 * 'HCPCRC8072I Recording entry not found' before the 293 * 'Command complete'. So I use strstr rather then the strncmp. 294 */ 295 if (strstr(cp_response,"Command complete")) 296 return 0; 297 else 298 return -EIO; 299 300 } 301 302 303 static int vmlogrdr_open (struct inode *inode, struct file *filp) 304 { 305 int dev_num = 0; 306 struct vmlogrdr_priv_t * logptr = NULL; 307 int connect_rc = 0; 308 int ret; 309 310 dev_num = iminor(inode); 311 if (dev_num > MAXMINOR) 312 return -ENODEV; 313 logptr = &sys_ser[dev_num]; 314 315 /* 316 * only allow for blocking reads to be open 317 */ 318 if (filp->f_flags & O_NONBLOCK) 319 return -ENOSYS; 320 321 /* Besure this device hasn't already been opened */ 322 spin_lock_bh(&logptr->priv_lock); 323 if (logptr->dev_in_use) { 324 spin_unlock_bh(&logptr->priv_lock); 325 return -EBUSY; 326 } 327 logptr->dev_in_use = 1; 328 logptr->connection_established = 0; 329 logptr->iucv_path_severed = 0; 330 atomic_set(&logptr->receive_ready, 0); 331 logptr->buffer_free = 1; 332 spin_unlock_bh(&logptr->priv_lock); 333 334 /* set the file options */ 335 filp->private_data = logptr; 336 filp->f_op = &vmlogrdr_fops; 337 338 /* start recording for this service*/ 339 if (logptr->autorecording) { 340 ret = vmlogrdr_recording(logptr,1,logptr->autopurge); 341 if (ret) 342 printk (KERN_WARNING "vmlogrdr: failed to start " 343 "recording automatically\n"); 344 } 345 346 /* create connection to the system service */ 347 logptr->path = iucv_path_alloc(10, 0, GFP_KERNEL); 348 if (!logptr->path) 349 goto out_dev; 350 connect_rc = iucv_path_connect(logptr->path, &vmlogrdr_iucv_handler, 351 logptr->system_service, NULL, NULL, 352 logptr); 353 if (connect_rc) { 354 printk (KERN_ERR "vmlogrdr: iucv connection to %s " 355 "failed with rc %i \n", logptr->system_service, 356 connect_rc); 357 goto out_path; 358 } 359 360 /* We've issued the connect and now we must wait for a 361 * ConnectionComplete or ConnectinSevered Interrupt 362 * before we can continue to process. 363 */ 364 wait_event(conn_wait_queue, (logptr->connection_established) 365 || (logptr->iucv_path_severed)); 366 if (logptr->iucv_path_severed) 367 goto out_record; 368 return nonseekable_open(inode, filp); 369 370 out_record: 371 if (logptr->autorecording) 372 vmlogrdr_recording(logptr,0,logptr->autopurge); 373 out_path: 374 kfree(logptr->path); /* kfree(NULL) is ok. */ 375 logptr->path = NULL; 376 out_dev: 377 logptr->dev_in_use = 0; 378 return -EIO; 379 } 380 381 382 static int vmlogrdr_release (struct inode *inode, struct file *filp) 383 { 384 int ret; 385 386 struct vmlogrdr_priv_t * logptr = filp->private_data; 387 388 iucv_path_sever(logptr->path, NULL); 389 kfree(logptr->path); 390 logptr->path = NULL; 391 if (logptr->autorecording) { 392 ret = vmlogrdr_recording(logptr,0,logptr->autopurge); 393 if (ret) 394 printk (KERN_WARNING "vmlogrdr: failed to stop " 395 "recording automatically\n"); 396 } 397 logptr->dev_in_use = 0; 398 399 return 0; 400 } 401 402 403 static int vmlogrdr_receive_data(struct vmlogrdr_priv_t *priv) 404 { 405 int rc, *temp; 406 /* we need to keep track of two data sizes here: 407 * The number of bytes we need to receive from iucv and 408 * the total number of bytes we actually write into the buffer. 409 */ 410 int user_data_count, iucv_data_count; 411 char * buffer; 412 413 if (atomic_read(&priv->receive_ready)) { 414 spin_lock_bh(&priv->priv_lock); 415 if (priv->residual_length){ 416 /* receive second half of a record */ 417 iucv_data_count = priv->residual_length; 418 user_data_count = 0; 419 buffer = priv->buffer; 420 } else { 421 /* receive a new record: 422 * We need to return the total length of the record 423 * + size of FENCE in the first 4 bytes of the buffer. 424 */ 425 iucv_data_count = priv->local_interrupt_buffer.length; 426 user_data_count = sizeof(int); 427 temp = (int*)priv->buffer; 428 *temp= iucv_data_count + sizeof(FENCE); 429 buffer = priv->buffer + sizeof(int); 430 } 431 /* 432 * If the record is bigger then our buffer, we receive only 433 * a part of it. We can get the rest later. 434 */ 435 if (iucv_data_count > NET_BUFFER_SIZE) 436 iucv_data_count = NET_BUFFER_SIZE; 437 rc = iucv_message_receive(priv->path, 438 &priv->local_interrupt_buffer, 439 0, buffer, iucv_data_count, 440 &priv->residual_length); 441 spin_unlock_bh(&priv->priv_lock); 442 /* An rc of 5 indicates that the record was bigger then 443 * the buffer, which is OK for us. A 9 indicates that the 444 * record was purged befor we could receive it. 445 */ 446 if (rc == 5) 447 rc = 0; 448 if (rc == 9) 449 atomic_set(&priv->receive_ready, 0); 450 } else { 451 rc = 1; 452 } 453 if (!rc) { 454 priv->buffer_free = 0; 455 user_data_count += iucv_data_count; 456 priv->current_position = priv->buffer; 457 if (priv->residual_length == 0){ 458 /* the whole record has been captured, 459 * now add the fence */ 460 atomic_dec(&priv->receive_ready); 461 buffer = priv->buffer + user_data_count; 462 memcpy(buffer, FENCE, sizeof(FENCE)); 463 user_data_count += sizeof(FENCE); 464 } 465 priv->remaining = user_data_count; 466 } 467 468 return rc; 469 } 470 471 472 static ssize_t vmlogrdr_read(struct file *filp, char __user *data, 473 size_t count, loff_t * ppos) 474 { 475 int rc; 476 struct vmlogrdr_priv_t * priv = filp->private_data; 477 478 while (priv->buffer_free) { 479 rc = vmlogrdr_receive_data(priv); 480 if (rc) { 481 rc = wait_event_interruptible(read_wait_queue, 482 atomic_read(&priv->receive_ready)); 483 if (rc) 484 return rc; 485 } 486 } 487 /* copy only up to end of record */ 488 if (count > priv->remaining) 489 count = priv->remaining; 490 491 if (copy_to_user(data, priv->current_position, count)) 492 return -EFAULT; 493 494 *ppos += count; 495 priv->current_position += count; 496 priv->remaining -= count; 497 498 /* if all data has been transferred, set buffer free */ 499 if (priv->remaining == 0) 500 priv->buffer_free = 1; 501 502 return count; 503 } 504 505 static ssize_t vmlogrdr_autopurge_store(struct device * dev, 506 struct device_attribute *attr, 507 const char * buf, size_t count) 508 { 509 struct vmlogrdr_priv_t *priv = dev->driver_data; 510 ssize_t ret = count; 511 512 switch (buf[0]) { 513 case '0': 514 priv->autopurge=0; 515 break; 516 case '1': 517 priv->autopurge=1; 518 break; 519 default: 520 ret = -EINVAL; 521 } 522 return ret; 523 } 524 525 526 static ssize_t vmlogrdr_autopurge_show(struct device *dev, 527 struct device_attribute *attr, 528 char *buf) 529 { 530 struct vmlogrdr_priv_t *priv = dev->driver_data; 531 return sprintf(buf, "%u\n", priv->autopurge); 532 } 533 534 535 static DEVICE_ATTR(autopurge, 0644, vmlogrdr_autopurge_show, 536 vmlogrdr_autopurge_store); 537 538 539 static ssize_t vmlogrdr_purge_store(struct device * dev, 540 struct device_attribute *attr, 541 const char * buf, size_t count) 542 { 543 544 char cp_command[80]; 545 char cp_response[80]; 546 struct vmlogrdr_priv_t *priv = dev->driver_data; 547 548 if (buf[0] != '1') 549 return -EINVAL; 550 551 memset(cp_command, 0x00, sizeof(cp_command)); 552 memset(cp_response, 0x00, sizeof(cp_response)); 553 554 /* 555 * The recording command needs to be called with option QID 556 * for guests that have previlege classes A or B. 557 * Other guests will not recognize the command and we have to 558 * issue the same command without the QID parameter. 559 */ 560 561 if (recording_class_AB) 562 snprintf(cp_command, sizeof(cp_command), 563 "RECORDING %s PURGE QID * ", 564 priv->recording_name); 565 else 566 snprintf(cp_command, sizeof(cp_command), 567 "RECORDING %s PURGE ", 568 priv->recording_name); 569 570 printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", cp_command); 571 cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); 572 printk (KERN_DEBUG "vmlogrdr: recording response: %s", 573 cp_response); 574 575 return count; 576 } 577 578 579 static DEVICE_ATTR(purge, 0200, NULL, vmlogrdr_purge_store); 580 581 582 static ssize_t vmlogrdr_autorecording_store(struct device *dev, 583 struct device_attribute *attr, 584 const char *buf, size_t count) 585 { 586 struct vmlogrdr_priv_t *priv = dev->driver_data; 587 ssize_t ret = count; 588 589 switch (buf[0]) { 590 case '0': 591 priv->autorecording=0; 592 break; 593 case '1': 594 priv->autorecording=1; 595 break; 596 default: 597 ret = -EINVAL; 598 } 599 return ret; 600 } 601 602 603 static ssize_t vmlogrdr_autorecording_show(struct device *dev, 604 struct device_attribute *attr, 605 char *buf) 606 { 607 struct vmlogrdr_priv_t *priv = dev->driver_data; 608 return sprintf(buf, "%u\n", priv->autorecording); 609 } 610 611 612 static DEVICE_ATTR(autorecording, 0644, vmlogrdr_autorecording_show, 613 vmlogrdr_autorecording_store); 614 615 616 static ssize_t vmlogrdr_recording_store(struct device * dev, 617 struct device_attribute *attr, 618 const char * buf, size_t count) 619 { 620 struct vmlogrdr_priv_t *priv = dev->driver_data; 621 ssize_t ret; 622 623 switch (buf[0]) { 624 case '0': 625 ret = vmlogrdr_recording(priv,0,0); 626 break; 627 case '1': 628 ret = vmlogrdr_recording(priv,1,0); 629 break; 630 default: 631 ret = -EINVAL; 632 } 633 if (ret) 634 return ret; 635 else 636 return count; 637 638 } 639 640 641 static DEVICE_ATTR(recording, 0200, NULL, vmlogrdr_recording_store); 642 643 644 static ssize_t vmlogrdr_recording_status_show(struct device_driver *driver, 645 char *buf) 646 { 647 648 char cp_command[] = "QUERY RECORDING "; 649 int len; 650 651 cpcmd(cp_command, buf, 4096, NULL); 652 len = strlen(buf); 653 return len; 654 } 655 656 657 static DRIVER_ATTR(recording_status, 0444, vmlogrdr_recording_status_show, 658 NULL); 659 660 static struct attribute *vmlogrdr_attrs[] = { 661 &dev_attr_autopurge.attr, 662 &dev_attr_purge.attr, 663 &dev_attr_autorecording.attr, 664 &dev_attr_recording.attr, 665 NULL, 666 }; 667 668 static struct attribute_group vmlogrdr_attr_group = { 669 .attrs = vmlogrdr_attrs, 670 }; 671 672 static struct class *vmlogrdr_class; 673 static struct device_driver vmlogrdr_driver = { 674 .name = "vmlogrdr", 675 .bus = &iucv_bus, 676 }; 677 678 679 static int vmlogrdr_register_driver(void) 680 { 681 int ret; 682 683 /* Register with iucv driver */ 684 ret = iucv_register(&vmlogrdr_iucv_handler, 1); 685 if (ret) { 686 printk (KERN_ERR "vmlogrdr: failed to register with" 687 "iucv driver\n"); 688 goto out; 689 } 690 691 ret = driver_register(&vmlogrdr_driver); 692 if (ret) { 693 printk(KERN_ERR "vmlogrdr: failed to register driver.\n"); 694 goto out_iucv; 695 } 696 697 ret = driver_create_file(&vmlogrdr_driver, 698 &driver_attr_recording_status); 699 if (ret) { 700 printk(KERN_ERR "vmlogrdr: failed to add driver attribute.\n"); 701 goto out_driver; 702 } 703 704 vmlogrdr_class = class_create(THIS_MODULE, "vmlogrdr"); 705 if (IS_ERR(vmlogrdr_class)) { 706 printk(KERN_ERR "vmlogrdr: failed to create class.\n"); 707 ret = PTR_ERR(vmlogrdr_class); 708 vmlogrdr_class = NULL; 709 goto out_attr; 710 } 711 return 0; 712 713 out_attr: 714 driver_remove_file(&vmlogrdr_driver, &driver_attr_recording_status); 715 out_driver: 716 driver_unregister(&vmlogrdr_driver); 717 out_iucv: 718 iucv_unregister(&vmlogrdr_iucv_handler, 1); 719 out: 720 return ret; 721 } 722 723 724 static void vmlogrdr_unregister_driver(void) 725 { 726 class_destroy(vmlogrdr_class); 727 vmlogrdr_class = NULL; 728 driver_remove_file(&vmlogrdr_driver, &driver_attr_recording_status); 729 driver_unregister(&vmlogrdr_driver); 730 iucv_unregister(&vmlogrdr_iucv_handler, 1); 731 } 732 733 734 static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) 735 { 736 struct device *dev; 737 int ret; 738 739 dev = kzalloc(sizeof(struct device), GFP_KERNEL); 740 if (dev) { 741 snprintf(dev->bus_id, BUS_ID_SIZE, "%s", 742 priv->internal_name); 743 dev->bus = &iucv_bus; 744 dev->parent = iucv_root; 745 dev->driver = &vmlogrdr_driver; 746 /* 747 * The release function could be called after the 748 * module has been unloaded. It's _only_ task is to 749 * free the struct. Therefore, we specify kfree() 750 * directly here. (Probably a little bit obfuscating 751 * but legitime ...). 752 */ 753 dev->release = (void (*)(struct device *))kfree; 754 } else 755 return -ENOMEM; 756 ret = device_register(dev); 757 if (ret) 758 return ret; 759 760 ret = sysfs_create_group(&dev->kobj, &vmlogrdr_attr_group); 761 if (ret) { 762 device_unregister(dev); 763 return ret; 764 } 765 priv->class_device = class_device_create( 766 vmlogrdr_class, 767 NULL, 768 MKDEV(vmlogrdr_major, priv->minor_num), 769 dev, 770 "%s", dev->bus_id ); 771 if (IS_ERR(priv->class_device)) { 772 ret = PTR_ERR(priv->class_device); 773 priv->class_device=NULL; 774 sysfs_remove_group(&dev->kobj, &vmlogrdr_attr_group); 775 device_unregister(dev); 776 return ret; 777 } 778 dev->driver_data = priv; 779 priv->device = dev; 780 return 0; 781 } 782 783 784 static int vmlogrdr_unregister_device(struct vmlogrdr_priv_t *priv) 785 { 786 class_device_destroy(vmlogrdr_class, 787 MKDEV(vmlogrdr_major, priv->minor_num)); 788 if (priv->device != NULL) { 789 sysfs_remove_group(&priv->device->kobj, &vmlogrdr_attr_group); 790 device_unregister(priv->device); 791 priv->device=NULL; 792 } 793 return 0; 794 } 795 796 797 static int vmlogrdr_register_cdev(dev_t dev) 798 { 799 int rc = 0; 800 vmlogrdr_cdev = cdev_alloc(); 801 if (!vmlogrdr_cdev) { 802 return -ENOMEM; 803 } 804 vmlogrdr_cdev->owner = THIS_MODULE; 805 vmlogrdr_cdev->ops = &vmlogrdr_fops; 806 vmlogrdr_cdev->dev = dev; 807 rc = cdev_add(vmlogrdr_cdev, vmlogrdr_cdev->dev, MAXMINOR); 808 if (!rc) 809 return 0; 810 811 // cleanup: cdev is not fully registered, no cdev_del here! 812 kobject_put(&vmlogrdr_cdev->kobj); 813 vmlogrdr_cdev=NULL; 814 return rc; 815 } 816 817 818 static void vmlogrdr_cleanup(void) 819 { 820 int i; 821 822 if (vmlogrdr_cdev) { 823 cdev_del(vmlogrdr_cdev); 824 vmlogrdr_cdev=NULL; 825 } 826 for (i=0; i < MAXMINOR; ++i ) { 827 vmlogrdr_unregister_device(&sys_ser[i]); 828 free_page((unsigned long)sys_ser[i].buffer); 829 } 830 vmlogrdr_unregister_driver(); 831 if (vmlogrdr_major) { 832 unregister_chrdev_region(MKDEV(vmlogrdr_major, 0), MAXMINOR); 833 vmlogrdr_major=0; 834 } 835 } 836 837 838 static int __init vmlogrdr_init(void) 839 { 840 int rc; 841 int i; 842 dev_t dev; 843 844 if (! MACHINE_IS_VM) { 845 printk (KERN_ERR "vmlogrdr: not running under VM, " 846 "driver not loaded.\n"); 847 return -ENODEV; 848 } 849 850 recording_class_AB = vmlogrdr_get_recording_class_AB(); 851 852 rc = alloc_chrdev_region(&dev, 0, MAXMINOR, "vmlogrdr"); 853 if (rc) 854 return rc; 855 vmlogrdr_major = MAJOR(dev); 856 857 rc=vmlogrdr_register_driver(); 858 if (rc) 859 goto cleanup; 860 861 for (i=0; i < MAXMINOR; ++i ) { 862 sys_ser[i].buffer = (char *) get_zeroed_page(GFP_KERNEL); 863 if (!sys_ser[i].buffer) { 864 rc = ENOMEM; 865 break; 866 } 867 sys_ser[i].current_position = sys_ser[i].buffer; 868 rc=vmlogrdr_register_device(&sys_ser[i]); 869 if (rc) 870 break; 871 } 872 if (rc) 873 goto cleanup; 874 875 rc = vmlogrdr_register_cdev(dev); 876 if (rc) 877 goto cleanup; 878 printk (KERN_INFO "vmlogrdr: driver loaded\n"); 879 return 0; 880 881 cleanup: 882 vmlogrdr_cleanup(); 883 printk (KERN_ERR "vmlogrdr: driver not loaded.\n"); 884 return rc; 885 } 886 887 888 static void __exit vmlogrdr_exit(void) 889 { 890 vmlogrdr_cleanup(); 891 printk (KERN_INFO "vmlogrdr: driver unloaded\n"); 892 return; 893 } 894 895 896 module_init(vmlogrdr_init); 897 module_exit(vmlogrdr_exit); 898