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.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 1294876bf7b4..91c6028d7b74 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -33,6 +33,7 @@
33#include <linux/err.h> 33#include <linux/err.h>
34#include <linux/interrupt.h> 34#include <linux/interrupt.h>
35#include <linux/workqueue.h> 35#include <linux/workqueue.h>
36#include <linux/slab.h>
36#include <linux/notifier.h> 37#include <linux/notifier.h>
37#include <linux/kthread.h> 38#include <linux/kthread.h>
38#include <linux/mutex.h> 39#include <linux/mutex.h>
@@ -102,6 +103,7 @@ static atomic_t ap_poll_requests = ATOMIC_INIT(0);
102static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait); 103static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait);
103static struct task_struct *ap_poll_kthread = NULL; 104static struct task_struct *ap_poll_kthread = NULL;
104static DEFINE_MUTEX(ap_poll_thread_mutex); 105static DEFINE_MUTEX(ap_poll_thread_mutex);
106static DEFINE_SPINLOCK(ap_poll_timer_lock);
105static void *ap_interrupt_indicator; 107static void *ap_interrupt_indicator;
106static struct hrtimer ap_poll_timer; 108static struct hrtimer ap_poll_timer;
107/* In LPAR poll with 4kHz frequency. Poll every 250000 nanoseconds. 109/* In LPAR poll with 4kHz frequency. Poll every 250000 nanoseconds.
@@ -282,6 +284,7 @@ static int ap_queue_enable_interruption(ap_qid_t qid, void *ind)
282 * @psmid: The program supplied message identifier 284 * @psmid: The program supplied message identifier
283 * @msg: The message text 285 * @msg: The message text
284 * @length: The message length 286 * @length: The message length
287 * @special: Special Bit
285 * 288 *
286 * Returns AP queue status structure. 289 * Returns AP queue status structure.
287 * Condition code 1 on NQAP can't happen because the L bit is 1. 290 * Condition code 1 on NQAP can't happen because the L bit is 1.
@@ -289,7 +292,8 @@ static int ap_queue_enable_interruption(ap_qid_t qid, void *ind)
289 * because a segment boundary was reached. The NQAP is repeated. 292 * because a segment boundary was reached. The NQAP is repeated.
290 */ 293 */
291static inline struct ap_queue_status 294static inline struct ap_queue_status
292__ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length) 295__ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length,
296 unsigned int special)
293{ 297{
294 typedef struct { char _[length]; } msgblock; 298 typedef struct { char _[length]; } msgblock;
295 register unsigned long reg0 asm ("0") = qid | 0x40000000UL; 299 register unsigned long reg0 asm ("0") = qid | 0x40000000UL;
@@ -299,6 +303,9 @@ __ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length)
299 register unsigned long reg4 asm ("4") = (unsigned int) (psmid >> 32); 303 register unsigned long reg4 asm ("4") = (unsigned int) (psmid >> 32);
300 register unsigned long reg5 asm ("5") = (unsigned int) psmid; 304 register unsigned long reg5 asm ("5") = (unsigned int) psmid;
301 305
306 if (special == 1)
307 reg0 |= 0x400000UL;
308
302 asm volatile ( 309 asm volatile (
303 "0: .long 0xb2ad0042\n" /* DQAP */ 310 "0: .long 0xb2ad0042\n" /* DQAP */
304 " brc 2,0b" 311 " brc 2,0b"
@@ -312,13 +319,15 @@ int ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length)
312{ 319{
313 struct ap_queue_status status; 320 struct ap_queue_status status;
314 321
315 status = __ap_send(qid, psmid, msg, length); 322 status = __ap_send(qid, psmid, msg, length, 0);
316 switch (status.response_code) { 323 switch (status.response_code) {
317 case AP_RESPONSE_NORMAL: 324 case AP_RESPONSE_NORMAL:
318 return 0; 325 return 0;
319 case AP_RESPONSE_Q_FULL: 326 case AP_RESPONSE_Q_FULL:
320 case AP_RESPONSE_RESET_IN_PROGRESS: 327 case AP_RESPONSE_RESET_IN_PROGRESS:
321 return -EBUSY; 328 return -EBUSY;
329 case AP_RESPONSE_REQ_FAC_NOT_INST:
330 return -EINVAL;
322 default: /* Device is gone. */ 331 default: /* Device is gone. */
323 return -ENODEV; 332 return -ENODEV;
324 } 333 }
@@ -1008,7 +1017,7 @@ static int ap_probe_device_type(struct ap_device *ap_dev)
1008 } 1017 }
1009 1018
1010 status = __ap_send(ap_dev->qid, 0x0102030405060708ULL, 1019 status = __ap_send(ap_dev->qid, 0x0102030405060708ULL,
1011 msg, sizeof(msg)); 1020 msg, sizeof(msg), 0);
1012 if (status.response_code != AP_RESPONSE_NORMAL) { 1021 if (status.response_code != AP_RESPONSE_NORMAL) {
1013 rc = -ENODEV; 1022 rc = -ENODEV;
1014 goto out_free; 1023 goto out_free;
@@ -1163,16 +1172,19 @@ ap_config_timeout(unsigned long ptr)
1163static inline void ap_schedule_poll_timer(void) 1172static inline void ap_schedule_poll_timer(void)
1164{ 1173{
1165 ktime_t hr_time; 1174 ktime_t hr_time;
1175
1176 spin_lock_bh(&ap_poll_timer_lock);
1166 if (ap_using_interrupts() || ap_suspend_flag) 1177 if (ap_using_interrupts() || ap_suspend_flag)
1167 return; 1178 goto out;
1168 if (hrtimer_is_queued(&ap_poll_timer)) 1179 if (hrtimer_is_queued(&ap_poll_timer))
1169 return; 1180 goto out;
1170 if (ktime_to_ns(hrtimer_expires_remaining(&ap_poll_timer)) <= 0) { 1181 if (ktime_to_ns(hrtimer_expires_remaining(&ap_poll_timer)) <= 0) {
1171 hr_time = ktime_set(0, poll_timeout); 1182 hr_time = ktime_set(0, poll_timeout);
1172 hrtimer_forward_now(&ap_poll_timer, hr_time); 1183 hrtimer_forward_now(&ap_poll_timer, hr_time);
1173 hrtimer_restart(&ap_poll_timer); 1184 hrtimer_restart(&ap_poll_timer);
1174 } 1185 }
1175 return; 1186out:
1187 spin_unlock_bh(&ap_poll_timer_lock);
1176} 1188}
1177 1189
1178/** 1190/**
@@ -1243,7 +1255,7 @@ static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
1243 /* Start the next request on the queue. */ 1255 /* Start the next request on the queue. */
1244 ap_msg = list_entry(ap_dev->requestq.next, struct ap_message, list); 1256 ap_msg = list_entry(ap_dev->requestq.next, struct ap_message, list);
1245 status = __ap_send(ap_dev->qid, ap_msg->psmid, 1257 status = __ap_send(ap_dev->qid, ap_msg->psmid,
1246 ap_msg->message, ap_msg->length); 1258 ap_msg->message, ap_msg->length, ap_msg->special);
1247 switch (status.response_code) { 1259 switch (status.response_code) {
1248 case AP_RESPONSE_NORMAL: 1260 case AP_RESPONSE_NORMAL:
1249 atomic_inc(&ap_poll_requests); 1261 atomic_inc(&ap_poll_requests);
@@ -1261,6 +1273,7 @@ static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
1261 *flags |= 2; 1273 *flags |= 2;
1262 break; 1274 break;
1263 case AP_RESPONSE_MESSAGE_TOO_BIG: 1275 case AP_RESPONSE_MESSAGE_TOO_BIG:
1276 case AP_RESPONSE_REQ_FAC_NOT_INST:
1264 return -EINVAL; 1277 return -EINVAL;
1265 default: 1278 default:
1266 return -ENODEV; 1279 return -ENODEV;
@@ -1302,7 +1315,8 @@ static int __ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_ms
1302 if (list_empty(&ap_dev->requestq) && 1315 if (list_empty(&ap_dev->requestq) &&
1303 ap_dev->queue_count < ap_dev->queue_depth) { 1316 ap_dev->queue_count < ap_dev->queue_depth) {
1304 status = __ap_send(ap_dev->qid, ap_msg->psmid, 1317 status = __ap_send(ap_dev->qid, ap_msg->psmid,
1305 ap_msg->message, ap_msg->length); 1318 ap_msg->message, ap_msg->length,
1319 ap_msg->special);
1306 switch (status.response_code) { 1320 switch (status.response_code) {
1307 case AP_RESPONSE_NORMAL: 1321 case AP_RESPONSE_NORMAL:
1308 list_add_tail(&ap_msg->list, &ap_dev->pendingq); 1322 list_add_tail(&ap_msg->list, &ap_dev->pendingq);
@@ -1317,6 +1331,7 @@ static int __ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_ms
1317 ap_dev->requestq_count++; 1331 ap_dev->requestq_count++;
1318 ap_dev->total_request_count++; 1332 ap_dev->total_request_count++;
1319 return -EBUSY; 1333 return -EBUSY;
1334 case AP_RESPONSE_REQ_FAC_NOT_INST:
1320 case AP_RESPONSE_MESSAGE_TOO_BIG: 1335 case AP_RESPONSE_MESSAGE_TOO_BIG:
1321 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL)); 1336 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL));
1322 return -EINVAL; 1337 return -EINVAL;
@@ -1658,6 +1673,7 @@ int __init ap_module_init(void)
1658 */ 1673 */
1659 if (MACHINE_IS_VM) 1674 if (MACHINE_IS_VM)
1660 poll_timeout = 1500000; 1675 poll_timeout = 1500000;
1676 spin_lock_init(&ap_poll_timer_lock);
1661 hrtimer_init(&ap_poll_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); 1677 hrtimer_init(&ap_poll_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
1662 ap_poll_timer.function = ap_poll_timeout; 1678 ap_poll_timer.function = ap_poll_timeout;
1663 1679