3 * Author: Martin Peschke <mpeschke@de.ibm.com>
4 * Copyright (C) 2001 IBM Entwicklung GmbH, IBM Corporation
7 #include <linux/string.h>
8 #include <linux/ctype.h>
9 #include <linux/module.h>
10 #include <linux/init.h>
11 #include <linux/errno.h>
12 #include <linux/slab.h>
13 #include <linux/version.h>
14 #include <asm/semaphore.h>
15 #include <asm/ebcdic.h>
20 #define CPI_SLEEP_TICKS 50
22 #define CPI_LENGTH_SYSTEM_TYPE 8
23 #define CPI_LENGTH_SYSTEM_NAME 8
24 #define CPI_LENGTH_SYSPLEX_NAME 8
30 u8 system_type[CPI_LENGTH_SYSTEM_TYPE];
32 u8 system_name[CPI_LENGTH_SYSTEM_NAME];
36 u8 sysplex_name[CPI_LENGTH_SYSPLEX_NAME];
38 } __attribute__ ((packed))
42 typedef struct _cpi_hwcb_t {
44 cpi_evbuf_t cpi_evbuf;
45 } __attribute__ ((packed))
51 static int __init cpi_module_init (void);
52 static void __exit cpi_module_exit (void);
54 module_init (cpi_module_init);
55 module_exit (cpi_module_exit);
58 "Martin Peschke, IBM Deutschland Entwicklung GmbH "
59 "<mpeschke@de.ibm.com>");
62 "identify this operating system instance to the S/390 or zSeries hardware");
64 static char *system_name = NULL;
65 MODULE_PARM (system_name, "s");
66 MODULE_PARM_DESC (system_name, "e.g. hostname - max. 8 characters");
68 static char *sysplex_name = NULL;
69 #ifdef ALLOW_SYSPLEX_NAME
70 MODULE_PARM (sysplex_name, "s");
71 MODULE_PARM_DESC (sysplex_name, "if applicable - max. 8 characters");
74 static char *system_type = "LINUX";
76 hwc_request_t cpi_request =
79 hwc_callback_t cpi_callback;
81 static DECLARE_MUTEX_LOCKED (sem);
84 cpi_module_init (void)
87 int system_type_length;
88 int system_name_length;
89 int sysplex_name_length = 0;
92 if (!MACHINE_HAS_HWC) {
93 printk ("cpi: bug: hardware console not present\n");
98 printk ("cpi: bug: no system type specified\n");
102 system_type_length = strlen (system_type);
103 if (system_type_length > CPI_LENGTH_SYSTEM_NAME) {
104 printk ("cpi: bug: system type has length of %i characters - "
105 "only %i characters supported\n",
107 CPI_LENGTH_SYSTEM_TYPE);
112 printk ("cpi: no system name specified\n");
116 system_name_length = strlen (system_name);
117 if (system_name_length > CPI_LENGTH_SYSTEM_NAME) {
118 printk ("cpi: system name has length of %i characters - "
119 "only %i characters supported\n",
121 CPI_LENGTH_SYSTEM_NAME);
126 sysplex_name_length = strlen (sysplex_name);
127 if (sysplex_name_length > CPI_LENGTH_SYSPLEX_NAME) {
128 printk ("cpi: sysplex name has length of %i characters - "
129 "only %i characters supported\n",
131 CPI_LENGTH_SYSPLEX_NAME);
136 cpi_hwcb = kmalloc (sizeof (cpi_hwcb_t), GFP_KERNEL);
138 printk ("cpi: no storage to fulfill request\n");
142 memset (cpi_hwcb, 0, sizeof (cpi_hwcb_t));
144 cpi_hwcb->length = sizeof (cpi_hwcb_t);
145 cpi_hwcb->cpi_evbuf.length = sizeof (cpi_evbuf_t);
146 cpi_hwcb->cpi_evbuf.type = 0x0B;
148 memset (cpi_hwcb->cpi_evbuf.system_type, ' ', CPI_LENGTH_SYSTEM_TYPE);
149 memcpy (cpi_hwcb->cpi_evbuf.system_type, system_type, system_type_length);
150 HWC_ASCEBC_STR (cpi_hwcb->cpi_evbuf.system_type, CPI_LENGTH_SYSTEM_TYPE);
151 EBC_TOUPPER (cpi_hwcb->cpi_evbuf.system_type, CPI_LENGTH_SYSTEM_TYPE);
153 memset (cpi_hwcb->cpi_evbuf.system_name, ' ', CPI_LENGTH_SYSTEM_NAME);
154 memcpy (cpi_hwcb->cpi_evbuf.system_name, system_name, system_name_length);
155 HWC_ASCEBC_STR (cpi_hwcb->cpi_evbuf.system_name, CPI_LENGTH_SYSTEM_NAME);
156 EBC_TOUPPER (cpi_hwcb->cpi_evbuf.system_name, CPI_LENGTH_SYSTEM_NAME);
158 cpi_hwcb->cpi_evbuf.system_level = LINUX_VERSION_CODE;
161 memset (cpi_hwcb->cpi_evbuf.sysplex_name, ' ', CPI_LENGTH_SYSPLEX_NAME);
162 memcpy (cpi_hwcb->cpi_evbuf.sysplex_name, sysplex_name, sysplex_name_length);
163 HWC_ASCEBC_STR (cpi_hwcb->cpi_evbuf.sysplex_name, CPI_LENGTH_SYSPLEX_NAME);
164 EBC_TOUPPER (cpi_hwcb->cpi_evbuf.sysplex_name, CPI_LENGTH_SYSPLEX_NAME);
166 cpi_request.block = cpi_hwcb;
167 cpi_request.word = HWC_CMDW_WRITEDATA;
168 cpi_request.callback = cpi_callback;
170 for (retries = CPI_RETRIES; retries; retries--) {
171 retval = hwc_send (&cpi_request);
174 set_current_state (TASK_INTERRUPTIBLE);
175 schedule_timeout (CPI_SLEEP_TICKS);
180 switch (cpi_hwcb->response_code) {
182 printk ("cpi: succeeded\n");
185 printk ("cpi: failed with response code 0x%x\n",
186 cpi_hwcb->response_code);
192 printk ("cpi: failed (%i)\n", retval);
202 cpi_module_exit (void)
204 printk ("cpi: exit\n");
208 cpi_callback (hwc_request_t * req)