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