diff options
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/char/Makefile | 2 | ||||
-rw-r--r-- | drivers/s390/char/sclp_chp.c | 200 | ||||
-rw-r--r-- | drivers/s390/char/sclp_cmd.c | 123 |
3 files changed, 123 insertions, 202 deletions
diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile index 9317333ec149..7e73e39a1741 100644 --- a/drivers/s390/char/Makefile +++ b/drivers/s390/char/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += ctrlchar.o keyboard.o defkeymap.o sclp.o sclp_rw.o sclp_quiesce.o \ | 5 | obj-y += ctrlchar.o keyboard.o defkeymap.o sclp.o sclp_rw.o sclp_quiesce.o \ |
6 | sclp_cmd.o sclp_config.o sclp_chp.o sclp_cpi_sys.o | 6 | sclp_cmd.o sclp_config.o sclp_cpi_sys.o |
7 | 7 | ||
8 | obj-$(CONFIG_TN3270) += raw3270.o | 8 | obj-$(CONFIG_TN3270) += raw3270.o |
9 | obj-$(CONFIG_TN3270_CONSOLE) += con3270.o | 9 | obj-$(CONFIG_TN3270_CONSOLE) += con3270.o |
diff --git a/drivers/s390/char/sclp_chp.c b/drivers/s390/char/sclp_chp.c deleted file mode 100644 index c68f5e7e63a0..000000000000 --- a/drivers/s390/char/sclp_chp.c +++ /dev/null | |||
@@ -1,200 +0,0 @@ | |||
1 | /* | ||
2 | * drivers/s390/char/sclp_chp.c | ||
3 | * | ||
4 | * Copyright IBM Corp. 2007 | ||
5 | * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | ||
6 | */ | ||
7 | |||
8 | #include <linux/types.h> | ||
9 | #include <linux/gfp.h> | ||
10 | #include <linux/errno.h> | ||
11 | #include <linux/completion.h> | ||
12 | #include <asm/sclp.h> | ||
13 | #include <asm/chpid.h> | ||
14 | |||
15 | #include "sclp.h" | ||
16 | |||
17 | #define TAG "sclp_chp: " | ||
18 | |||
19 | #define SCLP_CMDW_CONFIGURE_CHANNEL_PATH 0x000f0001 | ||
20 | #define SCLP_CMDW_DECONFIGURE_CHANNEL_PATH 0x000e0001 | ||
21 | #define SCLP_CMDW_READ_CHANNEL_PATH_INFORMATION 0x00030001 | ||
22 | |||
23 | static inline sclp_cmdw_t get_configure_cmdw(struct chp_id chpid) | ||
24 | { | ||
25 | return SCLP_CMDW_CONFIGURE_CHANNEL_PATH | chpid.id << 8; | ||
26 | } | ||
27 | |||
28 | static inline sclp_cmdw_t get_deconfigure_cmdw(struct chp_id chpid) | ||
29 | { | ||
30 | return SCLP_CMDW_DECONFIGURE_CHANNEL_PATH | chpid.id << 8; | ||
31 | } | ||
32 | |||
33 | static void chp_callback(struct sclp_req *req, void *data) | ||
34 | { | ||
35 | struct completion *completion = data; | ||
36 | |||
37 | complete(completion); | ||
38 | } | ||
39 | |||
40 | struct chp_cfg_sccb { | ||
41 | struct sccb_header header; | ||
42 | u8 ccm; | ||
43 | u8 reserved[6]; | ||
44 | u8 cssid; | ||
45 | } __attribute__((packed)); | ||
46 | |||
47 | struct chp_cfg_data { | ||
48 | struct chp_cfg_sccb sccb; | ||
49 | struct sclp_req req; | ||
50 | struct completion completion; | ||
51 | } __attribute__((packed)); | ||
52 | |||
53 | static int do_configure(sclp_cmdw_t cmd) | ||
54 | { | ||
55 | struct chp_cfg_data *data; | ||
56 | int rc; | ||
57 | |||
58 | if (!SCLP_HAS_CHP_RECONFIG) | ||
59 | return -EOPNOTSUPP; | ||
60 | /* Prepare sccb. */ | ||
61 | data = (struct chp_cfg_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | ||
62 | if (!data) | ||
63 | return -ENOMEM; | ||
64 | data->sccb.header.length = sizeof(struct chp_cfg_sccb); | ||
65 | data->req.command = cmd; | ||
66 | data->req.sccb = &(data->sccb); | ||
67 | data->req.status = SCLP_REQ_FILLED; | ||
68 | data->req.callback = chp_callback; | ||
69 | data->req.callback_data = &(data->completion); | ||
70 | init_completion(&data->completion); | ||
71 | |||
72 | /* Perform sclp request. */ | ||
73 | rc = sclp_add_request(&(data->req)); | ||
74 | if (rc) | ||
75 | goto out; | ||
76 | wait_for_completion(&data->completion); | ||
77 | |||
78 | /* Check response .*/ | ||
79 | if (data->req.status != SCLP_REQ_DONE) { | ||
80 | printk(KERN_WARNING TAG "configure channel-path request failed " | ||
81 | "(status=0x%02x)\n", data->req.status); | ||
82 | rc = -EIO; | ||
83 | goto out; | ||
84 | } | ||
85 | switch (data->sccb.header.response_code) { | ||
86 | case 0x0020: | ||
87 | case 0x0120: | ||
88 | case 0x0440: | ||
89 | case 0x0450: | ||
90 | break; | ||
91 | default: | ||
92 | printk(KERN_WARNING TAG "configure channel-path failed " | ||
93 | "(cmd=0x%08x, response=0x%04x)\n", cmd, | ||
94 | data->sccb.header.response_code); | ||
95 | rc = -EIO; | ||
96 | break; | ||
97 | } | ||
98 | out: | ||
99 | free_page((unsigned long) data); | ||
100 | |||
101 | return rc; | ||
102 | } | ||
103 | |||
104 | /** | ||
105 | * sclp_chp_configure - perform configure channel-path sclp command | ||
106 | * @chpid: channel-path ID | ||
107 | * | ||
108 | * Perform configure channel-path command sclp command for specified chpid. | ||
109 | * Return 0 after command successfully finished, non-zero otherwise. | ||
110 | */ | ||
111 | int sclp_chp_configure(struct chp_id chpid) | ||
112 | { | ||
113 | return do_configure(get_configure_cmdw(chpid)); | ||
114 | } | ||
115 | |||
116 | /** | ||
117 | * sclp_chp_deconfigure - perform deconfigure channel-path sclp command | ||
118 | * @chpid: channel-path ID | ||
119 | * | ||
120 | * Perform deconfigure channel-path command sclp command for specified chpid | ||
121 | * and wait for completion. On success return 0. Return non-zero otherwise. | ||
122 | */ | ||
123 | int sclp_chp_deconfigure(struct chp_id chpid) | ||
124 | { | ||
125 | return do_configure(get_deconfigure_cmdw(chpid)); | ||
126 | } | ||
127 | |||
128 | struct chp_info_sccb { | ||
129 | struct sccb_header header; | ||
130 | u8 recognized[SCLP_CHP_INFO_MASK_SIZE]; | ||
131 | u8 standby[SCLP_CHP_INFO_MASK_SIZE]; | ||
132 | u8 configured[SCLP_CHP_INFO_MASK_SIZE]; | ||
133 | u8 ccm; | ||
134 | u8 reserved[6]; | ||
135 | u8 cssid; | ||
136 | } __attribute__((packed)); | ||
137 | |||
138 | struct chp_info_data { | ||
139 | struct chp_info_sccb sccb; | ||
140 | struct sclp_req req; | ||
141 | struct completion completion; | ||
142 | } __attribute__((packed)); | ||
143 | |||
144 | /** | ||
145 | * sclp_chp_read_info - perform read channel-path information sclp command | ||
146 | * @info: resulting channel-path information data | ||
147 | * | ||
148 | * Perform read channel-path information sclp command and wait for completion. | ||
149 | * On success, store channel-path information in @info and return 0. Return | ||
150 | * non-zero otherwise. | ||
151 | */ | ||
152 | int sclp_chp_read_info(struct sclp_chp_info *info) | ||
153 | { | ||
154 | struct chp_info_data *data; | ||
155 | int rc; | ||
156 | |||
157 | if (!SCLP_HAS_CHP_INFO) | ||
158 | return -EOPNOTSUPP; | ||
159 | /* Prepare sccb. */ | ||
160 | data = (struct chp_info_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | ||
161 | if (!data) | ||
162 | return -ENOMEM; | ||
163 | data->sccb.header.length = sizeof(struct chp_info_sccb); | ||
164 | data->req.command = SCLP_CMDW_READ_CHANNEL_PATH_INFORMATION; | ||
165 | data->req.sccb = &(data->sccb); | ||
166 | data->req.status = SCLP_REQ_FILLED; | ||
167 | data->req.callback = chp_callback; | ||
168 | data->req.callback_data = &(data->completion); | ||
169 | init_completion(&data->completion); | ||
170 | |||
171 | /* Perform sclp request. */ | ||
172 | rc = sclp_add_request(&(data->req)); | ||
173 | if (rc) | ||
174 | goto out; | ||
175 | wait_for_completion(&data->completion); | ||
176 | |||
177 | /* Check response .*/ | ||
178 | if (data->req.status != SCLP_REQ_DONE) { | ||
179 | printk(KERN_WARNING TAG "read channel-path info request failed " | ||
180 | "(status=0x%02x)\n", data->req.status); | ||
181 | rc = -EIO; | ||
182 | goto out; | ||
183 | } | ||
184 | if (data->sccb.header.response_code != 0x0010) { | ||
185 | printk(KERN_WARNING TAG "read channel-path info failed " | ||
186 | "(response=0x%04x)\n", data->sccb.header.response_code); | ||
187 | rc = -EIO; | ||
188 | goto out; | ||
189 | } | ||
190 | memcpy(info->recognized, data->sccb.recognized, | ||
191 | SCLP_CHP_INFO_MASK_SIZE); | ||
192 | memcpy(info->standby, data->sccb.standby, | ||
193 | SCLP_CHP_INFO_MASK_SIZE); | ||
194 | memcpy(info->configured, data->sccb.configured, | ||
195 | SCLP_CHP_INFO_MASK_SIZE); | ||
196 | out: | ||
197 | free_page((unsigned long) data); | ||
198 | |||
199 | return rc; | ||
200 | } | ||
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index ba004fd43c05..d7e6f4d65b78 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c | |||
@@ -2,7 +2,8 @@ | |||
2 | * drivers/s390/char/sclp_cmd.c | 2 | * drivers/s390/char/sclp_cmd.c |
3 | * | 3 | * |
4 | * Copyright IBM Corp. 2007 | 4 | * Copyright IBM Corp. 2007 |
5 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> | 5 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>, |
6 | * Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | ||
6 | */ | 7 | */ |
7 | 8 | ||
8 | #include <linux/completion.h> | 9 | #include <linux/completion.h> |
@@ -10,6 +11,7 @@ | |||
10 | #include <linux/errno.h> | 11 | #include <linux/errno.h> |
11 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
12 | #include <linux/string.h> | 13 | #include <linux/string.h> |
14 | #include <asm/chpid.h> | ||
13 | #include <asm/sclp.h> | 15 | #include <asm/sclp.h> |
14 | #include "sclp.h" | 16 | #include "sclp.h" |
15 | 17 | ||
@@ -317,3 +319,122 @@ int sclp_cpu_deconfigure(u8 cpu) | |||
317 | { | 319 | { |
318 | return do_cpu_configure(SCLP_CMDW_DECONFIGURE_CPU | cpu << 8); | 320 | return do_cpu_configure(SCLP_CMDW_DECONFIGURE_CPU | cpu << 8); |
319 | } | 321 | } |
322 | |||
323 | /* | ||
324 | * Channel path configuration related functions. | ||
325 | */ | ||
326 | |||
327 | #define SCLP_CMDW_CONFIGURE_CHPATH 0x000f0001 | ||
328 | #define SCLP_CMDW_DECONFIGURE_CHPATH 0x000e0001 | ||
329 | #define SCLP_CMDW_READ_CHPATH_INFORMATION 0x00030001 | ||
330 | |||
331 | struct chp_cfg_sccb { | ||
332 | struct sccb_header header; | ||
333 | u8 ccm; | ||
334 | u8 reserved[6]; | ||
335 | u8 cssid; | ||
336 | } __attribute__((packed)); | ||
337 | |||
338 | static int do_chp_configure(sclp_cmdw_t cmd) | ||
339 | { | ||
340 | struct chp_cfg_sccb *sccb; | ||
341 | int rc; | ||
342 | |||
343 | if (!SCLP_HAS_CHP_RECONFIG) | ||
344 | return -EOPNOTSUPP; | ||
345 | /* Prepare sccb. */ | ||
346 | sccb = (struct chp_cfg_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | ||
347 | if (!sccb) | ||
348 | return -ENOMEM; | ||
349 | sccb->header.length = sizeof(*sccb); | ||
350 | rc = do_sync_request(cmd, sccb); | ||
351 | if (rc) | ||
352 | goto out; | ||
353 | switch (sccb->header.response_code) { | ||
354 | case 0x0020: | ||
355 | case 0x0120: | ||
356 | case 0x0440: | ||
357 | case 0x0450: | ||
358 | break; | ||
359 | default: | ||
360 | printk(KERN_WARNING TAG "configure channel-path failed " | ||
361 | "(cmd=0x%08x, response=0x%04x)\n", cmd, | ||
362 | sccb->header.response_code); | ||
363 | rc = -EIO; | ||
364 | break; | ||
365 | } | ||
366 | out: | ||
367 | free_page((unsigned long) sccb); | ||
368 | return rc; | ||
369 | } | ||
370 | |||
371 | /** | ||
372 | * sclp_chp_configure - perform configure channel-path sclp command | ||
373 | * @chpid: channel-path ID | ||
374 | * | ||
375 | * Perform configure channel-path command sclp command for specified chpid. | ||
376 | * Return 0 after command successfully finished, non-zero otherwise. | ||
377 | */ | ||
378 | int sclp_chp_configure(struct chp_id chpid) | ||
379 | { | ||
380 | return do_chp_configure(SCLP_CMDW_CONFIGURE_CHPATH | chpid.id << 8); | ||
381 | } | ||
382 | |||
383 | /** | ||
384 | * sclp_chp_deconfigure - perform deconfigure channel-path sclp command | ||
385 | * @chpid: channel-path ID | ||
386 | * | ||
387 | * Perform deconfigure channel-path command sclp command for specified chpid | ||
388 | * and wait for completion. On success return 0. Return non-zero otherwise. | ||
389 | */ | ||
390 | int sclp_chp_deconfigure(struct chp_id chpid) | ||
391 | { | ||
392 | return do_chp_configure(SCLP_CMDW_DECONFIGURE_CHPATH | chpid.id << 8); | ||
393 | } | ||
394 | |||
395 | struct chp_info_sccb { | ||
396 | struct sccb_header header; | ||
397 | u8 recognized[SCLP_CHP_INFO_MASK_SIZE]; | ||
398 | u8 standby[SCLP_CHP_INFO_MASK_SIZE]; | ||
399 | u8 configured[SCLP_CHP_INFO_MASK_SIZE]; | ||
400 | u8 ccm; | ||
401 | u8 reserved[6]; | ||
402 | u8 cssid; | ||
403 | } __attribute__((packed)); | ||
404 | |||
405 | /** | ||
406 | * sclp_chp_read_info - perform read channel-path information sclp command | ||
407 | * @info: resulting channel-path information data | ||
408 | * | ||
409 | * Perform read channel-path information sclp command and wait for completion. | ||
410 | * On success, store channel-path information in @info and return 0. Return | ||
411 | * non-zero otherwise. | ||
412 | */ | ||
413 | int sclp_chp_read_info(struct sclp_chp_info *info) | ||
414 | { | ||
415 | struct chp_info_sccb *sccb; | ||
416 | int rc; | ||
417 | |||
418 | if (!SCLP_HAS_CHP_INFO) | ||
419 | return -EOPNOTSUPP; | ||
420 | /* Prepare sccb. */ | ||
421 | sccb = (struct chp_info_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | ||
422 | if (!sccb) | ||
423 | return -ENOMEM; | ||
424 | sccb->header.length = sizeof(*sccb); | ||
425 | rc = do_sync_request(SCLP_CMDW_READ_CHPATH_INFORMATION, sccb); | ||
426 | if (rc) | ||
427 | goto out; | ||
428 | if (sccb->header.response_code != 0x0010) { | ||
429 | printk(KERN_WARNING TAG "read channel-path info failed " | ||
430 | "(response=0x%04x)\n", sccb->header.response_code); | ||
431 | rc = -EIO; | ||
432 | goto out; | ||
433 | } | ||
434 | memcpy(info->recognized, sccb->recognized, SCLP_CHP_INFO_MASK_SIZE); | ||
435 | memcpy(info->standby, sccb->standby, SCLP_CHP_INFO_MASK_SIZE); | ||
436 | memcpy(info->configured, sccb->configured, SCLP_CHP_INFO_MASK_SIZE); | ||
437 | out: | ||
438 | free_page((unsigned long) sccb); | ||
439 | return rc; | ||
440 | } | ||