diff options
Diffstat (limited to 'drivers/s390/cio/chsc_sch.c')
-rw-r--r-- | drivers/s390/cio/chsc_sch.c | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c index cc5144b6f9d9..3b6f4adc5094 100644 --- a/drivers/s390/cio/chsc_sch.c +++ b/drivers/s390/cio/chsc_sch.c | |||
@@ -7,11 +7,13 @@ | |||
7 | * | 7 | * |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/slab.h> | ||
10 | #include <linux/device.h> | 11 | #include <linux/device.h> |
11 | #include <linux/module.h> | 12 | #include <linux/module.h> |
12 | #include <linux/uaccess.h> | 13 | #include <linux/uaccess.h> |
13 | #include <linux/miscdevice.h> | 14 | #include <linux/miscdevice.h> |
14 | 15 | ||
16 | #include <asm/compat.h> | ||
15 | #include <asm/cio.h> | 17 | #include <asm/cio.h> |
16 | #include <asm/chsc.h> | 18 | #include <asm/chsc.h> |
17 | #include <asm/isc.h> | 19 | #include <asm/isc.h> |
@@ -50,7 +52,7 @@ static void chsc_subchannel_irq(struct subchannel *sch) | |||
50 | { | 52 | { |
51 | struct chsc_private *private = sch->private; | 53 | struct chsc_private *private = sch->private; |
52 | struct chsc_request *request = private->request; | 54 | struct chsc_request *request = private->request; |
53 | struct irb *irb = (struct irb *)__LC_IRB; | 55 | struct irb *irb = (struct irb *)&S390_lowcore.irb; |
54 | 56 | ||
55 | CHSC_LOG(4, "irb"); | 57 | CHSC_LOG(4, "irb"); |
56 | CHSC_LOG_HEX(4, irb, sizeof(*irb)); | 58 | CHSC_LOG_HEX(4, irb, sizeof(*irb)); |
@@ -122,7 +124,7 @@ static int chsc_subchannel_prepare(struct subchannel *sch) | |||
122 | * since we don't have a way to clear the subchannel and | 124 | * since we don't have a way to clear the subchannel and |
123 | * cannot disable it with a request running. | 125 | * cannot disable it with a request running. |
124 | */ | 126 | */ |
125 | cc = stsch(sch->schid, &schib); | 127 | cc = stsch_err(sch->schid, &schib); |
126 | if (!cc && scsw_stctl(&schib.scsw)) | 128 | if (!cc && scsw_stctl(&schib.scsw)) |
127 | return -EAGAIN; | 129 | return -EAGAIN; |
128 | return 0; | 130 | return 0; |
@@ -236,7 +238,7 @@ static int chsc_async(struct chsc_async_area *chsc_area, | |||
236 | int ret = -ENODEV; | 238 | int ret = -ENODEV; |
237 | char dbf[10]; | 239 | char dbf[10]; |
238 | 240 | ||
239 | chsc_area->header.key = PAGE_DEFAULT_KEY; | 241 | chsc_area->header.key = PAGE_DEFAULT_KEY >> 4; |
240 | while ((sch = chsc_get_next_subchannel(sch))) { | 242 | while ((sch = chsc_get_next_subchannel(sch))) { |
241 | spin_lock(sch->lock); | 243 | spin_lock(sch->lock); |
242 | private = sch->private; | 244 | private = sch->private; |
@@ -770,24 +772,30 @@ out_free: | |||
770 | static long chsc_ioctl(struct file *filp, unsigned int cmd, | 772 | static long chsc_ioctl(struct file *filp, unsigned int cmd, |
771 | unsigned long arg) | 773 | unsigned long arg) |
772 | { | 774 | { |
775 | void __user *argp; | ||
776 | |||
773 | CHSC_MSG(2, "chsc_ioctl called, cmd=%x\n", cmd); | 777 | CHSC_MSG(2, "chsc_ioctl called, cmd=%x\n", cmd); |
778 | if (is_compat_task()) | ||
779 | argp = compat_ptr(arg); | ||
780 | else | ||
781 | argp = (void __user *)arg; | ||
774 | switch (cmd) { | 782 | switch (cmd) { |
775 | case CHSC_START: | 783 | case CHSC_START: |
776 | return chsc_ioctl_start((void __user *)arg); | 784 | return chsc_ioctl_start(argp); |
777 | case CHSC_INFO_CHANNEL_PATH: | 785 | case CHSC_INFO_CHANNEL_PATH: |
778 | return chsc_ioctl_info_channel_path((void __user *)arg); | 786 | return chsc_ioctl_info_channel_path(argp); |
779 | case CHSC_INFO_CU: | 787 | case CHSC_INFO_CU: |
780 | return chsc_ioctl_info_cu((void __user *)arg); | 788 | return chsc_ioctl_info_cu(argp); |
781 | case CHSC_INFO_SCH_CU: | 789 | case CHSC_INFO_SCH_CU: |
782 | return chsc_ioctl_info_sch_cu((void __user *)arg); | 790 | return chsc_ioctl_info_sch_cu(argp); |
783 | case CHSC_INFO_CI: | 791 | case CHSC_INFO_CI: |
784 | return chsc_ioctl_conf_info((void __user *)arg); | 792 | return chsc_ioctl_conf_info(argp); |
785 | case CHSC_INFO_CCL: | 793 | case CHSC_INFO_CCL: |
786 | return chsc_ioctl_conf_comp_list((void __user *)arg); | 794 | return chsc_ioctl_conf_comp_list(argp); |
787 | case CHSC_INFO_CPD: | 795 | case CHSC_INFO_CPD: |
788 | return chsc_ioctl_chpd((void __user *)arg); | 796 | return chsc_ioctl_chpd(argp); |
789 | case CHSC_INFO_DCAL: | 797 | case CHSC_INFO_DCAL: |
790 | return chsc_ioctl_dcal((void __user *)arg); | 798 | return chsc_ioctl_dcal(argp); |
791 | default: /* unknown ioctl number */ | 799 | default: /* unknown ioctl number */ |
792 | return -ENOIOCTLCMD; | 800 | return -ENOIOCTLCMD; |
793 | } | 801 | } |