Commit 64150adf89df2ed165d6760f414fa6df07d22628
Committed by
Martin Schwidefsky
1 parent
80b054ba2a
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
s390/cio: Introduce generic synchronous CHSC IOCTL
This patch adds a new ioctl CHSC_START_SYNC that allows to execute any synchronous CHSC that is provided by user space. Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Showing 3 changed files with 46 additions and 7 deletions Side-by-side Diff
arch/s390/include/uapi/asm/chsc.h
... | ... | @@ -29,6 +29,16 @@ |
29 | 29 | __u8 data[CHSC_SIZE - sizeof(struct chsc_async_header)]; |
30 | 30 | } __attribute__ ((packed)); |
31 | 31 | |
32 | +struct chsc_header { | |
33 | + __u16 length; | |
34 | + __u16 code; | |
35 | +} __attribute__ ((packed)); | |
36 | + | |
37 | +struct chsc_sync_area { | |
38 | + struct chsc_header header; | |
39 | + __u8 data[CHSC_SIZE - sizeof(struct chsc_header)]; | |
40 | +} __attribute__ ((packed)); | |
41 | + | |
32 | 42 | struct chsc_response_struct { |
33 | 43 | __u16 length; |
34 | 44 | __u16 code; |
... | ... | @@ -126,6 +136,7 @@ |
126 | 136 | #define CHSC_INFO_CCL _IOWR(CHSC_IOCTL_MAGIC, 0x86, struct chsc_comp_list) |
127 | 137 | #define CHSC_INFO_CPD _IOWR(CHSC_IOCTL_MAGIC, 0x87, struct chsc_cpd_info) |
128 | 138 | #define CHSC_INFO_DCAL _IOWR(CHSC_IOCTL_MAGIC, 0x88, struct chsc_dcal) |
139 | +#define CHSC_START_SYNC _IOWR(CHSC_IOCTL_MAGIC, 0x89, struct chsc_sync_area) | |
129 | 140 | |
130 | 141 | #endif |
drivers/s390/cio/chsc.h
drivers/s390/cio/chsc_sch.c
... | ... | @@ -287,11 +287,11 @@ |
287 | 287 | return ret; |
288 | 288 | } |
289 | 289 | |
290 | -static void chsc_log_command(struct chsc_async_area *chsc_area) | |
290 | +static void chsc_log_command(void *chsc_area) | |
291 | 291 | { |
292 | 292 | char dbf[10]; |
293 | 293 | |
294 | - sprintf(dbf, "CHSC:%x", chsc_area->header.code); | |
294 | + sprintf(dbf, "CHSC:%x", ((uint16_t *)chsc_area)[1]); | |
295 | 295 | CHSC_LOG(0, dbf); |
296 | 296 | CHSC_LOG_HEX(0, chsc_area, 32); |
297 | 297 | } |
... | ... | @@ -362,6 +362,37 @@ |
362 | 362 | return ret; |
363 | 363 | } |
364 | 364 | |
365 | +static int chsc_ioctl_start_sync(void __user *user_area) | |
366 | +{ | |
367 | + struct chsc_sync_area *chsc_area; | |
368 | + int ret, ccode; | |
369 | + | |
370 | + chsc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); | |
371 | + if (!chsc_area) | |
372 | + return -ENOMEM; | |
373 | + if (copy_from_user(chsc_area, user_area, PAGE_SIZE)) { | |
374 | + ret = -EFAULT; | |
375 | + goto out_free; | |
376 | + } | |
377 | + if (chsc_area->header.code & 0x4000) { | |
378 | + ret = -EINVAL; | |
379 | + goto out_free; | |
380 | + } | |
381 | + chsc_log_command(chsc_area); | |
382 | + ccode = chsc(chsc_area); | |
383 | + if (ccode != 0) { | |
384 | + ret = -EIO; | |
385 | + goto out_free; | |
386 | + } | |
387 | + if (copy_to_user(user_area, chsc_area, PAGE_SIZE)) | |
388 | + ret = -EFAULT; | |
389 | + else | |
390 | + ret = 0; | |
391 | +out_free: | |
392 | + free_page((unsigned long)chsc_area); | |
393 | + return ret; | |
394 | +} | |
395 | + | |
365 | 396 | static int chsc_ioctl_info_channel_path(void __user *user_cd) |
366 | 397 | { |
367 | 398 | struct chsc_chp_cd *cd; |
... | ... | @@ -795,6 +826,8 @@ |
795 | 826 | switch (cmd) { |
796 | 827 | case CHSC_START: |
797 | 828 | return chsc_ioctl_start(argp); |
829 | + case CHSC_START_SYNC: | |
830 | + return chsc_ioctl_start_sync(argp); | |
798 | 831 | case CHSC_INFO_CHANNEL_PATH: |
799 | 832 | return chsc_ioctl_info_channel_path(argp); |
800 | 833 | case CHSC_INFO_CU: |