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, 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, 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, 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 if (logptr->autorecording) { 389 ret = vmlogrdr_recording(logptr,0,logptr->autopurge); 390 if (ret) 391 printk (KERN_WARNING "vmlogrdr: failed to stop " 392 "recording automatically\n"); 393 } 394 logptr->dev_in_use = 0; 395 396 return 0; 397 } 398 399 400 static int vmlogrdr_receive_data(struct vmlogrdr_priv_t *priv) 401 { 402 int rc, *temp; 403 /* we need to keep track of two data sizes here: 404 * The number of bytes we need to receive from iucv and 405 * the total number of bytes we actually write into the buffer. 406 */ 407 int user_data_count, iucv_data_count; 408 char * buffer; 409 410 if (atomic_read(&priv->receive_ready)) { 411 spin_lock_bh(&priv->priv_lock); 412 if (priv->residual_length){ 413 /* receive second half of a record */ 414 iucv_data_count = priv->residual_length; 415 user_data_count = 0; 416 buffer = priv->buffer; 417 } else { 418 /* receive a new record: 419 * We need to return the total length of the record 420 * + size of FENCE in the first 4 bytes of the buffer. 421 */ 422 iucv_data_count = priv->local_interrupt_buffer.length; 423 user_data_count = sizeof(int); 424 temp = (int*)priv->buffer; 425 *temp= iucv_data_count + sizeof(FENCE); 426 buffer = priv->buffer + sizeof(int); 427 } 428 /* 429 * If the record is bigger then our buffer, we receive only 430 * a part of it. We can get the rest later. 431 */ 432 if (iucv_data_count > NET_BUFFER_SIZE) 433 iucv_data_count = NET_BUFFER_SIZE; 434 rc = iucv_message_receive(priv->path, 435 &priv->local_interrupt_buffer, 436 0, buffer, iucv_data_count, 437 &priv->residual_length); 438 spin_unlock_bh(&priv->priv_lock); 439 /* An rc of 5 indicates that the record was bigger then 440 * the buffer, which is OK for us. A 9 indicates that the 441 * record was purged befor we could receive it. 442 */ 443 if (rc == 5) 444 rc = 0; 445 if (rc == 9) 446 atomic_set(&priv->receive_ready, 0); 447 } else { 448 rc = 1; 449 } 450 if (!rc) { 451 priv->buffer_free = 0; 452 user_data_count += iucv_data_count; 453 priv->current_position = priv->buffer; 454 if (priv->residual_length == 0){ 455 /* the whole record has been captured, 456 * now add the fence */ 457 atomic_dec(&priv->receive_ready); 458 buffer = priv->buffer + user_data_count; 459 memcpy(buffer, FENCE, sizeof(FENCE)); 460 user_data_count += sizeof(FENCE); 461 } 462 priv->remaining = user_data_count; 463 } 464 465 return rc; 466 } 467 468 469 static ssize_t vmlogrdr_read(struct file *filp, char __user *data, 470 size_t count, loff_t * ppos) 471 { 472 int rc; 473 struct vmlogrdr_priv_t * priv = filp->private_data; 474 475 while (priv->buffer_free) { 476 rc = vmlogrdr_receive_data(priv); 477 if (rc) { 478 rc = wait_event_interruptible(read_wait_queue, 479 atomic_read(&priv->receive_ready)); 480 if (rc) 481 return rc; 482 } 483 } 484 /* copy only up to end of record */ 485 if (count > priv->remaining) 486 count = priv->remaining; 487 488 if (copy_to_user(data, priv->current_position, count)) 489 return -EFAULT; 490 491 *ppos += count; 492 priv->current_position += count; 493 priv->remaining -= count; 494 495 /* if all data has been transferred, set buffer free */ 496 if (priv->remaining == 0) 497 priv->buffer_free = 1; 498 499 return count; 500 } 501 502 static ssize_t vmlogrdr_autopurge_store(struct device * dev, 503 struct device_attribute *attr, 504 const char * buf, size_t count) 505 { 506 struct vmlogrdr_priv_t *priv = dev->driver_data; 507 ssize_t ret = count; 508 509 switch (buf[0]) { 510 case '0': 511 priv->autopurge=0; 512 break; 513 case '1': 514 priv->autopurge=1; 515 break; 516 default: 517 ret = -EINVAL; 518 } 519 return ret; 520 } 521 522 523 static ssize_t vmlogrdr_autopurge_show(struct device *dev, 524 struct device_attribute *attr, 525 char *buf) 526 { 527 struct vmlogrdr_priv_t *priv = dev->driver_data; 528 return sprintf(buf, "%u\n", priv->autopurge); 529 } 530 531 532 static DEVICE_ATTR(autopurge, 0644, vmlogrdr_autopurge_show, 533 vmlogrdr_autopurge_store); 534 535 536 static ssize_t vmlogrdr_purge_store(struct device * dev, 537 struct device_attribute *attr, 538 const char * buf, size_t count) 539 { 540 541 char cp_command[80]; 542 char cp_response[80]; 543 struct vmlogrdr_priv_t *priv = dev->driver_data; 544 545 if (buf[0] != '1') 546 return -EINVAL; 547 548 memset(cp_command, 0x00, sizeof(cp_command)); 549 memset(cp_response, 0x00, sizeof(cp_response)); 550 551 /* 552 * The recording command needs to be called with option QID 553 * for guests that have previlege classes A or B. 554 * Other guests will not recognize the command and we have to 555 * issue the same command without the QID parameter. 556 */ 557 558 if (recording_class_AB) 559 snprintf(cp_command, sizeof(cp_command), 560 "RECORDING %s PURGE QID * ", 561 priv->recording_name); 562 else 563 snprintf(cp_command, sizeof(cp_command), 564 "RECORDING %s PURGE ", 565 priv->recording_name); 566 567 printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", cp_command); 568 cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); 569 printk (KERN_DEBUG "vmlogrdr: recording response: %s", 570 cp_response); 571 572 return count; 573 } 574 575 576 static DEVICE_ATTR(purge, 0200, NULL, vmlogrdr_purge_store); 577 578 579 static ssize_t vmlogrdr_autorecording_store(struct device *dev, 580 struct device_attribute *attr, 581 const char *buf, size_t count) 582 { 583 struct vmlogrdr_priv_t *priv = dev->driver_data; 584 ssize_t ret = count; 585 586 switch (buf[0]) { 587 case '0': 588 priv->autorecording=0; 589 break; 590 case '1': 591 priv->autorecording=1; 592 break; 593 default: 594 ret = -EINVAL; 595 } 596 return ret; 597 } 598 599 600 static ssize_t vmlogrdr_autorecording_show(struct device *dev, 601 struct device_attribute *attr, 602 char *buf) 603 { 604 struct vmlogrdr_priv_t *priv = dev->driver_data; 605 return sprintf(buf, "%u\n", priv->autorecording); 606 } 607 608 609 static DEVICE_ATTR(autorecording, 0644, vmlogrdr_autorecording_show, 610 vmlogrdr_autorecording_store); 611 612 613 static ssize_t vmlogrdr_recording_store(struct device * dev, 614 struct device_attribute *attr, 615 const char * buf, size_t count) 616 { 617 struct vmlogrdr_priv_t *priv = dev->driver_data; 618 ssize_t ret; 619 620 switch (buf[0]) { 621 case '0': 622 ret = vmlogrdr_recording(priv,0,0); 623 break; 624 case '1': 625 ret = vmlogrdr_recording(priv,1,0); 626 break; 627 default: 628 ret = -EINVAL; 629 } 630 if (ret) 631 return ret; 632 else 633 return count; 634 635 } 636 637 638 static DEVICE_ATTR(recording, 0200, NULL, vmlogrdr_recording_store); 639 640 641 static ssize_t vmlogrdr_recording_status_show(struct device_driver *driver, 642 char *buf) 643 { 644 645 char cp_command[] = "QUERY RECORDING "; 646 int len; 647 648 cpcmd(cp_command, buf, 4096, NULL); 649 len = strlen(buf); 650 return len; 651 } 652 653 654 static DRIVER_ATTR(recording_status, 0444, vmlogrdr_recording_status_show, 655 NULL); 656 657 static struct attribute *vmlogrdr_attrs[] = { 658 &dev_attr_autopurge.attr, 659 &dev_attr_purge.attr, 660 &dev_attr_autorecording.attr, 661 &dev_attr_recording.attr, 662 NULL, 663 }; 664 665 static struct attribute_group vmlogrdr_attr_group = { 666 .attrs = vmlogrdr_attrs, 667 }; 668 669 static struct class *vmlogrdr_class; 670 static struct device_driver vmlogrdr_driver = { 671 .name = "vmlogrdr", 672 .bus = &iucv_bus, 673 }; 674 675 676 static int vmlogrdr_register_driver(void) 677 { 678 int ret; 679 680 /* Register with iucv driver */ 681 ret = iucv_register(&vmlogrdr_iucv_handler, 1); 682 if (ret) { 683 printk (KERN_ERR "vmlogrdr: failed to register with" 684 "iucv driver\n"); 685 goto out; 686 } 687 688 ret = driver_register(&vmlogrdr_driver); 689 if (ret) { 690 printk(KERN_ERR "vmlogrdr: failed to register driver.\n"); 691 goto out_iucv; 692 } 693 694 ret = driver_create_file(&vmlogrdr_driver, 695 &driver_attr_recording_status); 696 if (ret) { 697 printk(KERN_ERR "vmlogrdr: failed to add driver attribute.\n"); 698 goto out_driver; 699 } 700 701 vmlogrdr_class = class_create(THIS_MODULE, "vmlogrdr"); 702 if (IS_ERR(vmlogrdr_class)) { 703 printk(KERN_ERR "vmlogrdr: failed to create class.\n"); 704 ret = PTR_ERR(vmlogrdr_class); 705 vmlogrdr_class = NULL; 706 goto out_attr; 707 } 708 return 0; 709 710 out_attr: 711 driver_remove_file(&vmlogrdr_driver, &driver_attr_recording_status); 712 out_driver: 713 driver_unregister(&vmlogrdr_driver); 714 out_iucv: 715 iucv_unregister(&vmlogrdr_iucv_handler, 1); 716 out: 717 return ret; 718 } 719 720 721 static void vmlogrdr_unregister_driver(void) 722 { 723 class_destroy(vmlogrdr_class); 724 vmlogrdr_class = NULL; 725 driver_remove_file(&vmlogrdr_driver, &driver_attr_recording_status); 726 driver_unregister(&vmlogrdr_driver); 727 iucv_unregister(&vmlogrdr_iucv_handler, 1); 728 } 729 730 731 static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) 732 { 733 struct device *dev; 734 int ret; 735 736 dev = kzalloc(sizeof(struct device), GFP_KERNEL); 737 if (dev) { 738 snprintf(dev->bus_id, BUS_ID_SIZE, "%s", 739 priv->internal_name); 740 dev->bus = &iucv_bus; 741 dev->parent = iucv_root; 742 dev->driver = &vmlogrdr_driver; 743 /* 744 * The release function could be called after the 745 * module has been unloaded. It's _only_ task is to 746 * free the struct. Therefore, we specify kfree() 747 * directly here. (Probably a little bit obfuscating 748 * but legitime ...). 749 */ 750 dev->release = (void (*)(struct device *))kfree; 751 } else 752 return -ENOMEM; 753 ret = device_register(dev); 754 if (ret) 755 return ret; 756 757 ret = sysfs_create_group(&dev->kobj, &vmlogrdr_attr_group); 758 if (ret) { 759 device_unregister(dev); 760 return ret; 761 } 762 priv->class_device = class_device_create( 763 vmlogrdr_class, 764 NULL, 765 MKDEV(vmlogrdr_major, priv->minor_num), 766 dev, 767 "%s", dev->bus_id ); 768 if (IS_ERR(priv->class_device)) { 769 ret = PTR_ERR(priv->class_device); 770 priv->class_device=NULL; 771 sysfs_remove_group(&dev->kobj, &vmlogrdr_attr_group); 772 device_unregister(dev); 773 return ret; 774 } 775 dev->driver_data = priv; 776 priv->device = dev; 777 return 0; 778 } 779 780 781 static int vmlogrdr_unregister_device(struct vmlogrdr_priv_t *priv) 782 { 783 class_device_destroy(vmlogrdr_class, 784 MKDEV(vmlogrdr_major, priv->minor_num)); 785 if (priv->device != NULL) { 786 sysfs_remove_group(&priv->device->kobj, &vmlogrdr_attr_group); 787 device_unregister(priv->device); 788 priv->device=NULL; 789 } 790 return 0; 791 } 792 793 794 static int vmlogrdr_register_cdev(dev_t dev) 795 { 796 int rc = 0; 797 vmlogrdr_cdev = cdev_alloc(); 798 if (!vmlogrdr_cdev) { 799 return -ENOMEM; 800 } 801 vmlogrdr_cdev->owner = THIS_MODULE; 802 vmlogrdr_cdev->ops = &vmlogrdr_fops; 803 vmlogrdr_cdev->dev = dev; 804 rc = cdev_add(vmlogrdr_cdev, vmlogrdr_cdev->dev, MAXMINOR); 805 if (!rc) 806 return 0; 807 808 // cleanup: cdev is not fully registered, no cdev_del here! 809 kobject_put(&vmlogrdr_cdev->kobj); 810 vmlogrdr_cdev=NULL; 811 return rc; 812 } 813 814 815 static void vmlogrdr_cleanup(void) 816 { 817 int i; 818 819 if (vmlogrdr_cdev) { 820 cdev_del(vmlogrdr_cdev); 821 vmlogrdr_cdev=NULL; 822 } 823 for (i=0; i < MAXMINOR; ++i ) { 824 vmlogrdr_unregister_device(&sys_ser[i]); 825 free_page((unsigned long)sys_ser[i].buffer); 826 } 827 vmlogrdr_unregister_driver(); 828 if (vmlogrdr_major) { 829 unregister_chrdev_region(MKDEV(vmlogrdr_major, 0), MAXMINOR); 830 vmlogrdr_major=0; 831 } 832 } 833 834 835 static int vmlogrdr_init(void) 836 { 837 int rc; 838 int i; 839 dev_t dev; 840 841 if (! MACHINE_IS_VM) { 842 printk (KERN_ERR "vmlogrdr: not running under VM, " 843 "driver not loaded.\n"); 844 return -ENODEV; 845 } 846 847 recording_class_AB = vmlogrdr_get_recording_class_AB(); 848 849 rc = alloc_chrdev_region(&dev, 0, MAXMINOR, "vmlogrdr"); 850 if (rc) 851 return rc; 852 vmlogrdr_major = MAJOR(dev); 853 854 rc=vmlogrdr_register_driver(); 855 if (rc) 856 goto cleanup; 857 858 for (i=0; i < MAXMINOR; ++i ) { 859 sys_ser[i].buffer = (char *) get_zeroed_page(GFP_KERNEL); 860 if (!sys_ser[i].buffer) { 861 rc = ENOMEM; 862 break; 863 } 864 sys_ser[i].current_position = sys_ser[i].buffer; 865 rc=vmlogrdr_register_device(&sys_ser[i]); 866 if (rc) 867 break; 868 } 869 if (rc) 870 goto cleanup; 871 872 rc = vmlogrdr_register_cdev(dev); 873 if (rc) 874 goto cleanup; 875 printk (KERN_INFO "vmlogrdr: driver loaded\n"); 876 return 0; 877 878 cleanup: 879 vmlogrdr_cleanup(); 880 printk (KERN_ERR "vmlogrdr: driver not loaded.\n"); 881 return rc; 882 } 883 884 885 static void vmlogrdr_exit(void) 886 { 887 vmlogrdr_cleanup(); 888 printk (KERN_INFO "vmlogrdr: driver unloaded\n"); 889 return; 890 } 891 892 893 module_init(vmlogrdr_init); 894 module_exit(vmlogrdr_exit); 895