aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/crypto/ap_bus.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/crypto/ap_bus.c')
-rw-r--r--drivers/s390/crypto/ap_bus.c82
1 files changed, 72 insertions, 10 deletions
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 91c6028d7b74..16e4a25596e7 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -27,6 +27,7 @@
27#define KMSG_COMPONENT "ap" 27#define KMSG_COMPONENT "ap"
28#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 28#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
29 29
30#include <linux/kernel_stat.h>
30#include <linux/module.h> 31#include <linux/module.h>
31#include <linux/init.h> 32#include <linux/init.h>
32#include <linux/delay.h> 33#include <linux/delay.h>
@@ -154,14 +155,7 @@ static inline int ap_instructions_available(void)
154 */ 155 */
155static int ap_interrupts_available(void) 156static int ap_interrupts_available(void)
156{ 157{
157 unsigned long long facility_bits[2]; 158 return test_facility(2) && test_facility(65);
158
159 if (stfle(facility_bits, 2) <= 1)
160 return 0;
161 if (!(facility_bits[0] & (1ULL << 61)) ||
162 !(facility_bits[1] & (1ULL << 62)))
163 return 0;
164 return 1;
165} 159}
166 160
167/** 161/**
@@ -228,6 +222,69 @@ ap_queue_interruption_control(ap_qid_t qid, void *ind)
228} 222}
229#endif 223#endif
230 224
225static inline struct ap_queue_status __ap_4096_commands_available(ap_qid_t qid,
226 int *support)
227{
228 register unsigned long reg0 asm ("0") = 0UL | qid | (1UL << 23);
229 register struct ap_queue_status reg1 asm ("1");
230 register unsigned long reg2 asm ("2") = 0UL;
231
232 asm volatile(
233 ".long 0xb2af0000\n"
234 "0: la %1,0\n"
235 "1:\n"
236 EX_TABLE(0b, 1b)
237 : "+d" (reg0), "=d" (reg1), "=d" (reg2)
238 :
239 : "cc");
240
241 if (reg2 & 0x6000000000000000ULL)
242 *support = 1;
243 else
244 *support = 0;
245
246 return reg1;
247}
248
249/**
250 * ap_4096_commands_availablen(): Check for availability of 4096 bit RSA
251 * support.
252 * @qid: The AP queue number
253 *
254 * Returns 1 if 4096 bit RSA keys are support fo the AP, returns 0 if not.
255 */
256int ap_4096_commands_available(ap_qid_t qid)
257{
258 struct ap_queue_status status;
259 int i, support = 0;
260 status = __ap_4096_commands_available(qid, &support);
261
262 for (i = 0; i < AP_MAX_RESET; i++) {
263 switch (status.response_code) {
264 case AP_RESPONSE_NORMAL:
265 return support;
266 case AP_RESPONSE_RESET_IN_PROGRESS:
267 case AP_RESPONSE_BUSY:
268 break;
269 case AP_RESPONSE_Q_NOT_AVAIL:
270 case AP_RESPONSE_DECONFIGURED:
271 case AP_RESPONSE_CHECKSTOPPED:
272 case AP_RESPONSE_INVALID_ADDRESS:
273 return 0;
274 case AP_RESPONSE_OTHERWISE_CHANGED:
275 break;
276 default:
277 break;
278 }
279 if (i < AP_MAX_RESET - 1) {
280 udelay(5);
281 status = __ap_4096_commands_available(qid, &support);
282 }
283 }
284 return support;
285}
286EXPORT_SYMBOL(ap_4096_commands_available);
287
231/** 288/**
232 * ap_queue_enable_interruption(): Enable interruption on an AP. 289 * ap_queue_enable_interruption(): Enable interruption on an AP.
233 * @qid: The AP queue number 290 * @qid: The AP queue number
@@ -1049,6 +1106,7 @@ out:
1049 1106
1050static void ap_interrupt_handler(void *unused1, void *unused2) 1107static void ap_interrupt_handler(void *unused1, void *unused2)
1051{ 1108{
1109 kstat_cpu(smp_processor_id()).irqs[IOINT_APB]++;
1052 tasklet_schedule(&ap_tasklet); 1110 tasklet_schedule(&ap_tasklet);
1053} 1111}
1054 1112
@@ -1125,8 +1183,12 @@ static void ap_scan_bus(struct work_struct *unused)
1125 INIT_LIST_HEAD(&ap_dev->list); 1183 INIT_LIST_HEAD(&ap_dev->list);
1126 setup_timer(&ap_dev->timeout, ap_request_timeout, 1184 setup_timer(&ap_dev->timeout, ap_request_timeout,
1127 (unsigned long) ap_dev); 1185 (unsigned long) ap_dev);
1128 if (device_type == 0) 1186 if (device_type == 0) {
1129 ap_probe_device_type(ap_dev); 1187 if (ap_probe_device_type(ap_dev)) {
1188 kfree(ap_dev);
1189 continue;
1190 }
1191 }
1130 else 1192 else
1131 ap_dev->device_type = device_type; 1193 ap_dev->device_type = device_type;
1132 1194