hwc_cpi.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:5k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * Author: Martin Peschke <mpeschke@de.ibm.com>
  3.  * Copyright (C) 2001 IBM Entwicklung GmbH, IBM Corporation
  4.  */
  5. #include <linux/string.h>
  6. #include <linux/ctype.h>
  7. #include <linux/module.h>
  8. #include <linux/init.h>
  9. #include <linux/errno.h>
  10. #include <linux/slab.h>
  11. #include <linux/version.h>
  12. #include <asm/semaphore.h>
  13. #include <asm/ebcdic.h>
  14. #include "hwc_rw.h"
  15. #include "hwc.h"
  16. #define CPI_RETRIES 3
  17. #define CPI_SLEEP_TICKS 50
  18. #define CPI_LENGTH_SYSTEM_TYPE 8
  19. #define CPI_LENGTH_SYSTEM_NAME 8
  20. #define CPI_LENGTH_SYSPLEX_NAME 8
  21. typedef struct {
  22. _EBUF_HEADER
  23. u8 id_format;
  24. u8 reserved0;
  25. u8 system_type[CPI_LENGTH_SYSTEM_TYPE];
  26. u64 reserved1;
  27. u8 system_name[CPI_LENGTH_SYSTEM_NAME];
  28. u64 reserved2;
  29. u64 system_level;
  30. u64 reserved3;
  31. u8 sysplex_name[CPI_LENGTH_SYSPLEX_NAME];
  32. u8 reserved4[16];
  33. } __attribute__ ((packed)) 
  34. cpi_evbuf_t;
  35. typedef struct _cpi_hwcb_t {
  36. _HWCB_HEADER
  37. cpi_evbuf_t cpi_evbuf;
  38. } __attribute__ ((packed)) 
  39. cpi_hwcb_t;
  40. cpi_hwcb_t *cpi_hwcb;
  41. static int __init cpi_module_init (void);
  42. static void __exit cpi_module_exit (void);
  43. module_init (cpi_module_init);
  44. module_exit (cpi_module_exit);
  45. MODULE_AUTHOR (
  46.       "Martin Peschke, IBM Deutschland Entwicklung GmbH "
  47.       "<mpeschke@de.ibm.com>");
  48. MODULE_DESCRIPTION (
  49.   "identify this operating system instance to the S/390 or zSeries hardware");
  50. static char *system_name = NULL;
  51. MODULE_PARM (system_name, "s");
  52. MODULE_PARM_DESC (system_name, "e.g. hostname - max. 8 characters");
  53. static char *sysplex_name = NULL;
  54. #ifdef ALLOW_SYSPLEX_NAME
  55. MODULE_PARM (sysplex_name, "s");
  56. MODULE_PARM_DESC (sysplex_name, "if applicable - max. 8 characters");
  57. #endif
  58. static char *system_type = "LINUX";
  59. hwc_request_t cpi_request =
  60. {};
  61. hwc_callback_t cpi_callback;
  62. static DECLARE_MUTEX_LOCKED (sem);
  63. static int __init 
  64. cpi_module_init (void)
  65. {
  66. int retval;
  67. int system_type_length;
  68. int system_name_length;
  69. int sysplex_name_length = 0;
  70. int retries;
  71. if (!MACHINE_HAS_HWC) {
  72. printk ("cpi: bug: hardware console not presentn");
  73. retval = -EINVAL;
  74. goto out;
  75. }
  76. if (!system_type) {
  77. printk ("cpi: bug: no system type specifiedn");
  78. retval = -EINVAL;
  79. goto out;
  80. }
  81. system_type_length = strlen (system_type);
  82. if (system_type_length > CPI_LENGTH_SYSTEM_NAME) {
  83. printk ("cpi: bug: system type has length of %i characters - "
  84. "only %i characters supportedn",
  85. system_type_length,
  86. CPI_LENGTH_SYSTEM_TYPE);
  87. retval = -EINVAL;
  88. goto out;
  89. }
  90. if (!system_name) {
  91. printk ("cpi: no system name specifiedn");
  92. retval = -EINVAL;
  93. goto out;
  94. }
  95. system_name_length = strlen (system_name);
  96. if (system_name_length > CPI_LENGTH_SYSTEM_NAME) {
  97. printk ("cpi: system name has length of %i characters - "
  98. "only %i characters supportedn",
  99. system_name_length,
  100. CPI_LENGTH_SYSTEM_NAME);
  101. retval = -EINVAL;
  102. goto out;
  103. }
  104. if (sysplex_name) {
  105. sysplex_name_length = strlen (sysplex_name);
  106. if (sysplex_name_length > CPI_LENGTH_SYSPLEX_NAME) {
  107. printk ("cpi: sysplex name has length of %i characters - "
  108. "only %i characters supportedn",
  109. sysplex_name_length,
  110. CPI_LENGTH_SYSPLEX_NAME);
  111. retval = -EINVAL;
  112. goto out;
  113. }
  114. }
  115. cpi_hwcb = kmalloc (sizeof (cpi_hwcb_t), GFP_KERNEL);
  116. if (!cpi_hwcb) {
  117. printk ("cpi: no storage to fulfill requestn");
  118. retval = -ENOMEM;
  119. goto out;
  120. }
  121. memset (cpi_hwcb, 0, sizeof (cpi_hwcb_t));
  122. cpi_hwcb->length = sizeof (cpi_hwcb_t);
  123. cpi_hwcb->cpi_evbuf.length = sizeof (cpi_evbuf_t);
  124. cpi_hwcb->cpi_evbuf.type = 0x0B;
  125. memset (cpi_hwcb->cpi_evbuf.system_type, ' ', CPI_LENGTH_SYSTEM_TYPE);
  126. memcpy (cpi_hwcb->cpi_evbuf.system_type, system_type, system_type_length);
  127. HWC_ASCEBC_STR (cpi_hwcb->cpi_evbuf.system_type, CPI_LENGTH_SYSTEM_TYPE);
  128. EBC_TOUPPER (cpi_hwcb->cpi_evbuf.system_type, CPI_LENGTH_SYSTEM_TYPE);
  129. memset (cpi_hwcb->cpi_evbuf.system_name, ' ', CPI_LENGTH_SYSTEM_NAME);
  130. memcpy (cpi_hwcb->cpi_evbuf.system_name, system_name, system_name_length);
  131. HWC_ASCEBC_STR (cpi_hwcb->cpi_evbuf.system_name, CPI_LENGTH_SYSTEM_NAME);
  132. EBC_TOUPPER (cpi_hwcb->cpi_evbuf.system_name, CPI_LENGTH_SYSTEM_NAME);
  133. cpi_hwcb->cpi_evbuf.system_level = LINUX_VERSION_CODE;
  134. if (sysplex_name) {
  135. memset (cpi_hwcb->cpi_evbuf.sysplex_name, ' ', CPI_LENGTH_SYSPLEX_NAME);
  136. memcpy (cpi_hwcb->cpi_evbuf.sysplex_name, sysplex_name, sysplex_name_length);
  137. HWC_ASCEBC_STR (cpi_hwcb->cpi_evbuf.sysplex_name, CPI_LENGTH_SYSPLEX_NAME);
  138. EBC_TOUPPER (cpi_hwcb->cpi_evbuf.sysplex_name, CPI_LENGTH_SYSPLEX_NAME);
  139. }
  140. cpi_request.block = cpi_hwcb;
  141. cpi_request.word = HWC_CMDW_WRITEDATA;
  142. cpi_request.callback = cpi_callback;
  143. for (retries = CPI_RETRIES; retries; retries--) {
  144. retval = hwc_send (&cpi_request);
  145. if (retval) {
  146. set_current_state (TASK_INTERRUPTIBLE);
  147. schedule_timeout (CPI_SLEEP_TICKS);
  148. } else {
  149. down (&sem);
  150. switch (cpi_hwcb->response_code) {
  151. case 0x0020:
  152. printk ("cpi: succeededn");
  153. break;
  154. default:
  155. printk ("cpi: failed with response code 0x%xn",
  156. cpi_hwcb->response_code);
  157. }
  158. goto free;
  159. }
  160. }
  161. printk ("cpi: failed (%i)n", retval);
  162.       free:
  163. kfree (cpi_hwcb);
  164.       out:
  165. return retval;
  166. }
  167. static void __exit 
  168. cpi_module_exit (void)
  169. {
  170. printk ("cpi: exitn");
  171. }
  172. void 
  173. cpi_callback (hwc_request_t * req)
  174. {
  175. up (&sem);
  176. }