aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/hypfs/hypfs_diag.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /arch/s390/hypfs/hypfs_diag.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'arch/s390/hypfs/hypfs_diag.c')
-rw-r--r--arch/s390/hypfs/hypfs_diag.c100
1 files changed, 31 insertions, 69 deletions
diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c
index 1211bb1d2f24..6023c6dc1fb7 100644
--- a/arch/s390/hypfs/hypfs_diag.c
+++ b/arch/s390/hypfs/hypfs_diag.c
@@ -555,80 +555,38 @@ struct dbfs_d204 {
555 char buf[]; /* d204 buffer */ 555 char buf[]; /* d204 buffer */
556} __attribute__ ((packed)); 556} __attribute__ ((packed));
557 557
558struct dbfs_d204_private { 558static int dbfs_d204_create(void **data, void **data_free_ptr, size_t *size)
559 struct dbfs_d204 *d204; /* Aligned d204 data with header */
560 void *base; /* Base pointer (needed for vfree) */
561};
562
563static int dbfs_d204_open(struct inode *inode, struct file *file)
564{ 559{
565 struct dbfs_d204_private *data;
566 struct dbfs_d204 *d204; 560 struct dbfs_d204 *d204;
567 int rc, buf_size; 561 int rc, buf_size;
562 void *base;
568 563
569 data = kzalloc(sizeof(*data), GFP_KERNEL);
570 if (!data)
571 return -ENOMEM;
572 buf_size = PAGE_SIZE * (diag204_buf_pages + 1) + sizeof(d204->hdr); 564 buf_size = PAGE_SIZE * (diag204_buf_pages + 1) + sizeof(d204->hdr);
573 data->base = vmalloc(buf_size); 565 base = vmalloc(buf_size);
574 if (!data->base) { 566 if (!base)
575 rc = -ENOMEM; 567 return -ENOMEM;
576 goto fail_kfree_data; 568 memset(base, 0, buf_size);
569 d204 = page_align_ptr(base + sizeof(d204->hdr)) - sizeof(d204->hdr);
570 rc = diag204_do_store(d204->buf, diag204_buf_pages);
571 if (rc) {
572 vfree(base);
573 return rc;
577 } 574 }
578 memset(data->base, 0, buf_size);
579 d204 = page_align_ptr(data->base + sizeof(d204->hdr))
580 - sizeof(d204->hdr);
581 rc = diag204_do_store(&d204->buf, diag204_buf_pages);
582 if (rc)
583 goto fail_vfree_base;
584 d204->hdr.version = DBFS_D204_HDR_VERSION; 575 d204->hdr.version = DBFS_D204_HDR_VERSION;
585 d204->hdr.len = PAGE_SIZE * diag204_buf_pages; 576 d204->hdr.len = PAGE_SIZE * diag204_buf_pages;
586 d204->hdr.sc = diag204_store_sc; 577 d204->hdr.sc = diag204_store_sc;
587 data->d204 = d204; 578 *data = d204;
588 file->private_data = data; 579 *data_free_ptr = base;
589 return nonseekable_open(inode, file); 580 *size = d204->hdr.len + sizeof(struct dbfs_d204_hdr);
590
591fail_vfree_base:
592 vfree(data->base);
593fail_kfree_data:
594 kfree(data);
595 return rc;
596}
597
598static int dbfs_d204_release(struct inode *inode, struct file *file)
599{
600 struct dbfs_d204_private *data = file->private_data;
601
602 vfree(data->base);
603 kfree(data);
604 return 0; 581 return 0;
605} 582}
606 583
607static ssize_t dbfs_d204_read(struct file *file, char __user *buf, 584static struct hypfs_dbfs_file dbfs_file_d204 = {
608 size_t size, loff_t *ppos) 585 .name = "diag_204",
609{ 586 .data_create = dbfs_d204_create,
610 struct dbfs_d204_private *data = file->private_data; 587 .data_free = vfree,
611
612 return simple_read_from_buffer(buf, size, ppos, data->d204,
613 data->d204->hdr.len +
614 sizeof(data->d204->hdr));
615}
616
617static const struct file_operations dbfs_d204_ops = {
618 .open = dbfs_d204_open,
619 .read = dbfs_d204_read,
620 .release = dbfs_d204_release,
621}; 588};
622 589
623static int hypfs_dbfs_init(void)
624{
625 dbfs_d204_file = debugfs_create_file("diag_204", 0400, hypfs_dbfs_dir,
626 NULL, &dbfs_d204_ops);
627 if (IS_ERR(dbfs_d204_file))
628 return PTR_ERR(dbfs_d204_file);
629 return 0;
630}
631
632__init int hypfs_diag_init(void) 590__init int hypfs_diag_init(void)
633{ 591{
634 int rc; 592 int rc;
@@ -637,18 +595,21 @@ __init int hypfs_diag_init(void)
637 pr_err("The hardware system does not support hypfs\n"); 595 pr_err("The hardware system does not support hypfs\n");
638 return -ENODATA; 596 return -ENODATA;
639 } 597 }
640 rc = diag224_get_name_table();
641 if (rc) {
642 diag204_free_buffer();
643 pr_err("The hardware system does not provide all "
644 "functions required by hypfs\n");
645 }
646 if (diag204_info_type == INFO_EXT) { 598 if (diag204_info_type == INFO_EXT) {
647 rc = hypfs_dbfs_init(); 599 rc = hypfs_dbfs_create_file(&dbfs_file_d204);
648 if (rc) 600 if (rc)
649 diag204_free_buffer(); 601 return rc;
650 } 602 }
651 return rc; 603 if (MACHINE_IS_LPAR) {
604 rc = diag224_get_name_table();
605 if (rc) {
606 pr_err("The hardware system does not provide all "
607 "functions required by hypfs\n");
608 debugfs_remove(dbfs_d204_file);
609 return rc;
610 }
611 }
612 return 0;
652} 613}
653 614
654void hypfs_diag_exit(void) 615void hypfs_diag_exit(void)
@@ -656,6 +617,7 @@ void hypfs_diag_exit(void)
656 debugfs_remove(dbfs_d204_file); 617 debugfs_remove(dbfs_d204_file);
657 diag224_delete_name_table(); 618 diag224_delete_name_table();
658 diag204_free_buffer(); 619 diag204_free_buffer();
620 hypfs_dbfs_remove_file(&dbfs_file_d204);
659} 621}
660 622
661/* 623/*