]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/s390/char/zcore.c
1d61a01576d213ac600e367e231272a2fbbcb5dc
[karo-tx-linux.git] / drivers / s390 / char / zcore.c
1 /*
2  * zcore module to export memory content and register sets for creating system
3  * dumps on SCSI disks (zfcpdump). The "zcore/mem" debugfs file shows the same
4  * dump format as s390 standalone dumps.
5  *
6  * For more information please refer to Documentation/s390/zfcpdump.txt
7  *
8  * Copyright IBM Corp. 2003, 2008
9  * Author(s): Michael Holzheu
10  */
11
12 #define KMSG_COMPONENT "zdump"
13 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
14
15 #include <linux/init.h>
16 #include <linux/slab.h>
17 #include <linux/miscdevice.h>
18 #include <linux/debugfs.h>
19 #include <linux/module.h>
20 #include <asm/asm-offsets.h>
21 #include <asm/ipl.h>
22 #include <asm/sclp.h>
23 #include <asm/setup.h>
24 #include <asm/uaccess.h>
25 #include <asm/debug.h>
26 #include <asm/processor.h>
27 #include <asm/irqflags.h>
28 #include <asm/checksum.h>
29 #include "sclp.h"
30
31 #define TRACE(x...) debug_sprintf_event(zcore_dbf, 1, x)
32
33 #define TO_USER         0
34 #define TO_KERNEL       1
35 #define CHUNK_INFO_SIZE 34 /* 2 16-byte char, each followed by blank */
36
37 enum arch_id {
38         ARCH_S390       = 0,
39         ARCH_S390X      = 1,
40 };
41
42 /* dump system info */
43
44 struct sys_info {
45         enum arch_id     arch;
46         unsigned long    sa_base;
47         u32              sa_size;
48         int              cpu_map[NR_CPUS];
49         unsigned long    mem_size;
50         struct save_area lc_mask;
51 };
52
53 struct ipib_info {
54         unsigned long   ipib;
55         u32             checksum;
56 }  __attribute__((packed));
57
58 static struct sys_info sys_info;
59 static struct debug_info *zcore_dbf;
60 static int hsa_available;
61 static struct dentry *zcore_dir;
62 static struct dentry *zcore_file;
63 static struct dentry *zcore_memmap_file;
64 static struct dentry *zcore_reipl_file;
65 static struct dentry *zcore_hsa_file;
66 static struct ipl_parameter_block *ipl_block;
67
68 /*
69  * Copy memory from HSA to kernel or user memory (not reentrant):
70  *
71  * @dest:  Kernel or user buffer where memory should be copied to
72  * @src:   Start address within HSA where data should be copied
73  * @count: Size of buffer, which should be copied
74  * @mode:  Either TO_KERNEL or TO_USER
75  */
76 static int memcpy_hsa(void *dest, unsigned long src, size_t count, int mode)
77 {
78         int offs, blk_num;
79         static char buf[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
80
81         if (!hsa_available)
82                 return -ENODATA;
83         if (count == 0)
84                 return 0;
85
86         /* copy first block */
87         offs = 0;
88         if ((src % PAGE_SIZE) != 0) {
89                 blk_num = src / PAGE_SIZE + 2;
90                 if (sclp_sdias_copy(buf, blk_num, 1)) {
91                         TRACE("sclp_sdias_copy() failed\n");
92                         return -EIO;
93                 }
94                 offs = min((PAGE_SIZE - (src % PAGE_SIZE)), count);
95                 if (mode == TO_USER) {
96                         if (copy_to_user((__force __user void*) dest,
97                                          buf + (src % PAGE_SIZE), offs))
98                                 return -EFAULT;
99                 } else
100                         memcpy(dest, buf + (src % PAGE_SIZE), offs);
101         }
102         if (offs == count)
103                 goto out;
104
105         /* copy middle */
106         for (; (offs + PAGE_SIZE) <= count; offs += PAGE_SIZE) {
107                 blk_num = (src + offs) / PAGE_SIZE + 2;
108                 if (sclp_sdias_copy(buf, blk_num, 1)) {
109                         TRACE("sclp_sdias_copy() failed\n");
110                         return -EIO;
111                 }
112                 if (mode == TO_USER) {
113                         if (copy_to_user((__force __user void*) dest + offs,
114                                          buf, PAGE_SIZE))
115                                 return -EFAULT;
116                 } else
117                         memcpy(dest + offs, buf, PAGE_SIZE);
118         }
119         if (offs == count)
120                 goto out;
121
122         /* copy last block */
123         blk_num = (src + offs) / PAGE_SIZE + 2;
124         if (sclp_sdias_copy(buf, blk_num, 1)) {
125                 TRACE("sclp_sdias_copy() failed\n");
126                 return -EIO;
127         }
128         if (mode == TO_USER) {
129                 if (copy_to_user((__force __user void*) dest + offs, buf,
130                                  PAGE_SIZE))
131                         return -EFAULT;
132         } else
133                 memcpy(dest + offs, buf, count - offs);
134 out:
135         return 0;
136 }
137
138 static int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count)
139 {
140         return memcpy_hsa((void __force *) dest, src, count, TO_USER);
141 }
142
143 static int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count)
144 {
145         return memcpy_hsa(dest, src, count, TO_KERNEL);
146 }
147
148 static int __init init_cpu_info(enum arch_id arch)
149 {
150         struct save_area *sa;
151
152         /* get info for boot cpu from lowcore, stored in the HSA */
153
154         sa = kmalloc(sizeof(*sa), GFP_KERNEL);
155         if (!sa)
156                 return -ENOMEM;
157         if (memcpy_hsa_kernel(sa, sys_info.sa_base, sys_info.sa_size) < 0) {
158                 TRACE("could not copy from HSA\n");
159                 kfree(sa);
160                 return -EIO;
161         }
162         zfcpdump_save_areas[0] = sa;
163         return 0;
164 }
165
166 static DEFINE_MUTEX(zcore_mutex);
167
168 #define DUMP_VERSION    0x5
169 #define DUMP_MAGIC      0xa8190173618f23fdULL
170 #define DUMP_ARCH_S390X 2
171 #define DUMP_ARCH_S390  1
172 #define HEADER_SIZE     4096
173
174 /* dump header dumped according to s390 crash dump format */
175
176 struct zcore_header {
177         u64 magic;
178         u32 version;
179         u32 header_size;
180         u32 dump_level;
181         u32 page_size;
182         u64 mem_size;
183         u64 mem_start;
184         u64 mem_end;
185         u32 num_pages;
186         u32 pad1;
187         u64 tod;
188         struct cpuid cpu_id;
189         u32 arch_id;
190         u32 volnr;
191         u32 build_arch;
192         u64 rmem_size;
193         u8 mvdump;
194         u16 cpu_cnt;
195         u16 real_cpu_cnt;
196         u8 end_pad1[0x200-0x061];
197         u64 mvdump_sign;
198         u64 mvdump_zipl_time;
199         u8 end_pad2[0x800-0x210];
200         u32 lc_vec[512];
201 } __attribute__((packed,__aligned__(16)));
202
203 static struct zcore_header zcore_header = {
204         .magic          = DUMP_MAGIC,
205         .version        = DUMP_VERSION,
206         .header_size    = 4096,
207         .dump_level     = 0,
208         .page_size      = PAGE_SIZE,
209         .mem_start      = 0,
210 #ifdef CONFIG_64BIT
211         .build_arch     = DUMP_ARCH_S390X,
212 #else
213         .build_arch     = DUMP_ARCH_S390,
214 #endif
215 };
216
217 /*
218  * Copy lowcore info to buffer. Use map in order to copy only register parts.
219  *
220  * @buf:    User buffer
221  * @sa:     Pointer to save area
222  * @sa_off: Offset in save area to copy
223  * @len:    Number of bytes to copy
224  */
225 static int copy_lc(void __user *buf, void *sa, int sa_off, int len)
226 {
227         int i;
228         char *lc_mask = (char*)&sys_info.lc_mask;
229
230         for (i = 0; i < len; i++) {
231                 if (!lc_mask[i + sa_off])
232                         continue;
233                 if (copy_to_user(buf + i, sa + sa_off + i, 1))
234                         return -EFAULT;
235         }
236         return 0;
237 }
238
239 /*
240  * Copy lowcores info to memory, if necessary
241  *
242  * @buf:   User buffer
243  * @addr:  Start address of buffer in dump memory
244  * @count: Size of buffer
245  */
246 static int zcore_add_lc(char __user *buf, unsigned long start, size_t count)
247 {
248         unsigned long end;
249         int i = 0;
250
251         if (count == 0)
252                 return 0;
253
254         end = start + count;
255         while (zfcpdump_save_areas[i]) {
256                 unsigned long cp_start, cp_end; /* copy range */
257                 unsigned long sa_start, sa_end; /* save area range */
258                 unsigned long prefix;
259                 unsigned long sa_off, len, buf_off;
260
261                 prefix = zfcpdump_save_areas[i]->pref_reg;
262                 sa_start = prefix + sys_info.sa_base;
263                 sa_end = prefix + sys_info.sa_base + sys_info.sa_size;
264
265                 if ((end < sa_start) || (start > sa_end))
266                         goto next;
267                 cp_start = max(start, sa_start);
268                 cp_end = min(end, sa_end);
269
270                 buf_off = cp_start - start;
271                 sa_off = cp_start - sa_start;
272                 len = cp_end - cp_start;
273
274                 TRACE("copy_lc for: %lx\n", start);
275                 if (copy_lc(buf + buf_off, zfcpdump_save_areas[i], sa_off, len))
276                         return -EFAULT;
277 next:
278                 i++;
279         }
280         return 0;
281 }
282
283 /*
284  * Release the HSA
285  */
286 static void release_hsa(void)
287 {
288         diag308(DIAG308_REL_HSA, NULL);
289         hsa_available = 0;
290 }
291
292 /*
293  * Read routine for zcore character device
294  * First 4K are dump header
295  * Next 32MB are HSA Memory
296  * Rest is read from absolute Memory
297  */
298 static ssize_t zcore_read(struct file *file, char __user *buf, size_t count,
299                           loff_t *ppos)
300 {
301         unsigned long mem_start; /* Start address in memory */
302         size_t mem_offs;         /* Offset in dump memory */
303         size_t hdr_count;        /* Size of header part of output buffer */
304         size_t size;
305         int rc;
306
307         mutex_lock(&zcore_mutex);
308
309         if (*ppos > (sys_info.mem_size + HEADER_SIZE)) {
310                 rc = -EINVAL;
311                 goto fail;
312         }
313
314         count = min(count, (size_t) (sys_info.mem_size + HEADER_SIZE - *ppos));
315
316         /* Copy dump header */
317         if (*ppos < HEADER_SIZE) {
318                 size = min(count, (size_t) (HEADER_SIZE - *ppos));
319                 if (copy_to_user(buf, &zcore_header + *ppos, size)) {
320                         rc = -EFAULT;
321                         goto fail;
322                 }
323                 hdr_count = size;
324                 mem_start = 0;
325         } else {
326                 hdr_count = 0;
327                 mem_start = *ppos - HEADER_SIZE;
328         }
329
330         mem_offs = 0;
331
332         /* Copy from HSA data */
333         if (*ppos < (ZFCPDUMP_HSA_SIZE + HEADER_SIZE)) {
334                 size = min((count - hdr_count), (size_t) (ZFCPDUMP_HSA_SIZE
335                            - mem_start));
336                 rc = memcpy_hsa_user(buf + hdr_count, mem_start, size);
337                 if (rc)
338                         goto fail;
339
340                 mem_offs += size;
341         }
342
343         /* Copy from real mem */
344         size = count - mem_offs - hdr_count;
345         rc = copy_to_user_real(buf + hdr_count + mem_offs,
346                                (void *) mem_start + mem_offs, size);
347         if (rc)
348                 goto fail;
349
350         /*
351          * Since s390 dump analysis tools like lcrash or crash
352          * expect register sets in the prefix pages of the cpus,
353          * we copy them into the read buffer, if necessary.
354          * buf + hdr_count: Start of memory part of output buffer
355          * mem_start: Start memory address to copy from
356          * count - hdr_count: Size of memory area to copy
357          */
358         if (zcore_add_lc(buf + hdr_count, mem_start, count - hdr_count)) {
359                 rc = -EFAULT;
360                 goto fail;
361         }
362         *ppos += count;
363 fail:
364         mutex_unlock(&zcore_mutex);
365         return (rc < 0) ? rc : count;
366 }
367
368 static int zcore_open(struct inode *inode, struct file *filp)
369 {
370         if (!hsa_available)
371                 return -ENODATA;
372         else
373                 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
374 }
375
376 static int zcore_release(struct inode *inode, struct file *filep)
377 {
378         if (hsa_available)
379                 release_hsa();
380         return 0;
381 }
382
383 static loff_t zcore_lseek(struct file *file, loff_t offset, int orig)
384 {
385         loff_t rc;
386
387         mutex_lock(&zcore_mutex);
388         switch (orig) {
389         case 0:
390                 file->f_pos = offset;
391                 rc = file->f_pos;
392                 break;
393         case 1:
394                 file->f_pos += offset;
395                 rc = file->f_pos;
396                 break;
397         default:
398                 rc = -EINVAL;
399         }
400         mutex_unlock(&zcore_mutex);
401         return rc;
402 }
403
404 static const struct file_operations zcore_fops = {
405         .owner          = THIS_MODULE,
406         .llseek         = zcore_lseek,
407         .read           = zcore_read,
408         .open           = zcore_open,
409         .release        = zcore_release,
410 };
411
412 static ssize_t zcore_memmap_read(struct file *filp, char __user *buf,
413                                  size_t count, loff_t *ppos)
414 {
415         return simple_read_from_buffer(buf, count, ppos, filp->private_data,
416                                        MEMORY_CHUNKS * CHUNK_INFO_SIZE);
417 }
418
419 static int zcore_memmap_open(struct inode *inode, struct file *filp)
420 {
421         int i;
422         char *buf;
423         struct mem_chunk *chunk_array;
424
425         chunk_array = kzalloc(MEMORY_CHUNKS * sizeof(struct mem_chunk),
426                               GFP_KERNEL);
427         if (!chunk_array)
428                 return -ENOMEM;
429         detect_memory_layout(chunk_array);
430         buf = kzalloc(MEMORY_CHUNKS * CHUNK_INFO_SIZE, GFP_KERNEL);
431         if (!buf) {
432                 kfree(chunk_array);
433                 return -ENOMEM;
434         }
435         for (i = 0; i < MEMORY_CHUNKS; i++) {
436                 sprintf(buf + (i * CHUNK_INFO_SIZE), "%016llx %016llx ",
437                         (unsigned long long) chunk_array[i].addr,
438                         (unsigned long long) chunk_array[i].size);
439                 if (chunk_array[i].size == 0)
440                         break;
441         }
442         kfree(chunk_array);
443         filp->private_data = buf;
444         return nonseekable_open(inode, filp);
445 }
446
447 static int zcore_memmap_release(struct inode *inode, struct file *filp)
448 {
449         kfree(filp->private_data);
450         return 0;
451 }
452
453 static const struct file_operations zcore_memmap_fops = {
454         .owner          = THIS_MODULE,
455         .read           = zcore_memmap_read,
456         .open           = zcore_memmap_open,
457         .release        = zcore_memmap_release,
458         .llseek         = no_llseek,
459 };
460
461 static ssize_t zcore_reipl_write(struct file *filp, const char __user *buf,
462                                  size_t count, loff_t *ppos)
463 {
464         if (ipl_block) {
465                 diag308(DIAG308_SET, ipl_block);
466                 diag308(DIAG308_IPL, NULL);
467         }
468         return count;
469 }
470
471 static int zcore_reipl_open(struct inode *inode, struct file *filp)
472 {
473         return nonseekable_open(inode, filp);
474 }
475
476 static int zcore_reipl_release(struct inode *inode, struct file *filp)
477 {
478         return 0;
479 }
480
481 static const struct file_operations zcore_reipl_fops = {
482         .owner          = THIS_MODULE,
483         .write          = zcore_reipl_write,
484         .open           = zcore_reipl_open,
485         .release        = zcore_reipl_release,
486         .llseek         = no_llseek,
487 };
488
489 static ssize_t zcore_hsa_read(struct file *filp, char __user *buf,
490                               size_t count, loff_t *ppos)
491 {
492         static char str[18];
493
494         if (hsa_available)
495                 snprintf(str, sizeof(str), "%lx\n", ZFCPDUMP_HSA_SIZE);
496         else
497                 snprintf(str, sizeof(str), "0\n");
498         return simple_read_from_buffer(buf, count, ppos, str, strlen(str));
499 }
500
501 static ssize_t zcore_hsa_write(struct file *filp, const char __user *buf,
502                                size_t count, loff_t *ppos)
503 {
504         char value;
505
506         if (*ppos != 0)
507                 return -EPIPE;
508         if (copy_from_user(&value, buf, 1))
509                 return -EFAULT;
510         if (value != '0')
511                 return -EINVAL;
512         release_hsa();
513         return count;
514 }
515
516 static const struct file_operations zcore_hsa_fops = {
517         .owner          = THIS_MODULE,
518         .write          = zcore_hsa_write,
519         .read           = zcore_hsa_read,
520         .open           = nonseekable_open,
521         .llseek         = no_llseek,
522 };
523
524 #ifdef CONFIG_32BIT
525
526 static void __init set_lc_mask(struct save_area *map)
527 {
528         memset(&map->ext_save, 0xff, sizeof(map->ext_save));
529         memset(&map->timer, 0xff, sizeof(map->timer));
530         memset(&map->clk_cmp, 0xff, sizeof(map->clk_cmp));
531         memset(&map->psw, 0xff, sizeof(map->psw));
532         memset(&map->pref_reg, 0xff, sizeof(map->pref_reg));
533         memset(&map->acc_regs, 0xff, sizeof(map->acc_regs));
534         memset(&map->fp_regs, 0xff, sizeof(map->fp_regs));
535         memset(&map->gp_regs, 0xff, sizeof(map->gp_regs));
536         memset(&map->ctrl_regs, 0xff, sizeof(map->ctrl_regs));
537 }
538
539 #else /* CONFIG_32BIT */
540
541 static void __init set_lc_mask(struct save_area *map)
542 {
543         memset(&map->fp_regs, 0xff, sizeof(map->fp_regs));
544         memset(&map->gp_regs, 0xff, sizeof(map->gp_regs));
545         memset(&map->psw, 0xff, sizeof(map->psw));
546         memset(&map->pref_reg, 0xff, sizeof(map->pref_reg));
547         memset(&map->fp_ctrl_reg, 0xff, sizeof(map->fp_ctrl_reg));
548         memset(&map->tod_reg, 0xff, sizeof(map->tod_reg));
549         memset(&map->timer, 0xff, sizeof(map->timer));
550         memset(&map->clk_cmp, 0xff, sizeof(map->clk_cmp));
551         memset(&map->acc_regs, 0xff, sizeof(map->acc_regs));
552         memset(&map->ctrl_regs, 0xff, sizeof(map->ctrl_regs));
553 }
554
555 #endif /* CONFIG_32BIT */
556
557 /*
558  * Initialize dump globals for a given architecture
559  */
560 static int __init sys_info_init(enum arch_id arch)
561 {
562         int rc;
563
564         switch (arch) {
565         case ARCH_S390X:
566                 pr_alert("DETECTED 'S390X (64 bit) OS'\n");
567                 break;
568         case ARCH_S390:
569                 pr_alert("DETECTED 'S390 (32 bit) OS'\n");
570                 break;
571         default:
572                 pr_alert("0x%x is an unknown architecture.\n",arch);
573                 return -EINVAL;
574         }
575         sys_info.sa_base = SAVE_AREA_BASE;
576         sys_info.sa_size = sizeof(struct save_area);
577         sys_info.arch = arch;
578         set_lc_mask(&sys_info.lc_mask);
579         rc = init_cpu_info(arch);
580         if (rc)
581                 return rc;
582         sys_info.mem_size = real_memory_size;
583
584         return 0;
585 }
586
587 static int __init check_sdias(void)
588 {
589         int rc, act_hsa_size;
590
591         rc = sclp_sdias_blk_count();
592         if (rc < 0) {
593                 TRACE("Could not determine HSA size\n");
594                 return rc;
595         }
596         act_hsa_size = (rc - 1) * PAGE_SIZE;
597         if (act_hsa_size < ZFCPDUMP_HSA_SIZE) {
598                 TRACE("HSA size too small: %i\n", act_hsa_size);
599                 return -EINVAL;
600         }
601         return 0;
602 }
603
604 static int __init get_mem_size(unsigned long *mem)
605 {
606         int i;
607         struct mem_chunk *chunk_array;
608
609         chunk_array = kzalloc(MEMORY_CHUNKS * sizeof(struct mem_chunk),
610                               GFP_KERNEL);
611         if (!chunk_array)
612                 return -ENOMEM;
613         detect_memory_layout(chunk_array);
614         for (i = 0; i < MEMORY_CHUNKS; i++) {
615                 if (chunk_array[i].size == 0)
616                         break;
617                 *mem += chunk_array[i].size;
618         }
619         kfree(chunk_array);
620         return 0;
621 }
622
623 static int __init zcore_header_init(int arch, struct zcore_header *hdr)
624 {
625         int rc, i;
626         unsigned long memory = 0;
627         u32 prefix;
628
629         if (arch == ARCH_S390X)
630                 hdr->arch_id = DUMP_ARCH_S390X;
631         else
632                 hdr->arch_id = DUMP_ARCH_S390;
633         rc = get_mem_size(&memory);
634         if (rc)
635                 return rc;
636         hdr->mem_size = memory;
637         hdr->rmem_size = memory;
638         hdr->mem_end = sys_info.mem_size;
639         hdr->num_pages = memory / PAGE_SIZE;
640         hdr->tod = get_tod_clock();
641         get_cpu_id(&hdr->cpu_id);
642         for (i = 0; zfcpdump_save_areas[i]; i++) {
643                 prefix = zfcpdump_save_areas[i]->pref_reg;
644                 hdr->real_cpu_cnt++;
645                 if (!prefix)
646                         continue;
647                 hdr->lc_vec[hdr->cpu_cnt] = prefix;
648                 hdr->cpu_cnt++;
649         }
650         return 0;
651 }
652
653 /*
654  * Provide IPL parameter information block from either HSA or memory
655  * for future reipl
656  */
657 static int __init zcore_reipl_init(void)
658 {
659         struct ipib_info ipib_info;
660         int rc;
661
662         rc = memcpy_hsa_kernel(&ipib_info, __LC_DUMP_REIPL, sizeof(ipib_info));
663         if (rc)
664                 return rc;
665         if (ipib_info.ipib == 0)
666                 return 0;
667         ipl_block = (void *) __get_free_page(GFP_KERNEL);
668         if (!ipl_block)
669                 return -ENOMEM;
670         if (ipib_info.ipib < ZFCPDUMP_HSA_SIZE)
671                 rc = memcpy_hsa_kernel(ipl_block, ipib_info.ipib, PAGE_SIZE);
672         else
673                 rc = memcpy_real(ipl_block, (void *) ipib_info.ipib, PAGE_SIZE);
674         if (rc || csum_partial(ipl_block, ipl_block->hdr.len, 0) !=
675             ipib_info.checksum) {
676                 TRACE("Checksum does not match\n");
677                 free_page((unsigned long) ipl_block);
678                 ipl_block = NULL;
679         }
680         return 0;
681 }
682
683 static int __init zcore_init(void)
684 {
685         unsigned char arch;
686         int rc;
687
688         if (ipl_info.type != IPL_TYPE_FCP_DUMP)
689                 return -ENODATA;
690         if (OLDMEM_BASE)
691                 return -ENODATA;
692
693         zcore_dbf = debug_register("zcore", 4, 1, 4 * sizeof(long));
694         debug_register_view(zcore_dbf, &debug_sprintf_view);
695         debug_set_level(zcore_dbf, 6);
696
697         TRACE("devno:  %x\n", ipl_info.data.fcp.dev_id.devno);
698         TRACE("wwpn:   %llx\n", (unsigned long long) ipl_info.data.fcp.wwpn);
699         TRACE("lun:    %llx\n", (unsigned long long) ipl_info.data.fcp.lun);
700
701         rc = sclp_sdias_init();
702         if (rc)
703                 goto fail;
704
705         rc = check_sdias();
706         if (rc)
707                 goto fail;
708         hsa_available = 1;
709
710         rc = memcpy_hsa_kernel(&arch, __LC_AR_MODE_ID, 1);
711         if (rc)
712                 goto fail;
713
714 #ifdef CONFIG_64BIT
715         if (arch == ARCH_S390) {
716                 pr_alert("The 64-bit dump tool cannot be used for a "
717                          "32-bit system\n");
718                 rc = -EINVAL;
719                 goto fail;
720         }
721 #else /* CONFIG_64BIT */
722         if (arch == ARCH_S390X) {
723                 pr_alert("The 32-bit dump tool cannot be used for a "
724                          "64-bit system\n");
725                 rc = -EINVAL;
726                 goto fail;
727         }
728 #endif /* CONFIG_64BIT */
729
730         rc = sys_info_init(arch);
731         if (rc)
732                 goto fail;
733
734         rc = zcore_header_init(arch, &zcore_header);
735         if (rc)
736                 goto fail;
737
738         rc = zcore_reipl_init();
739         if (rc)
740                 goto fail;
741
742         zcore_dir = debugfs_create_dir("zcore" , NULL);
743         if (!zcore_dir) {
744                 rc = -ENOMEM;
745                 goto fail;
746         }
747         zcore_file = debugfs_create_file("mem", S_IRUSR, zcore_dir, NULL,
748                                          &zcore_fops);
749         if (!zcore_file) {
750                 rc = -ENOMEM;
751                 goto fail_dir;
752         }
753         zcore_memmap_file = debugfs_create_file("memmap", S_IRUSR, zcore_dir,
754                                                 NULL, &zcore_memmap_fops);
755         if (!zcore_memmap_file) {
756                 rc = -ENOMEM;
757                 goto fail_file;
758         }
759         zcore_reipl_file = debugfs_create_file("reipl", S_IRUSR, zcore_dir,
760                                                 NULL, &zcore_reipl_fops);
761         if (!zcore_reipl_file) {
762                 rc = -ENOMEM;
763                 goto fail_memmap_file;
764         }
765         zcore_hsa_file = debugfs_create_file("hsa", S_IRUSR|S_IWUSR, zcore_dir,
766                                              NULL, &zcore_hsa_fops);
767         if (!zcore_hsa_file) {
768                 rc = -ENOMEM;
769                 goto fail_reipl_file;
770         }
771         return 0;
772
773 fail_reipl_file:
774         debugfs_remove(zcore_reipl_file);
775 fail_memmap_file:
776         debugfs_remove(zcore_memmap_file);
777 fail_file:
778         debugfs_remove(zcore_file);
779 fail_dir:
780         debugfs_remove(zcore_dir);
781 fail:
782         diag308(DIAG308_REL_HSA, NULL);
783         return rc;
784 }
785
786 static void __exit zcore_exit(void)
787 {
788         debug_unregister(zcore_dbf);
789         sclp_sdias_exit();
790         free_page((unsigned long) ipl_block);
791         debugfs_remove(zcore_hsa_file);
792         debugfs_remove(zcore_reipl_file);
793         debugfs_remove(zcore_memmap_file);
794         debugfs_remove(zcore_file);
795         debugfs_remove(zcore_dir);
796         diag308(DIAG308_REL_HSA, NULL);
797 }
798
799 MODULE_AUTHOR("Copyright IBM Corp. 2003,2008");
800 MODULE_DESCRIPTION("zcore module for zfcpdump support");
801 MODULE_LICENSE("GPL");
802
803 subsys_initcall(zcore_init);
804 module_exit(zcore_exit);