diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-10 17:46:09 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-10 17:46:09 -0400 |
commit | 9f9d76321659b5ebc9939101481f7c3ce228ea6e (patch) | |
tree | 7abd21796ad85ba6c606cd2a93e787fb90b3abe6 /drivers | |
parent | 1b21f458ddbc8fb6fceeb68158e9e04b2571dabd (diff) | |
parent | f60d89108f3481ca11672b82cf7e67171e050ce4 (diff) |
Merge branch 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6:
[S390] vmlogrdr function annotation.
[S390] s390: rename CPU_IDLE to S390_CPU_IDLE
[S390] cio: Remove prototype for non-existing function cmf_reset().
[S390] zcrypt: fix request timeout handling
[S390] system call optimization.
[S390] dasd: Avoid compile warnings on !CONFIG_DASD_PROFILE
[S390] Remove volatile from atomic_t
[S390] Program check in diag 210 under 31 bit
[S390] Bogomips calculation for 64 bit.
[S390] smp: Merge smp_count_cpus() and smp_get_save_areas().
[S390] zcore: Fix __user annotation.
[S390] fixed cdl-format detection.
[S390] sclp: Test facility list before executing a service call.
[S390] sclp: introduce some new interfaces.
[S390] Fixed comment typo.
[S390] vmcp cleanup
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/s390/block/dasd_proc.c | 4 | ||||
-rw-r--r-- | drivers/s390/char/sclp.h | 12 | ||||
-rw-r--r-- | drivers/s390/char/sclp_chp.c | 4 | ||||
-rw-r--r-- | drivers/s390/char/sclp_info.c | 117 | ||||
-rw-r--r-- | drivers/s390/char/vmcp.c | 13 | ||||
-rw-r--r-- | drivers/s390/char/vmlogrdr.c | 4 | ||||
-rw-r--r-- | drivers/s390/char/zcore.c | 2 | ||||
-rw-r--r-- | drivers/s390/cio/device_id.c | 22 | ||||
-rw-r--r-- | drivers/s390/crypto/ap_bus.c | 98 | ||||
-rw-r--r-- | drivers/s390/crypto/ap_bus.h | 11 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_cex2a.c | 27 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_pcica.c | 27 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_pcicc.c | 27 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_pcixcc.c | 40 |
14 files changed, 264 insertions, 144 deletions
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c index 8b3b0f4a157c..ac7e8ef504cb 100644 --- a/drivers/s390/block/dasd_proc.c +++ b/drivers/s390/block/dasd_proc.c | |||
@@ -28,6 +28,7 @@ static struct proc_dir_entry *dasd_proc_root_entry = NULL; | |||
28 | static struct proc_dir_entry *dasd_devices_entry = NULL; | 28 | static struct proc_dir_entry *dasd_devices_entry = NULL; |
29 | static struct proc_dir_entry *dasd_statistics_entry = NULL; | 29 | static struct proc_dir_entry *dasd_statistics_entry = NULL; |
30 | 30 | ||
31 | #ifdef CONFIG_DASD_PROFILE | ||
31 | static char * | 32 | static char * |
32 | dasd_get_user_string(const char __user *user_buf, size_t user_len) | 33 | dasd_get_user_string(const char __user *user_buf, size_t user_len) |
33 | { | 34 | { |
@@ -47,6 +48,7 @@ dasd_get_user_string(const char __user *user_buf, size_t user_len) | |||
47 | buffer[user_len] = 0; | 48 | buffer[user_len] = 0; |
48 | return buffer; | 49 | return buffer; |
49 | } | 50 | } |
51 | #endif /* CONFIG_DASD_PROFILE */ | ||
50 | 52 | ||
51 | static int | 53 | static int |
52 | dasd_devices_show(struct seq_file *m, void *v) | 54 | dasd_devices_show(struct seq_file *m, void *v) |
@@ -167,6 +169,7 @@ dasd_calc_metrics(char *page, char **start, off_t off, | |||
167 | return len; | 169 | return len; |
168 | } | 170 | } |
169 | 171 | ||
172 | #ifdef CONFIG_DASD_PROFILE | ||
170 | static char * | 173 | static char * |
171 | dasd_statistics_array(char *str, unsigned int *array, int shift) | 174 | dasd_statistics_array(char *str, unsigned int *array, int shift) |
172 | { | 175 | { |
@@ -180,6 +183,7 @@ dasd_statistics_array(char *str, unsigned int *array, int shift) | |||
180 | str += sprintf(str,"\n"); | 183 | str += sprintf(str,"\n"); |
181 | return str; | 184 | return str; |
182 | } | 185 | } |
186 | #endif /* CONFIG_DASD_PROFILE */ | ||
183 | 187 | ||
184 | static int | 188 | static int |
185 | dasd_statistics_read(char *page, char **start, off_t off, | 189 | dasd_statistics_read(char *page, char **start, off_t off, |
diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h index dbb99d1b6f57..c7318a125852 100644 --- a/drivers/s390/char/sclp.h +++ b/drivers/s390/char/sclp.h | |||
@@ -72,6 +72,18 @@ typedef unsigned int sclp_cmdw_t; | |||
72 | 72 | ||
73 | typedef u32 sccb_mask_t; /* ATTENTION: assumes 32bit mask !!! */ | 73 | typedef u32 sccb_mask_t; /* ATTENTION: assumes 32bit mask !!! */ |
74 | 74 | ||
75 | struct sccb_header { | ||
76 | u16 length; | ||
77 | u8 function_code; | ||
78 | u8 control_mask[3]; | ||
79 | u16 response_code; | ||
80 | } __attribute__((packed)); | ||
81 | |||
82 | extern u64 sclp_facilities; | ||
83 | |||
84 | #define SCLP_HAS_CHP_INFO (sclp_facilities & 0x8000000000000000ULL) | ||
85 | #define SCLP_HAS_CHP_RECONFIG (sclp_facilities & 0x2000000000000000ULL) | ||
86 | |||
75 | struct gds_subvector { | 87 | struct gds_subvector { |
76 | u8 length; | 88 | u8 length; |
77 | u8 key; | 89 | u8 key; |
diff --git a/drivers/s390/char/sclp_chp.c b/drivers/s390/char/sclp_chp.c index a66b914519b5..c68f5e7e63a0 100644 --- a/drivers/s390/char/sclp_chp.c +++ b/drivers/s390/char/sclp_chp.c | |||
@@ -55,6 +55,8 @@ static int do_configure(sclp_cmdw_t cmd) | |||
55 | struct chp_cfg_data *data; | 55 | struct chp_cfg_data *data; |
56 | int rc; | 56 | int rc; |
57 | 57 | ||
58 | if (!SCLP_HAS_CHP_RECONFIG) | ||
59 | return -EOPNOTSUPP; | ||
58 | /* Prepare sccb. */ | 60 | /* Prepare sccb. */ |
59 | data = (struct chp_cfg_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | 61 | data = (struct chp_cfg_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA); |
60 | if (!data) | 62 | if (!data) |
@@ -152,6 +154,8 @@ int sclp_chp_read_info(struct sclp_chp_info *info) | |||
152 | struct chp_info_data *data; | 154 | struct chp_info_data *data; |
153 | int rc; | 155 | int rc; |
154 | 156 | ||
157 | if (!SCLP_HAS_CHP_INFO) | ||
158 | return -EOPNOTSUPP; | ||
155 | /* Prepare sccb. */ | 159 | /* Prepare sccb. */ |
156 | data = (struct chp_info_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | 160 | data = (struct chp_info_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA); |
157 | if (!data) | 161 | if (!data) |
diff --git a/drivers/s390/char/sclp_info.c b/drivers/s390/char/sclp_info.c index 7bcbe643b087..a1136e052750 100644 --- a/drivers/s390/char/sclp_info.c +++ b/drivers/s390/char/sclp_info.c | |||
@@ -11,47 +11,106 @@ | |||
11 | #include <asm/sclp.h> | 11 | #include <asm/sclp.h> |
12 | #include "sclp.h" | 12 | #include "sclp.h" |
13 | 13 | ||
14 | struct sclp_readinfo_sccb s390_readinfo_sccb; | 14 | struct sclp_readinfo_sccb { |
15 | struct sccb_header header; /* 0-7 */ | ||
16 | u16 rnmax; /* 8-9 */ | ||
17 | u8 rnsize; /* 10 */ | ||
18 | u8 _reserved0[24 - 11]; /* 11-23 */ | ||
19 | u8 loadparm[8]; /* 24-31 */ | ||
20 | u8 _reserved1[48 - 32]; /* 32-47 */ | ||
21 | u64 facilities; /* 48-55 */ | ||
22 | u8 _reserved2[91 - 56]; /* 56-90 */ | ||
23 | u8 flags; /* 91 */ | ||
24 | u8 _reserved3[100 - 92]; /* 92-99 */ | ||
25 | u32 rnsize2; /* 100-103 */ | ||
26 | u64 rnmax2; /* 104-111 */ | ||
27 | u8 _reserved4[4096 - 112]; /* 112-4095 */ | ||
28 | } __attribute__((packed, aligned(4096))); | ||
29 | |||
30 | static struct sclp_readinfo_sccb __initdata early_readinfo_sccb; | ||
31 | static int __initdata early_readinfo_sccb_valid; | ||
32 | |||
33 | u64 sclp_facilities; | ||
15 | 34 | ||
16 | void __init sclp_readinfo_early(void) | 35 | void __init sclp_readinfo_early(void) |
17 | { | 36 | { |
18 | sclp_cmdw_t command; | ||
19 | struct sccb_header *sccb; | ||
20 | int ret; | 37 | int ret; |
38 | int i; | ||
39 | struct sclp_readinfo_sccb *sccb; | ||
40 | sclp_cmdw_t commands[] = {SCLP_CMDW_READ_SCP_INFO_FORCED, | ||
41 | SCLP_CMDW_READ_SCP_INFO}; | ||
21 | 42 | ||
22 | __ctl_set_bit(0, 9); /* enable service signal subclass mask */ | 43 | /* Enable service signal subclass mask. */ |
23 | 44 | __ctl_set_bit(0, 9); | |
24 | sccb = &s390_readinfo_sccb.header; | 45 | sccb = &early_readinfo_sccb; |
25 | command = SCLP_CMDW_READ_SCP_INFO_FORCED; | 46 | for (i = 0; i < ARRAY_SIZE(commands); i++) { |
26 | while (1) { | 47 | do { |
27 | u16 response; | 48 | memset(sccb, 0, sizeof(*sccb)); |
28 | 49 | sccb->header.length = sizeof(*sccb); | |
29 | memset(&s390_readinfo_sccb, 0, sizeof(s390_readinfo_sccb)); | 50 | sccb->header.control_mask[2] = 0x80; |
30 | sccb->length = sizeof(s390_readinfo_sccb); | 51 | ret = sclp_service_call(commands[i], sccb); |
31 | sccb->control_mask[2] = 0x80; | 52 | } while (ret == -EBUSY); |
32 | |||
33 | ret = sclp_service_call(command, &s390_readinfo_sccb); | ||
34 | |||
35 | if (ret == -EIO) | ||
36 | goto out; | ||
37 | if (ret == -EBUSY) | ||
38 | continue; | ||
39 | 53 | ||
54 | if (ret) | ||
55 | break; | ||
40 | __load_psw_mask(PSW_BASE_BITS | PSW_MASK_EXT | | 56 | __load_psw_mask(PSW_BASE_BITS | PSW_MASK_EXT | |
41 | PSW_MASK_WAIT | PSW_DEFAULT_KEY); | 57 | PSW_MASK_WAIT | PSW_DEFAULT_KEY); |
42 | local_irq_disable(); | 58 | local_irq_disable(); |
59 | /* | ||
60 | * Contents of the sccb might have changed | ||
61 | * therefore a barrier is needed. | ||
62 | */ | ||
43 | barrier(); | 63 | barrier(); |
64 | if (sccb->header.response_code == 0x10) { | ||
65 | early_readinfo_sccb_valid = 1; | ||
66 | break; | ||
67 | } | ||
68 | if (sccb->header.response_code != 0x1f0) | ||
69 | break; | ||
70 | } | ||
71 | /* Disable service signal subclass mask again. */ | ||
72 | __ctl_clear_bit(0, 9); | ||
73 | } | ||
44 | 74 | ||
45 | response = sccb->response_code; | 75 | void __init sclp_facilities_detect(void) |
76 | { | ||
77 | if (!early_readinfo_sccb_valid) | ||
78 | return; | ||
79 | sclp_facilities = early_readinfo_sccb.facilities; | ||
80 | } | ||
46 | 81 | ||
47 | if (response == 0x10) | 82 | unsigned long long __init sclp_memory_detect(void) |
48 | break; | 83 | { |
84 | unsigned long long memsize; | ||
85 | struct sclp_readinfo_sccb *sccb; | ||
49 | 86 | ||
50 | if (response != 0x1f0 || command == SCLP_CMDW_READ_SCP_INFO) | 87 | if (!early_readinfo_sccb_valid) |
51 | break; | 88 | return 0; |
89 | sccb = &early_readinfo_sccb; | ||
90 | if (sccb->rnsize) | ||
91 | memsize = sccb->rnsize << 20; | ||
92 | else | ||
93 | memsize = sccb->rnsize2 << 20; | ||
94 | if (sccb->rnmax) | ||
95 | memsize *= sccb->rnmax; | ||
96 | else | ||
97 | memsize *= sccb->rnmax2; | ||
98 | return memsize; | ||
99 | } | ||
52 | 100 | ||
53 | command = SCLP_CMDW_READ_SCP_INFO; | 101 | /* |
54 | } | 102 | * This function will be called after sclp_memory_detect(), which gets called |
55 | out: | 103 | * early from early.c code. Therefore the sccb should have valid contents. |
56 | __ctl_clear_bit(0, 9); /* disable service signal subclass mask */ | 104 | */ |
105 | void __init sclp_get_ipl_info(struct sclp_ipl_info *info) | ||
106 | { | ||
107 | struct sclp_readinfo_sccb *sccb; | ||
108 | |||
109 | if (!early_readinfo_sccb_valid) | ||
110 | return; | ||
111 | sccb = &early_readinfo_sccb; | ||
112 | info->is_valid = 1; | ||
113 | if (sccb->flags & 0x2) | ||
114 | info->has_dump = 1; | ||
115 | memcpy(&info->loadparm, &sccb->loadparm, LOADPARM_LEN); | ||
57 | } | 116 | } |
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c index fce3dac5cb3e..82e6a6b253eb 100644 --- a/drivers/s390/char/vmcp.c +++ b/drivers/s390/char/vmcp.c | |||
@@ -175,13 +175,12 @@ static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
175 | 175 | ||
176 | static const struct file_operations vmcp_fops = { | 176 | static const struct file_operations vmcp_fops = { |
177 | .owner = THIS_MODULE, | 177 | .owner = THIS_MODULE, |
178 | .open = &vmcp_open, | 178 | .open = vmcp_open, |
179 | .release = &vmcp_release, | 179 | .release = vmcp_release, |
180 | .read = &vmcp_read, | 180 | .read = vmcp_read, |
181 | .llseek = &no_llseek, | 181 | .write = vmcp_write, |
182 | .write = &vmcp_write, | 182 | .unlocked_ioctl = vmcp_ioctl, |
183 | .unlocked_ioctl = &vmcp_ioctl, | 183 | .compat_ioctl = vmcp_ioctl |
184 | .compat_ioctl = &vmcp_ioctl | ||
185 | }; | 184 | }; |
186 | 185 | ||
187 | static struct miscdevice vmcp_dev = { | 186 | static struct miscdevice vmcp_dev = { |
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index a5a00e9ae4d0..12f7a4ce82c1 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c | |||
@@ -835,7 +835,7 @@ static void vmlogrdr_cleanup(void) | |||
835 | } | 835 | } |
836 | 836 | ||
837 | 837 | ||
838 | static int vmlogrdr_init(void) | 838 | static int __init vmlogrdr_init(void) |
839 | { | 839 | { |
840 | int rc; | 840 | int rc; |
841 | int i; | 841 | int i; |
@@ -885,7 +885,7 @@ cleanup: | |||
885 | } | 885 | } |
886 | 886 | ||
887 | 887 | ||
888 | static void vmlogrdr_exit(void) | 888 | static void __exit vmlogrdr_exit(void) |
889 | { | 889 | { |
890 | vmlogrdr_cleanup(); | 890 | vmlogrdr_cleanup(); |
891 | printk (KERN_INFO "vmlogrdr: driver unloaded\n"); | 891 | printk (KERN_INFO "vmlogrdr: driver unloaded\n"); |
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 4e711a985d59..3712ede16723 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c | |||
@@ -156,7 +156,7 @@ static int memcpy_real(void *dest, unsigned long src, size_t count) | |||
156 | return rc; | 156 | return rc; |
157 | } | 157 | } |
158 | 158 | ||
159 | static int memcpy_real_user(__user void *dest, unsigned long src, size_t count) | 159 | static int memcpy_real_user(void __user *dest, unsigned long src, size_t count) |
160 | { | 160 | { |
161 | static char buf[4096]; | 161 | static char buf[4096]; |
162 | int offs = 0, size; | 162 | int offs = 0, size; |
diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c index 997f46874537..60b9347f7c92 100644 --- a/drivers/s390/cio/device_id.c +++ b/drivers/s390/cio/device_id.c | |||
@@ -27,7 +27,6 @@ | |||
27 | /* | 27 | /* |
28 | * diag210 is used under VM to get information about a virtual device | 28 | * diag210 is used under VM to get information about a virtual device |
29 | */ | 29 | */ |
30 | #ifdef CONFIG_64BIT | ||
31 | int | 30 | int |
32 | diag210(struct diag210 * addr) | 31 | diag210(struct diag210 * addr) |
33 | { | 32 | { |
@@ -43,6 +42,7 @@ diag210(struct diag210 * addr) | |||
43 | spin_lock_irqsave(&diag210_lock, flags); | 42 | spin_lock_irqsave(&diag210_lock, flags); |
44 | diag210_tmp = *addr; | 43 | diag210_tmp = *addr; |
45 | 44 | ||
45 | #ifdef CONFIG_64BIT | ||
46 | asm volatile( | 46 | asm volatile( |
47 | " lhi %0,-1\n" | 47 | " lhi %0,-1\n" |
48 | " sam31\n" | 48 | " sam31\n" |
@@ -51,19 +51,8 @@ diag210(struct diag210 * addr) | |||
51 | " srl %0,28\n" | 51 | " srl %0,28\n" |
52 | "1: sam64\n" | 52 | "1: sam64\n" |
53 | EX_TABLE(0b,1b) | 53 | EX_TABLE(0b,1b) |
54 | : "=&d" (ccode) : "a" (__pa(&diag210_tmp)) : "cc", "memory"); | 54 | : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); |
55 | |||
56 | *addr = diag210_tmp; | ||
57 | spin_unlock_irqrestore(&diag210_lock, flags); | ||
58 | |||
59 | return ccode; | ||
60 | } | ||
61 | #else | 55 | #else |
62 | int | ||
63 | diag210(struct diag210 * addr) | ||
64 | { | ||
65 | int ccode; | ||
66 | |||
67 | asm volatile( | 56 | asm volatile( |
68 | " lhi %0,-1\n" | 57 | " lhi %0,-1\n" |
69 | " diag %1,0,0x210\n" | 58 | " diag %1,0,0x210\n" |
@@ -71,11 +60,14 @@ diag210(struct diag210 * addr) | |||
71 | " srl %0,28\n" | 60 | " srl %0,28\n" |
72 | "1:\n" | 61 | "1:\n" |
73 | EX_TABLE(0b,1b) | 62 | EX_TABLE(0b,1b) |
74 | : "=&d" (ccode) : "a" (__pa(addr)) : "cc", "memory"); | 63 | : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); |
64 | #endif | ||
65 | |||
66 | *addr = diag210_tmp; | ||
67 | spin_unlock_irqrestore(&diag210_lock, flags); | ||
75 | 68 | ||
76 | return ccode; | 69 | return ccode; |
77 | } | 70 | } |
78 | #endif | ||
79 | 71 | ||
80 | /* | 72 | /* |
81 | * Input : | 73 | * Input : |
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 5aac0ec36368..90bd22014513 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c | |||
@@ -43,6 +43,7 @@ static void ap_poll_all(unsigned long); | |||
43 | static void ap_poll_timeout(unsigned long); | 43 | static void ap_poll_timeout(unsigned long); |
44 | static int ap_poll_thread_start(void); | 44 | static int ap_poll_thread_start(void); |
45 | static void ap_poll_thread_stop(void); | 45 | static void ap_poll_thread_stop(void); |
46 | static void ap_request_timeout(unsigned long); | ||
46 | 47 | ||
47 | /** | 48 | /** |
48 | * Module description. | 49 | * Module description. |
@@ -189,6 +190,7 @@ int ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length) | |||
189 | case AP_RESPONSE_NORMAL: | 190 | case AP_RESPONSE_NORMAL: |
190 | return 0; | 191 | return 0; |
191 | case AP_RESPONSE_Q_FULL: | 192 | case AP_RESPONSE_Q_FULL: |
193 | case AP_RESPONSE_RESET_IN_PROGRESS: | ||
192 | return -EBUSY; | 194 | return -EBUSY; |
193 | default: /* Device is gone. */ | 195 | default: /* Device is gone. */ |
194 | return -ENODEV; | 196 | return -ENODEV; |
@@ -252,6 +254,8 @@ int ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length) | |||
252 | if (status.queue_empty) | 254 | if (status.queue_empty) |
253 | return -ENOENT; | 255 | return -ENOENT; |
254 | return -EBUSY; | 256 | return -EBUSY; |
257 | case AP_RESPONSE_RESET_IN_PROGRESS: | ||
258 | return -EBUSY; | ||
255 | default: | 259 | default: |
256 | return -ENODEV; | 260 | return -ENODEV; |
257 | } | 261 | } |
@@ -326,11 +330,12 @@ static int ap_init_queue(ap_qid_t qid) | |||
326 | i = AP_MAX_RESET; /* return with -ENODEV */ | 330 | i = AP_MAX_RESET; /* return with -ENODEV */ |
327 | break; | 331 | break; |
328 | case AP_RESPONSE_RESET_IN_PROGRESS: | 332 | case AP_RESPONSE_RESET_IN_PROGRESS: |
333 | rc = -EBUSY; | ||
329 | case AP_RESPONSE_BUSY: | 334 | case AP_RESPONSE_BUSY: |
330 | default: | 335 | default: |
331 | break; | 336 | break; |
332 | } | 337 | } |
333 | if (rc != -ENODEV) | 338 | if (rc != -ENODEV && rc != -EBUSY) |
334 | break; | 339 | break; |
335 | if (i < AP_MAX_RESET - 1) { | 340 | if (i < AP_MAX_RESET - 1) { |
336 | udelay(5); | 341 | udelay(5); |
@@ -341,6 +346,40 @@ static int ap_init_queue(ap_qid_t qid) | |||
341 | } | 346 | } |
342 | 347 | ||
343 | /** | 348 | /** |
349 | * Arm request timeout if a AP device was idle and a new request is submitted. | ||
350 | */ | ||
351 | static void ap_increase_queue_count(struct ap_device *ap_dev) | ||
352 | { | ||
353 | int timeout = ap_dev->drv->request_timeout; | ||
354 | |||
355 | ap_dev->queue_count++; | ||
356 | if (ap_dev->queue_count == 1) { | ||
357 | mod_timer(&ap_dev->timeout, jiffies + timeout); | ||
358 | ap_dev->reset = AP_RESET_ARMED; | ||
359 | } | ||
360 | } | ||
361 | |||
362 | /** | ||
363 | * AP device is still alive, re-schedule request timeout if there are still | ||
364 | * pending requests. | ||
365 | */ | ||
366 | static void ap_decrease_queue_count(struct ap_device *ap_dev) | ||
367 | { | ||
368 | int timeout = ap_dev->drv->request_timeout; | ||
369 | |||
370 | ap_dev->queue_count--; | ||
371 | if (ap_dev->queue_count > 0) | ||
372 | mod_timer(&ap_dev->timeout, jiffies + timeout); | ||
373 | else | ||
374 | /** | ||
375 | * The timeout timer should to be disabled now - since | ||
376 | * del_timer_sync() is very expensive, we just tell via the | ||
377 | * reset flag to ignore the pending timeout timer. | ||
378 | */ | ||
379 | ap_dev->reset = AP_RESET_IGNORE; | ||
380 | } | ||
381 | |||
382 | /** | ||
344 | * AP device related attributes. | 383 | * AP device related attributes. |
345 | */ | 384 | */ |
346 | static ssize_t ap_hwtype_show(struct device *dev, | 385 | static ssize_t ap_hwtype_show(struct device *dev, |
@@ -498,6 +537,7 @@ static int ap_device_remove(struct device *dev) | |||
498 | struct ap_driver *ap_drv = ap_dev->drv; | 537 | struct ap_driver *ap_drv = ap_dev->drv; |
499 | 538 | ||
500 | ap_flush_queue(ap_dev); | 539 | ap_flush_queue(ap_dev); |
540 | del_timer_sync(&ap_dev->timeout); | ||
501 | if (ap_drv->remove) | 541 | if (ap_drv->remove) |
502 | ap_drv->remove(ap_dev); | 542 | ap_drv->remove(ap_dev); |
503 | spin_lock_bh(&ap_device_lock); | 543 | spin_lock_bh(&ap_device_lock); |
@@ -759,17 +799,21 @@ static void ap_scan_bus(struct work_struct *unused) | |||
759 | __ap_scan_bus); | 799 | __ap_scan_bus); |
760 | rc = ap_query_queue(qid, &queue_depth, &device_type); | 800 | rc = ap_query_queue(qid, &queue_depth, &device_type); |
761 | if (dev) { | 801 | if (dev) { |
802 | if (rc == -EBUSY) { | ||
803 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
804 | schedule_timeout(AP_RESET_TIMEOUT); | ||
805 | rc = ap_query_queue(qid, &queue_depth, | ||
806 | &device_type); | ||
807 | } | ||
762 | ap_dev = to_ap_dev(dev); | 808 | ap_dev = to_ap_dev(dev); |
763 | spin_lock_bh(&ap_dev->lock); | 809 | spin_lock_bh(&ap_dev->lock); |
764 | if (rc || ap_dev->unregistered) { | 810 | if (rc || ap_dev->unregistered) { |
765 | spin_unlock_bh(&ap_dev->lock); | 811 | spin_unlock_bh(&ap_dev->lock); |
766 | put_device(dev); | ||
767 | device_unregister(dev); | 812 | device_unregister(dev); |
813 | put_device(dev); | ||
768 | continue; | 814 | continue; |
769 | } else | 815 | } |
770 | spin_unlock_bh(&ap_dev->lock); | 816 | spin_unlock_bh(&ap_dev->lock); |
771 | } | ||
772 | if (dev) { | ||
773 | put_device(dev); | 817 | put_device(dev); |
774 | continue; | 818 | continue; |
775 | } | 819 | } |
@@ -788,6 +832,8 @@ static void ap_scan_bus(struct work_struct *unused) | |||
788 | INIT_LIST_HEAD(&ap_dev->pendingq); | 832 | INIT_LIST_HEAD(&ap_dev->pendingq); |
789 | INIT_LIST_HEAD(&ap_dev->requestq); | 833 | INIT_LIST_HEAD(&ap_dev->requestq); |
790 | INIT_LIST_HEAD(&ap_dev->list); | 834 | INIT_LIST_HEAD(&ap_dev->list); |
835 | setup_timer(&ap_dev->timeout, ap_request_timeout, | ||
836 | (unsigned long) ap_dev); | ||
791 | if (device_type == 0) | 837 | if (device_type == 0) |
792 | ap_probe_device_type(ap_dev); | 838 | ap_probe_device_type(ap_dev); |
793 | else | 839 | else |
@@ -853,7 +899,7 @@ static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags) | |||
853 | switch (status.response_code) { | 899 | switch (status.response_code) { |
854 | case AP_RESPONSE_NORMAL: | 900 | case AP_RESPONSE_NORMAL: |
855 | atomic_dec(&ap_poll_requests); | 901 | atomic_dec(&ap_poll_requests); |
856 | ap_dev->queue_count--; | 902 | ap_decrease_queue_count(ap_dev); |
857 | list_for_each_entry(ap_msg, &ap_dev->pendingq, list) { | 903 | list_for_each_entry(ap_msg, &ap_dev->pendingq, list) { |
858 | if (ap_msg->psmid != ap_dev->reply->psmid) | 904 | if (ap_msg->psmid != ap_dev->reply->psmid) |
859 | continue; | 905 | continue; |
@@ -904,7 +950,7 @@ static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags) | |||
904 | switch (status.response_code) { | 950 | switch (status.response_code) { |
905 | case AP_RESPONSE_NORMAL: | 951 | case AP_RESPONSE_NORMAL: |
906 | atomic_inc(&ap_poll_requests); | 952 | atomic_inc(&ap_poll_requests); |
907 | ap_dev->queue_count++; | 953 | ap_increase_queue_count(ap_dev); |
908 | list_move_tail(&ap_msg->list, &ap_dev->pendingq); | 954 | list_move_tail(&ap_msg->list, &ap_dev->pendingq); |
909 | ap_dev->requestq_count--; | 955 | ap_dev->requestq_count--; |
910 | ap_dev->pendingq_count++; | 956 | ap_dev->pendingq_count++; |
@@ -914,6 +960,7 @@ static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags) | |||
914 | *flags |= 2; | 960 | *flags |= 2; |
915 | break; | 961 | break; |
916 | case AP_RESPONSE_Q_FULL: | 962 | case AP_RESPONSE_Q_FULL: |
963 | case AP_RESPONSE_RESET_IN_PROGRESS: | ||
917 | *flags |= 2; | 964 | *flags |= 2; |
918 | break; | 965 | break; |
919 | case AP_RESPONSE_MESSAGE_TOO_BIG: | 966 | case AP_RESPONSE_MESSAGE_TOO_BIG: |
@@ -960,10 +1007,11 @@ static int __ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_ms | |||
960 | list_add_tail(&ap_msg->list, &ap_dev->pendingq); | 1007 | list_add_tail(&ap_msg->list, &ap_dev->pendingq); |
961 | atomic_inc(&ap_poll_requests); | 1008 | atomic_inc(&ap_poll_requests); |
962 | ap_dev->pendingq_count++; | 1009 | ap_dev->pendingq_count++; |
963 | ap_dev->queue_count++; | 1010 | ap_increase_queue_count(ap_dev); |
964 | ap_dev->total_request_count++; | 1011 | ap_dev->total_request_count++; |
965 | break; | 1012 | break; |
966 | case AP_RESPONSE_Q_FULL: | 1013 | case AP_RESPONSE_Q_FULL: |
1014 | case AP_RESPONSE_RESET_IN_PROGRESS: | ||
967 | list_add_tail(&ap_msg->list, &ap_dev->requestq); | 1015 | list_add_tail(&ap_msg->list, &ap_dev->requestq); |
968 | ap_dev->requestq_count++; | 1016 | ap_dev->requestq_count++; |
969 | ap_dev->total_request_count++; | 1017 | ap_dev->total_request_count++; |
@@ -1046,6 +1094,25 @@ static void ap_poll_timeout(unsigned long unused) | |||
1046 | } | 1094 | } |
1047 | 1095 | ||
1048 | /** | 1096 | /** |
1097 | * Reset a not responding AP device and move all requests from the | ||
1098 | * pending queue to the request queue. | ||
1099 | */ | ||
1100 | static void ap_reset(struct ap_device *ap_dev) | ||
1101 | { | ||
1102 | int rc; | ||
1103 | |||
1104 | ap_dev->reset = AP_RESET_IGNORE; | ||
1105 | atomic_sub(ap_dev->queue_count, &ap_poll_requests); | ||
1106 | ap_dev->queue_count = 0; | ||
1107 | list_splice_init(&ap_dev->pendingq, &ap_dev->requestq); | ||
1108 | ap_dev->requestq_count += ap_dev->pendingq_count; | ||
1109 | ap_dev->pendingq_count = 0; | ||
1110 | rc = ap_init_queue(ap_dev->qid); | ||
1111 | if (rc == -ENODEV) | ||
1112 | ap_dev->unregistered = 1; | ||
1113 | } | ||
1114 | |||
1115 | /** | ||
1049 | * Poll all AP devices on the bus in a round robin fashion. Continue | 1116 | * Poll all AP devices on the bus in a round robin fashion. Continue |
1050 | * polling until bit 2^0 of the control flags is not set. If bit 2^1 | 1117 | * polling until bit 2^0 of the control flags is not set. If bit 2^1 |
1051 | * of the control flags has been set arm the poll timer. | 1118 | * of the control flags has been set arm the poll timer. |
@@ -1056,6 +1123,8 @@ static int __ap_poll_all(struct ap_device *ap_dev, unsigned long *flags) | |||
1056 | if (!ap_dev->unregistered) { | 1123 | if (!ap_dev->unregistered) { |
1057 | if (ap_poll_queue(ap_dev, flags)) | 1124 | if (ap_poll_queue(ap_dev, flags)) |
1058 | ap_dev->unregistered = 1; | 1125 | ap_dev->unregistered = 1; |
1126 | if (ap_dev->reset == AP_RESET_DO) | ||
1127 | ap_reset(ap_dev); | ||
1059 | } | 1128 | } |
1060 | spin_unlock(&ap_dev->lock); | 1129 | spin_unlock(&ap_dev->lock); |
1061 | return 0; | 1130 | return 0; |
@@ -1147,6 +1216,17 @@ static void ap_poll_thread_stop(void) | |||
1147 | mutex_unlock(&ap_poll_thread_mutex); | 1216 | mutex_unlock(&ap_poll_thread_mutex); |
1148 | } | 1217 | } |
1149 | 1218 | ||
1219 | /** | ||
1220 | * Handling of request timeouts | ||
1221 | */ | ||
1222 | static void ap_request_timeout(unsigned long data) | ||
1223 | { | ||
1224 | struct ap_device *ap_dev = (struct ap_device *) data; | ||
1225 | |||
1226 | if (ap_dev->reset == AP_RESET_ARMED) | ||
1227 | ap_dev->reset = AP_RESET_DO; | ||
1228 | } | ||
1229 | |||
1150 | static void ap_reset_domain(void) | 1230 | static void ap_reset_domain(void) |
1151 | { | 1231 | { |
1152 | int i; | 1232 | int i; |
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h index 008559ea742b..87c2d6442875 100644 --- a/drivers/s390/crypto/ap_bus.h +++ b/drivers/s390/crypto/ap_bus.h | |||
@@ -33,6 +33,7 @@ | |||
33 | #define AP_DEVICES 64 /* Number of AP devices. */ | 33 | #define AP_DEVICES 64 /* Number of AP devices. */ |
34 | #define AP_DOMAINS 16 /* Number of AP domains. */ | 34 | #define AP_DOMAINS 16 /* Number of AP domains. */ |
35 | #define AP_MAX_RESET 90 /* Maximum number of resets. */ | 35 | #define AP_MAX_RESET 90 /* Maximum number of resets. */ |
36 | #define AP_RESET_TIMEOUT (HZ/2) /* Time in ticks for reset timeouts. */ | ||
36 | #define AP_CONFIG_TIME 30 /* Time in seconds between AP bus rescans. */ | 37 | #define AP_CONFIG_TIME 30 /* Time in seconds between AP bus rescans. */ |
37 | #define AP_POLL_TIME 1 /* Time in ticks between receive polls. */ | 38 | #define AP_POLL_TIME 1 /* Time in ticks between receive polls. */ |
38 | 39 | ||
@@ -83,6 +84,13 @@ struct ap_queue_status { | |||
83 | #define AP_DEVICE_TYPE_CEX2A 6 | 84 | #define AP_DEVICE_TYPE_CEX2A 6 |
84 | #define AP_DEVICE_TYPE_CEX2C 7 | 85 | #define AP_DEVICE_TYPE_CEX2C 7 |
85 | 86 | ||
87 | /** | ||
88 | * AP reset flag states | ||
89 | */ | ||
90 | #define AP_RESET_IGNORE 0 /* request timeout will be ignored */ | ||
91 | #define AP_RESET_ARMED 1 /* request timeout timer is active */ | ||
92 | #define AP_RESET_DO 2 /* AP reset required */ | ||
93 | |||
86 | struct ap_device; | 94 | struct ap_device; |
87 | struct ap_message; | 95 | struct ap_message; |
88 | 96 | ||
@@ -95,6 +103,7 @@ struct ap_driver { | |||
95 | /* receive is called from tasklet context */ | 103 | /* receive is called from tasklet context */ |
96 | void (*receive)(struct ap_device *, struct ap_message *, | 104 | void (*receive)(struct ap_device *, struct ap_message *, |
97 | struct ap_message *); | 105 | struct ap_message *); |
106 | int request_timeout; /* request timeout in jiffies */ | ||
98 | }; | 107 | }; |
99 | 108 | ||
100 | #define to_ap_drv(x) container_of((x), struct ap_driver, driver) | 109 | #define to_ap_drv(x) container_of((x), struct ap_driver, driver) |
@@ -112,6 +121,8 @@ struct ap_device { | |||
112 | int queue_depth; /* AP queue depth.*/ | 121 | int queue_depth; /* AP queue depth.*/ |
113 | int device_type; /* AP device type. */ | 122 | int device_type; /* AP device type. */ |
114 | int unregistered; /* marks AP device as unregistered */ | 123 | int unregistered; /* marks AP device as unregistered */ |
124 | struct timer_list timeout; /* Timer for request timeouts. */ | ||
125 | int reset; /* Reset required after req. timeout. */ | ||
115 | 126 | ||
116 | int queue_count; /* # messages currently on AP queue. */ | 127 | int queue_count; /* # messages currently on AP queue. */ |
117 | 128 | ||
diff --git a/drivers/s390/crypto/zcrypt_cex2a.c b/drivers/s390/crypto/zcrypt_cex2a.c index 5bb13a9d0898..08657f604b8c 100644 --- a/drivers/s390/crypto/zcrypt_cex2a.c +++ b/drivers/s390/crypto/zcrypt_cex2a.c | |||
@@ -70,6 +70,7 @@ static struct ap_driver zcrypt_cex2a_driver = { | |||
70 | .remove = zcrypt_cex2a_remove, | 70 | .remove = zcrypt_cex2a_remove, |
71 | .receive = zcrypt_cex2a_receive, | 71 | .receive = zcrypt_cex2a_receive, |
72 | .ids = zcrypt_cex2a_ids, | 72 | .ids = zcrypt_cex2a_ids, |
73 | .request_timeout = CEX2A_CLEANUP_TIME, | ||
73 | }; | 74 | }; |
74 | 75 | ||
75 | /** | 76 | /** |
@@ -306,18 +307,13 @@ static long zcrypt_cex2a_modexpo(struct zcrypt_device *zdev, | |||
306 | goto out_free; | 307 | goto out_free; |
307 | init_completion(&work); | 308 | init_completion(&work); |
308 | ap_queue_message(zdev->ap_dev, &ap_msg); | 309 | ap_queue_message(zdev->ap_dev, &ap_msg); |
309 | rc = wait_for_completion_interruptible_timeout( | 310 | rc = wait_for_completion_interruptible(&work); |
310 | &work, CEX2A_CLEANUP_TIME); | 311 | if (rc == 0) |
311 | if (rc > 0) | ||
312 | rc = convert_response(zdev, &ap_msg, mex->outputdata, | 312 | rc = convert_response(zdev, &ap_msg, mex->outputdata, |
313 | mex->outputdatalength); | 313 | mex->outputdatalength); |
314 | else { | 314 | else |
315 | /* Signal pending or message timed out. */ | 315 | /* Signal pending. */ |
316 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 316 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
317 | if (rc == 0) | ||
318 | /* Message timed out. */ | ||
319 | rc = -ETIME; | ||
320 | } | ||
321 | out_free: | 317 | out_free: |
322 | kfree(ap_msg.message); | 318 | kfree(ap_msg.message); |
323 | return rc; | 319 | return rc; |
@@ -348,18 +344,13 @@ static long zcrypt_cex2a_modexpo_crt(struct zcrypt_device *zdev, | |||
348 | goto out_free; | 344 | goto out_free; |
349 | init_completion(&work); | 345 | init_completion(&work); |
350 | ap_queue_message(zdev->ap_dev, &ap_msg); | 346 | ap_queue_message(zdev->ap_dev, &ap_msg); |
351 | rc = wait_for_completion_interruptible_timeout( | 347 | rc = wait_for_completion_interruptible(&work); |
352 | &work, CEX2A_CLEANUP_TIME); | 348 | if (rc == 0) |
353 | if (rc > 0) | ||
354 | rc = convert_response(zdev, &ap_msg, crt->outputdata, | 349 | rc = convert_response(zdev, &ap_msg, crt->outputdata, |
355 | crt->outputdatalength); | 350 | crt->outputdatalength); |
356 | else { | 351 | else |
357 | /* Signal pending or message timed out. */ | 352 | /* Signal pending. */ |
358 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 353 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
359 | if (rc == 0) | ||
360 | /* Message timed out. */ | ||
361 | rc = -ETIME; | ||
362 | } | ||
363 | out_free: | 354 | out_free: |
364 | kfree(ap_msg.message); | 355 | kfree(ap_msg.message); |
365 | return rc; | 356 | return rc; |
diff --git a/drivers/s390/crypto/zcrypt_pcica.c b/drivers/s390/crypto/zcrypt_pcica.c index 818ffe05ac00..6e93b4751782 100644 --- a/drivers/s390/crypto/zcrypt_pcica.c +++ b/drivers/s390/crypto/zcrypt_pcica.c | |||
@@ -70,6 +70,7 @@ static struct ap_driver zcrypt_pcica_driver = { | |||
70 | .remove = zcrypt_pcica_remove, | 70 | .remove = zcrypt_pcica_remove, |
71 | .receive = zcrypt_pcica_receive, | 71 | .receive = zcrypt_pcica_receive, |
72 | .ids = zcrypt_pcica_ids, | 72 | .ids = zcrypt_pcica_ids, |
73 | .request_timeout = PCICA_CLEANUP_TIME, | ||
73 | }; | 74 | }; |
74 | 75 | ||
75 | /** | 76 | /** |
@@ -290,18 +291,13 @@ static long zcrypt_pcica_modexpo(struct zcrypt_device *zdev, | |||
290 | goto out_free; | 291 | goto out_free; |
291 | init_completion(&work); | 292 | init_completion(&work); |
292 | ap_queue_message(zdev->ap_dev, &ap_msg); | 293 | ap_queue_message(zdev->ap_dev, &ap_msg); |
293 | rc = wait_for_completion_interruptible_timeout( | 294 | rc = wait_for_completion_interruptible(&work); |
294 | &work, PCICA_CLEANUP_TIME); | 295 | if (rc == 0) |
295 | if (rc > 0) | ||
296 | rc = convert_response(zdev, &ap_msg, mex->outputdata, | 296 | rc = convert_response(zdev, &ap_msg, mex->outputdata, |
297 | mex->outputdatalength); | 297 | mex->outputdatalength); |
298 | else { | 298 | else |
299 | /* Signal pending or message timed out. */ | 299 | /* Signal pending. */ |
300 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 300 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
301 | if (rc == 0) | ||
302 | /* Message timed out. */ | ||
303 | rc = -ETIME; | ||
304 | } | ||
305 | out_free: | 301 | out_free: |
306 | kfree(ap_msg.message); | 302 | kfree(ap_msg.message); |
307 | return rc; | 303 | return rc; |
@@ -332,18 +328,13 @@ static long zcrypt_pcica_modexpo_crt(struct zcrypt_device *zdev, | |||
332 | goto out_free; | 328 | goto out_free; |
333 | init_completion(&work); | 329 | init_completion(&work); |
334 | ap_queue_message(zdev->ap_dev, &ap_msg); | 330 | ap_queue_message(zdev->ap_dev, &ap_msg); |
335 | rc = wait_for_completion_interruptible_timeout( | 331 | rc = wait_for_completion_interruptible(&work); |
336 | &work, PCICA_CLEANUP_TIME); | 332 | if (rc == 0) |
337 | if (rc > 0) | ||
338 | rc = convert_response(zdev, &ap_msg, crt->outputdata, | 333 | rc = convert_response(zdev, &ap_msg, crt->outputdata, |
339 | crt->outputdatalength); | 334 | crt->outputdatalength); |
340 | else { | 335 | else |
341 | /* Signal pending or message timed out. */ | 336 | /* Signal pending. */ |
342 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 337 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
343 | if (rc == 0) | ||
344 | /* Message timed out. */ | ||
345 | rc = -ETIME; | ||
346 | } | ||
347 | out_free: | 338 | out_free: |
348 | kfree(ap_msg.message); | 339 | kfree(ap_msg.message); |
349 | return rc; | 340 | return rc; |
diff --git a/drivers/s390/crypto/zcrypt_pcicc.c b/drivers/s390/crypto/zcrypt_pcicc.c index f295a403b29a..d6d59bf9ac38 100644 --- a/drivers/s390/crypto/zcrypt_pcicc.c +++ b/drivers/s390/crypto/zcrypt_pcicc.c | |||
@@ -82,6 +82,7 @@ static struct ap_driver zcrypt_pcicc_driver = { | |||
82 | .remove = zcrypt_pcicc_remove, | 82 | .remove = zcrypt_pcicc_remove, |
83 | .receive = zcrypt_pcicc_receive, | 83 | .receive = zcrypt_pcicc_receive, |
84 | .ids = zcrypt_pcicc_ids, | 84 | .ids = zcrypt_pcicc_ids, |
85 | .request_timeout = PCICC_CLEANUP_TIME, | ||
85 | }; | 86 | }; |
86 | 87 | ||
87 | /** | 88 | /** |
@@ -501,18 +502,13 @@ static long zcrypt_pcicc_modexpo(struct zcrypt_device *zdev, | |||
501 | goto out_free; | 502 | goto out_free; |
502 | init_completion(&work); | 503 | init_completion(&work); |
503 | ap_queue_message(zdev->ap_dev, &ap_msg); | 504 | ap_queue_message(zdev->ap_dev, &ap_msg); |
504 | rc = wait_for_completion_interruptible_timeout( | 505 | rc = wait_for_completion_interruptible(&work); |
505 | &work, PCICC_CLEANUP_TIME); | 506 | if (rc == 0) |
506 | if (rc > 0) | ||
507 | rc = convert_response(zdev, &ap_msg, mex->outputdata, | 507 | rc = convert_response(zdev, &ap_msg, mex->outputdata, |
508 | mex->outputdatalength); | 508 | mex->outputdatalength); |
509 | else { | 509 | else |
510 | /* Signal pending or message timed out. */ | 510 | /* Signal pending. */ |
511 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 511 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
512 | if (rc == 0) | ||
513 | /* Message timed out. */ | ||
514 | rc = -ETIME; | ||
515 | } | ||
516 | out_free: | 512 | out_free: |
517 | free_page((unsigned long) ap_msg.message); | 513 | free_page((unsigned long) ap_msg.message); |
518 | return rc; | 514 | return rc; |
@@ -544,18 +540,13 @@ static long zcrypt_pcicc_modexpo_crt(struct zcrypt_device *zdev, | |||
544 | goto out_free; | 540 | goto out_free; |
545 | init_completion(&work); | 541 | init_completion(&work); |
546 | ap_queue_message(zdev->ap_dev, &ap_msg); | 542 | ap_queue_message(zdev->ap_dev, &ap_msg); |
547 | rc = wait_for_completion_interruptible_timeout( | 543 | rc = wait_for_completion_interruptible(&work); |
548 | &work, PCICC_CLEANUP_TIME); | 544 | if (rc == 0) |
549 | if (rc > 0) | ||
550 | rc = convert_response(zdev, &ap_msg, crt->outputdata, | 545 | rc = convert_response(zdev, &ap_msg, crt->outputdata, |
551 | crt->outputdatalength); | 546 | crt->outputdatalength); |
552 | else { | 547 | else |
553 | /* Signal pending or message timed out. */ | 548 | /* Signal pending. */ |
554 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 549 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
555 | if (rc == 0) | ||
556 | /* Message timed out. */ | ||
557 | rc = -ETIME; | ||
558 | } | ||
559 | out_free: | 550 | out_free: |
560 | free_page((unsigned long) ap_msg.message); | 551 | free_page((unsigned long) ap_msg.message); |
561 | return rc; | 552 | return rc; |
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c index 252443b6bd1b..64948788d301 100644 --- a/drivers/s390/crypto/zcrypt_pcixcc.c +++ b/drivers/s390/crypto/zcrypt_pcixcc.c | |||
@@ -93,6 +93,7 @@ static struct ap_driver zcrypt_pcixcc_driver = { | |||
93 | .remove = zcrypt_pcixcc_remove, | 93 | .remove = zcrypt_pcixcc_remove, |
94 | .receive = zcrypt_pcixcc_receive, | 94 | .receive = zcrypt_pcixcc_receive, |
95 | .ids = zcrypt_pcixcc_ids, | 95 | .ids = zcrypt_pcixcc_ids, |
96 | .request_timeout = PCIXCC_CLEANUP_TIME, | ||
96 | }; | 97 | }; |
97 | 98 | ||
98 | /** | 99 | /** |
@@ -641,18 +642,13 @@ static long zcrypt_pcixcc_modexpo(struct zcrypt_device *zdev, | |||
641 | goto out_free; | 642 | goto out_free; |
642 | init_completion(&resp_type.work); | 643 | init_completion(&resp_type.work); |
643 | ap_queue_message(zdev->ap_dev, &ap_msg); | 644 | ap_queue_message(zdev->ap_dev, &ap_msg); |
644 | rc = wait_for_completion_interruptible_timeout( | 645 | rc = wait_for_completion_interruptible(&resp_type.work); |
645 | &resp_type.work, PCIXCC_CLEANUP_TIME); | 646 | if (rc == 0) |
646 | if (rc > 0) | ||
647 | rc = convert_response_ica(zdev, &ap_msg, mex->outputdata, | 647 | rc = convert_response_ica(zdev, &ap_msg, mex->outputdata, |
648 | mex->outputdatalength); | 648 | mex->outputdatalength); |
649 | else { | 649 | else |
650 | /* Signal pending or message timed out. */ | 650 | /* Signal pending. */ |
651 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 651 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
652 | if (rc == 0) | ||
653 | /* Message timed out. */ | ||
654 | rc = -ETIME; | ||
655 | } | ||
656 | out_free: | 652 | out_free: |
657 | free_page((unsigned long) ap_msg.message); | 653 | free_page((unsigned long) ap_msg.message); |
658 | return rc; | 654 | return rc; |
@@ -685,18 +681,13 @@ static long zcrypt_pcixcc_modexpo_crt(struct zcrypt_device *zdev, | |||
685 | goto out_free; | 681 | goto out_free; |
686 | init_completion(&resp_type.work); | 682 | init_completion(&resp_type.work); |
687 | ap_queue_message(zdev->ap_dev, &ap_msg); | 683 | ap_queue_message(zdev->ap_dev, &ap_msg); |
688 | rc = wait_for_completion_interruptible_timeout( | 684 | rc = wait_for_completion_interruptible(&resp_type.work); |
689 | &resp_type.work, PCIXCC_CLEANUP_TIME); | 685 | if (rc == 0) |
690 | if (rc > 0) | ||
691 | rc = convert_response_ica(zdev, &ap_msg, crt->outputdata, | 686 | rc = convert_response_ica(zdev, &ap_msg, crt->outputdata, |
692 | crt->outputdatalength); | 687 | crt->outputdatalength); |
693 | else { | 688 | else |
694 | /* Signal pending or message timed out. */ | 689 | /* Signal pending. */ |
695 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 690 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
696 | if (rc == 0) | ||
697 | /* Message timed out. */ | ||
698 | rc = -ETIME; | ||
699 | } | ||
700 | out_free: | 691 | out_free: |
701 | free_page((unsigned long) ap_msg.message); | 692 | free_page((unsigned long) ap_msg.message); |
702 | return rc; | 693 | return rc; |
@@ -729,17 +720,12 @@ static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev, | |||
729 | goto out_free; | 720 | goto out_free; |
730 | init_completion(&resp_type.work); | 721 | init_completion(&resp_type.work); |
731 | ap_queue_message(zdev->ap_dev, &ap_msg); | 722 | ap_queue_message(zdev->ap_dev, &ap_msg); |
732 | rc = wait_for_completion_interruptible_timeout( | 723 | rc = wait_for_completion_interruptible(&resp_type.work); |
733 | &resp_type.work, PCIXCC_CLEANUP_TIME); | 724 | if (rc == 0) |
734 | if (rc > 0) | ||
735 | rc = convert_response_xcrb(zdev, &ap_msg, xcRB); | 725 | rc = convert_response_xcrb(zdev, &ap_msg, xcRB); |
736 | else { | 726 | else |
737 | /* Signal pending or message timed out. */ | 727 | /* Signal pending. */ |
738 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 728 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
739 | if (rc == 0) | ||
740 | /* Message timed out. */ | ||
741 | rc = -ETIME; | ||
742 | } | ||
743 | out_free: | 729 | out_free: |
744 | memset(ap_msg.message, 0x0, ap_msg.length); | 730 | memset(ap_msg.message, 0x0, ap_msg.length); |
745 | kfree(ap_msg.message); | 731 | kfree(ap_msg.message); |