Commit 64150adf89df2ed165d6760f414fa6df07d22628

Authored by Michael Holzheu
Committed by Martin Schwidefsky
1 parent 80b054ba2a

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
... ... @@ -10,11 +10,6 @@
10 10  
11 11 #define CHSC_SDA_OC_MSS 0x2
12 12  
13   -struct chsc_header {
14   - u16 length;
15   - u16 code;
16   -} __attribute__ ((packed));
17   -
18 13 #define NR_MEASUREMENT_CHARS 5
19 14 struct cmg_chars {
20 15 u32 values[NR_MEASUREMENT_CHARS];
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: