]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/s390/char/zcore.c
enc28j60: use netif_rx_ni() to deliver RX packets
[karo-tx-linux.git] / drivers / s390 / char / zcore.c
index bbbd14e9d48f8a17a6bb9f3efd566d7781ff71c0..7fd84be1193132f53163a272eba02c3791775116 100644 (file)
@@ -29,6 +29,7 @@
 
 #define TO_USER                0
 #define TO_KERNEL      1
+#define CHUNK_INFO_SIZE        34 /* 2 16-byte char, each followed by blank */
 
 enum arch_id {
        ARCH_S390       = 0,
@@ -51,6 +52,7 @@ static struct debug_info *zcore_dbf;
 static int hsa_available;
 static struct dentry *zcore_dir;
 static struct dentry *zcore_file;
+static struct dentry *zcore_memmap_file;
 
 /*
  * Copy memory from HSA to kernel or user memory (not reentrant):
@@ -223,12 +225,10 @@ static int __init init_cpu_info(enum arch_id arch)
        /* get info for boot cpu from lowcore, stored in the HSA */
 
        sa = kmalloc(sizeof(*sa), GFP_KERNEL);
-       if (!sa) {
-               ERROR_MSG("kmalloc failed: %s: %i\n",__func__, __LINE__);
+       if (!sa)
                return -ENOMEM;
-       }
        if (memcpy_hsa_kernel(sa, sys_info.sa_base, sys_info.sa_size) < 0) {
-               ERROR_MSG("could not copy from HSA\n");
+               TRACE("could not copy from HSA\n");
                kfree(sa);
                return -EIO;
        }
@@ -478,6 +478,54 @@ static const struct file_operations zcore_fops = {
        .release        = zcore_release,
 };
 
+static ssize_t zcore_memmap_read(struct file *filp, char __user *buf,
+                                size_t count, loff_t *ppos)
+{
+       return simple_read_from_buffer(buf, count, ppos, filp->private_data,
+                                      MEMORY_CHUNKS * CHUNK_INFO_SIZE);
+}
+
+static int zcore_memmap_open(struct inode *inode, struct file *filp)
+{
+       int i;
+       char *buf;
+       struct mem_chunk *chunk_array;
+
+       chunk_array = kzalloc(MEMORY_CHUNKS * sizeof(struct mem_chunk),
+                             GFP_KERNEL);
+       if (!chunk_array)
+               return -ENOMEM;
+       detect_memory_layout(chunk_array);
+       buf = kzalloc(MEMORY_CHUNKS * CHUNK_INFO_SIZE, GFP_KERNEL);
+       if (!buf) {
+               kfree(chunk_array);
+               return -ENOMEM;
+       }
+       for (i = 0; i < MEMORY_CHUNKS; i++) {
+               sprintf(buf + (i * CHUNK_INFO_SIZE), "%016llx %016llx ",
+                       (unsigned long long) chunk_array[i].addr,
+                       (unsigned long long) chunk_array[i].size);
+               if (chunk_array[i].size == 0)
+                       break;
+       }
+       kfree(chunk_array);
+       filp->private_data = buf;
+       return 0;
+}
+
+static int zcore_memmap_release(struct inode *inode, struct file *filp)
+{
+       kfree(filp->private_data);
+       return 0;
+}
+
+static const struct file_operations zcore_memmap_fops = {
+       .owner          = THIS_MODULE,
+       .read           = zcore_memmap_read,
+       .open           = zcore_memmap_open,
+       .release        = zcore_memmap_release,
+};
+
 
 static void __init set_s390_lc_mask(union save_area *map)
 {
@@ -511,6 +559,8 @@ static void __init set_s390x_lc_mask(union save_area *map)
  */
 static int __init sys_info_init(enum arch_id arch)
 {
+       int rc;
+
        switch (arch) {
        case ARCH_S390X:
                MSG("DETECTED 'S390X (64 bit) OS'\n");
@@ -529,10 +579,9 @@ static int __init sys_info_init(enum arch_id arch)
                return -EINVAL;
        }
        sys_info.arch = arch;
-       if (init_cpu_info(arch)) {
-               ERROR_MSG("get cpu info failed\n");
-               return -ENOMEM;
-       }
+       rc = init_cpu_info(arch);
+       if (rc)
+               return rc;
        sys_info.mem_size = real_memory_size;
 
        return 0;
@@ -544,29 +593,55 @@ static int __init check_sdias(void)
 
        rc = sclp_sdias_blk_count();
        if (rc < 0) {
-               ERROR_MSG("Could not determine HSA size\n");
+               TRACE("Could not determine HSA size\n");
                return rc;
        }
        act_hsa_size = (rc - 1) * PAGE_SIZE;
        if (act_hsa_size < ZFCPDUMP_HSA_SIZE) {
-               ERROR_MSG("HSA size too small: %i\n", act_hsa_size);
+               TRACE("HSA size too small: %i\n", act_hsa_size);
                return -EINVAL;
        }
        return 0;
 }
 
-static void __init zcore_header_init(int arch, struct zcore_header *hdr)
+static int __init get_mem_size(unsigned long *mem)
 {
+       int i;
+       struct mem_chunk *chunk_array;
+
+       chunk_array = kzalloc(MEMORY_CHUNKS * sizeof(struct mem_chunk),
+                             GFP_KERNEL);
+       if (!chunk_array)
+               return -ENOMEM;
+       detect_memory_layout(chunk_array);
+       for (i = 0; i < MEMORY_CHUNKS; i++) {
+               if (chunk_array[i].size == 0)
+                       break;
+               *mem += chunk_array[i].size;
+       }
+       kfree(chunk_array);
+       return 0;
+}
+
+static int __init zcore_header_init(int arch, struct zcore_header *hdr)
+{
+       int rc;
+       unsigned long memory = 0;
+
        if (arch == ARCH_S390X)
                hdr->arch_id = DUMP_ARCH_S390X;
        else
                hdr->arch_id = DUMP_ARCH_S390;
-       hdr->mem_size = sys_info.mem_size;
-       hdr->rmem_size = sys_info.mem_size;
+       rc = get_mem_size(&memory);
+       if (rc)
+               return rc;
+       hdr->mem_size = memory;
+       hdr->rmem_size = memory;
        hdr->mem_end = sys_info.mem_size;
-       hdr->num_pages = sys_info.mem_size / PAGE_SIZE;
+       hdr->num_pages = memory / PAGE_SIZE;
        hdr->tod = get_clock();
        get_cpu_id(&hdr->cpu_id);
+       return 0;
 }
 
 static int __init zcore_init(void)
@@ -590,16 +665,12 @@ static int __init zcore_init(void)
                goto fail;
 
        rc = check_sdias();
-       if (rc) {
-               ERROR_MSG("Dump initialization failed\n");
+       if (rc)
                goto fail;
-       }
 
        rc = memcpy_hsa_kernel(&arch, __LC_AR_MODE_ID, 1);
-       if (rc) {
-               ERROR_MSG("sdial memcpy for arch id failed\n");
+       if (rc)
                goto fail;
-       }
 
 #ifndef __s390x__
        if (arch == ARCH_S390X) {
@@ -610,12 +681,12 @@ static int __init zcore_init(void)
 #endif
 
        rc = sys_info_init(arch);
-       if (rc) {
-               ERROR_MSG("arch init failed\n");
+       if (rc)
                goto fail;
-       }
 
-       zcore_header_init(arch, &zcore_header);
+       rc = zcore_header_init(arch, &zcore_header);
+       if (rc)
+               goto fail;
 
        zcore_dir = debugfs_create_dir("zcore" , NULL);
        if (!zcore_dir) {
@@ -625,13 +696,22 @@ static int __init zcore_init(void)
        zcore_file = debugfs_create_file("mem", S_IRUSR, zcore_dir, NULL,
                                         &zcore_fops);
        if (!zcore_file) {
-               debugfs_remove(zcore_dir);
                rc = -ENOMEM;
-               goto fail;
+               goto fail_dir;
+       }
+       zcore_memmap_file = debugfs_create_file("memmap", S_IRUSR, zcore_dir,
+                                               NULL, &zcore_memmap_fops);
+       if (!zcore_memmap_file) {
+               rc = -ENOMEM;
+               goto fail_file;
        }
        hsa_available = 1;
        return 0;
 
+fail_file:
+       debugfs_remove(zcore_file);
+fail_dir:
+       debugfs_remove(zcore_dir);
 fail:
        diag308(DIAG308_REL_HSA, NULL);
        return rc;