aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/chsc_sch.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/cio/chsc_sch.c')
-rw-r--r--drivers/s390/cio/chsc_sch.c30
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:
770static long chsc_ioctl(struct file *filp, unsigned int cmd, 772static 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 }