blob: 3d7f19fb9a4ebda3bc744c6f1bcfcec047c73770 [file] [log] [blame]
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001/*
Holger Dengler75014552012-08-28 16:41:50 +02002 * Copyright IBM Corp. 2006, 2012
Martin Schwidefsky1534c382006-09-20 15:58:25 +02003 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
4 * Martin Schwidefsky <schwidefsky@de.ibm.com>
5 * Ralph Wuerthner <rwuerthn@de.ibm.com>
Felix Beckcb17a632008-12-25 13:38:41 +01006 * Felix Beck <felix.beck@de.ibm.com>
Holger Dengler6bed05b2011-07-24 10:48:25 +02007 * Holger Dengler <hd@linux.vnet.ibm.com>
Martin Schwidefsky1534c382006-09-20 15:58:25 +02008 *
9 * Adjunct processor bus.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2, or (at your option)
14 * any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
Martin Schwidefsky136f7a12008-12-25 13:39:46 +010026#define KMSG_COMPONENT "ap"
27#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
28
Holger Dengler62d146f2011-01-05 12:47:38 +010029#include <linux/kernel_stat.h>
Martin Schwidefsky1534c382006-09-20 15:58:25 +020030#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/delay.h>
33#include <linux/err.h>
34#include <linux/interrupt.h>
35#include <linux/workqueue.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090036#include <linux/slab.h>
Martin Schwidefsky1534c382006-09-20 15:58:25 +020037#include <linux/notifier.h>
38#include <linux/kthread.h>
39#include <linux/mutex.h>
Ralph Wuerthner85eca852006-12-08 15:54:07 +010040#include <asm/reset.h>
Felix Beckcb17a632008-12-25 13:38:41 +010041#include <asm/airq.h>
Arun Sharma600634972011-07-26 16:09:06 -070042#include <linux/atomic.h>
Felix Beckcb17a632008-12-25 13:38:41 +010043#include <asm/isc.h>
Felix Beckfe137232008-07-14 09:59:08 +020044#include <linux/hrtimer.h>
45#include <linux/ktime.h>
David Howellsa0616cd2012-03-28 18:30:02 +010046#include <asm/facility.h>
Kees Cook5d26a102014-11-20 17:05:53 -080047#include <linux/crypto.h>
Martin Schwidefsky1534c382006-09-20 15:58:25 +020048
49#include "ap_bus.h"
50
51/* Some prototypes. */
Al Viro4927b3f2006-12-06 19:18:20 +000052static void ap_scan_bus(struct work_struct *);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020053static void ap_poll_all(unsigned long);
Felix Beckfe137232008-07-14 09:59:08 +020054static enum hrtimer_restart ap_poll_timeout(struct hrtimer *);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020055static int ap_poll_thread_start(void);
56static void ap_poll_thread_stop(void);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +020057static void ap_request_timeout(unsigned long);
Felix Beckcb17a632008-12-25 13:38:41 +010058static inline void ap_schedule_poll_timer(void);
Felix Beck772f5472009-06-22 12:08:16 +020059static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags);
60static int ap_device_remove(struct device *dev);
61static int ap_device_probe(struct device *dev);
Martin Schwidefskyf4eae942013-06-24 10:30:41 +020062static void ap_interrupt_handler(struct airq_struct *airq);
Felix Beck772f5472009-06-22 12:08:16 +020063static void ap_reset(struct ap_device *ap_dev);
64static void ap_config_timeout(unsigned long ptr);
Felix Beck5314af62009-09-22 22:58:51 +020065static int ap_select_domain(void);
Holger Dengler75014552012-08-28 16:41:50 +020066static void ap_query_configuration(void);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020067
Felix Beck1749a812008-04-17 07:46:28 +020068/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +020069 * Module description.
70 */
71MODULE_AUTHOR("IBM Corporation");
Holger Dengler75014552012-08-28 16:41:50 +020072MODULE_DESCRIPTION("Adjunct Processor Bus driver, " \
73 "Copyright IBM Corp. 2006, 2012");
Martin Schwidefsky1534c382006-09-20 15:58:25 +020074MODULE_LICENSE("GPL");
Kees Cook5d26a102014-11-20 17:05:53 -080075MODULE_ALIAS_CRYPTO("z90crypt");
Martin Schwidefsky1534c382006-09-20 15:58:25 +020076
Felix Beck1749a812008-04-17 07:46:28 +020077/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +020078 * Module parameter
79 */
80int ap_domain_index = -1; /* Adjunct Processor Domain Index */
Michael Veigelc1a42f42014-04-14 14:28:27 +020081module_param_named(domain, ap_domain_index, int, S_IRUSR|S_IRGRP);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020082MODULE_PARM_DESC(domain, "domain index for ap devices");
83EXPORT_SYMBOL(ap_domain_index);
84
Felix Beckb90b34c2008-02-09 18:24:30 +010085static int ap_thread_flag = 0;
Michael Veigelc1a42f42014-04-14 14:28:27 +020086module_param_named(poll_thread, ap_thread_flag, int, S_IRUSR|S_IRGRP);
Felix Beckb90b34c2008-02-09 18:24:30 +010087MODULE_PARM_DESC(poll_thread, "Turn on/off poll thread, default is 0 (off).");
Martin Schwidefsky1534c382006-09-20 15:58:25 +020088
89static struct device *ap_root_device = NULL;
Holger Dengler75014552012-08-28 16:41:50 +020090static struct ap_config_info *ap_configuration;
Christian Maaser43c207e62008-12-25 13:38:42 +010091static DEFINE_SPINLOCK(ap_device_list_lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +010092static LIST_HEAD(ap_device_list);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020093
Felix Beck1749a812008-04-17 07:46:28 +020094/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +020095 * Workqueue & timer for bus rescan.
96 */
97static struct workqueue_struct *ap_work_queue;
98static struct timer_list ap_config_timer;
99static int ap_config_time = AP_CONFIG_TIME;
Al Viro4927b3f2006-12-06 19:18:20 +0000100static DECLARE_WORK(ap_config_work, ap_scan_bus);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200101
Felix Beck1749a812008-04-17 07:46:28 +0200102/*
Felix Beckcb17a632008-12-25 13:38:41 +0100103 * Tasklet & timer for AP request polling and interrupts
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200104 */
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200105static DECLARE_TASKLET(ap_tasklet, ap_poll_all, 0);
106static atomic_t ap_poll_requests = ATOMIC_INIT(0);
107static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait);
108static struct task_struct *ap_poll_kthread = NULL;
109static DEFINE_MUTEX(ap_poll_thread_mutex);
Felix Beck93521312009-12-07 12:52:00 +0100110static DEFINE_SPINLOCK(ap_poll_timer_lock);
Felix Beckfe137232008-07-14 09:59:08 +0200111static struct hrtimer ap_poll_timer;
112/* In LPAR poll with 4kHz frequency. Poll every 250000 nanoseconds.
113 * If z/VM change to 1500000 nanoseconds to adjust to z/VM polling.*/
114static unsigned long long poll_timeout = 250000;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200115
Felix Beck772f5472009-06-22 12:08:16 +0200116/* Suspend flag */
117static int ap_suspend_flag;
Felix Beck5314af62009-09-22 22:58:51 +0200118/* Flag to check if domain was set through module parameter domain=. This is
119 * important when supsend and resume is done in a z/VM environment where the
120 * domain might change. */
121static int user_set_domain = 0;
Felix Beck772f5472009-06-22 12:08:16 +0200122static struct bus_type ap_bus_type;
123
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200124/* Adapter interrupt definitions */
125static int ap_airq_flag;
126
127static struct airq_struct ap_airq = {
128 .handler = ap_interrupt_handler,
129 .isc = AP_ISC,
130};
131
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200132/**
Felix Beckcb17a632008-12-25 13:38:41 +0100133 * ap_using_interrupts() - Returns non-zero if interrupt support is
134 * available.
135 */
136static inline int ap_using_interrupts(void)
137{
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200138 return ap_airq_flag;
Felix Beckcb17a632008-12-25 13:38:41 +0100139}
140
141/**
Felix Beck1749a812008-04-17 07:46:28 +0200142 * ap_intructions_available() - Test if AP instructions are available.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200143 *
Felix Beck1749a812008-04-17 07:46:28 +0200144 * Returns 0 if the AP instructions are installed.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200145 */
146static inline int ap_instructions_available(void)
147{
148 register unsigned long reg0 asm ("0") = AP_MKQID(0,0);
149 register unsigned long reg1 asm ("1") = -ENODEV;
150 register unsigned long reg2 asm ("2") = 0UL;
151
152 asm volatile(
153 " .long 0xb2af0000\n" /* PQAP(TAPQ) */
154 "0: la %1,0\n"
155 "1:\n"
156 EX_TABLE(0b, 1b)
157 : "+d" (reg0), "+d" (reg1), "+d" (reg2) : : "cc" );
158 return reg1;
159}
160
161/**
Felix Beckcb17a632008-12-25 13:38:41 +0100162 * ap_interrupts_available(): Test if AP interrupts are available.
163 *
164 * Returns 1 if AP interrupts are available.
165 */
166static int ap_interrupts_available(void)
167{
Felix Beck53ec24b12011-01-05 12:46:44 +0100168 return test_facility(2) && test_facility(65);
Felix Beckcb17a632008-12-25 13:38:41 +0100169}
170
171/**
Holger Dengler75014552012-08-28 16:41:50 +0200172 * ap_configuration_available(): Test if AP configuration
173 * information is available.
174 *
175 * Returns 1 if AP configuration information is available.
176 */
Heiko Carstensc80773e2012-09-14 11:21:17 +0200177#ifdef CONFIG_64BIT
Holger Dengler75014552012-08-28 16:41:50 +0200178static int ap_configuration_available(void)
179{
180 return test_facility(2) && test_facility(12);
181}
Heiko Carstensc80773e2012-09-14 11:21:17 +0200182#endif
Holger Dengler75014552012-08-28 16:41:50 +0200183
184/**
Felix Beck1749a812008-04-17 07:46:28 +0200185 * ap_test_queue(): Test adjunct processor queue.
186 * @qid: The AP queue number
187 * @queue_depth: Pointer to queue depth value
188 * @device_type: Pointer to device type value
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200189 *
Felix Beck1749a812008-04-17 07:46:28 +0200190 * Returns AP queue status structure.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200191 */
192static inline struct ap_queue_status
193ap_test_queue(ap_qid_t qid, int *queue_depth, int *device_type)
194{
195 register unsigned long reg0 asm ("0") = qid;
196 register struct ap_queue_status reg1 asm ("1");
197 register unsigned long reg2 asm ("2") = 0UL;
198
199 asm volatile(".long 0xb2af0000" /* PQAP(TAPQ) */
200 : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
201 *device_type = (int) (reg2 >> 24);
202 *queue_depth = (int) (reg2 & 0xff);
203 return reg1;
204}
205
206/**
Ingo Tuchscherer5bc334b2015-01-23 13:27:04 +0100207 * ap_query_facilities(): PQAP(TAPQ) query facilities.
208 * @qid: The AP queue number
209 *
210 * Returns content of general register 2 after the PQAP(TAPQ)
211 * instruction was called.
212 */
213static inline unsigned long ap_query_facilities(ap_qid_t qid)
214{
215 register unsigned long reg0 asm ("0") = qid | 0x00800000UL;
216 register unsigned long reg1 asm ("1");
217 register unsigned long reg2 asm ("2") = 0UL;
218
219 asm volatile(".long 0xb2af0000" /* PQAP(TAPQ) */
220 : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
221 return reg2;
222}
223
224/**
Felix Beck1749a812008-04-17 07:46:28 +0200225 * ap_reset_queue(): Reset adjunct processor queue.
226 * @qid: The AP queue number
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200227 *
Felix Beck1749a812008-04-17 07:46:28 +0200228 * Returns AP queue status structure.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200229 */
230static inline struct ap_queue_status ap_reset_queue(ap_qid_t qid)
231{
232 register unsigned long reg0 asm ("0") = qid | 0x01000000UL;
233 register struct ap_queue_status reg1 asm ("1");
234 register unsigned long reg2 asm ("2") = 0UL;
235
236 asm volatile(
237 ".long 0xb2af0000" /* PQAP(RAPQ) */
238 : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
239 return reg1;
240}
241
Felix Beckcb17a632008-12-25 13:38:41 +0100242#ifdef CONFIG_64BIT
243/**
244 * ap_queue_interruption_control(): Enable interruption for a specific AP.
245 * @qid: The AP queue number
246 * @ind: The notification indicator byte
247 *
248 * Returns AP queue status.
249 */
250static inline struct ap_queue_status
251ap_queue_interruption_control(ap_qid_t qid, void *ind)
252{
253 register unsigned long reg0 asm ("0") = qid | 0x03000000UL;
254 register unsigned long reg1_in asm ("1") = 0x0000800000000000UL | AP_ISC;
255 register struct ap_queue_status reg1_out asm ("1");
256 register void *reg2 asm ("2") = ind;
257 asm volatile(
Holger Denglera7475af2012-05-16 14:10:26 +0200258 ".long 0xb2af0000" /* PQAP(AQIC) */
Felix Beckcb17a632008-12-25 13:38:41 +0100259 : "+d" (reg0), "+d" (reg1_in), "=d" (reg1_out), "+d" (reg2)
260 :
261 : "cc" );
262 return reg1_out;
263}
264#endif
265
Holger Dengler6bed05b2011-07-24 10:48:25 +0200266#ifdef CONFIG_64BIT
267static inline struct ap_queue_status
268__ap_query_functions(ap_qid_t qid, unsigned int *functions)
Felix Beckb1f933d2011-01-05 12:47:44 +0100269{
270 register unsigned long reg0 asm ("0") = 0UL | qid | (1UL << 23);
Holger Dengler6bed05b2011-07-24 10:48:25 +0200271 register struct ap_queue_status reg1 asm ("1") = AP_QUEUE_STATUS_INVALID;
272 register unsigned long reg2 asm ("2");
Felix Beckb1f933d2011-01-05 12:47:44 +0100273
274 asm volatile(
Holger Denglera7475af2012-05-16 14:10:26 +0200275 ".long 0xb2af0000\n" /* PQAP(TAPQ) */
Holger Dengler6bed05b2011-07-24 10:48:25 +0200276 "0:\n"
277 EX_TABLE(0b, 0b)
278 : "+d" (reg0), "+d" (reg1), "=d" (reg2)
Felix Beckb1f933d2011-01-05 12:47:44 +0100279 :
280 : "cc");
281
Holger Dengler6bed05b2011-07-24 10:48:25 +0200282 *functions = (unsigned int)(reg2 >> 32);
Felix Beckb1f933d2011-01-05 12:47:44 +0100283 return reg1;
284}
Holger Dengler6bed05b2011-07-24 10:48:25 +0200285#endif
286
Holger Dengler75014552012-08-28 16:41:50 +0200287#ifdef CONFIG_64BIT
288static inline int __ap_query_configuration(struct ap_config_info *config)
289{
290 register unsigned long reg0 asm ("0") = 0x04000000UL;
291 register unsigned long reg1 asm ("1") = -EINVAL;
292 register unsigned char *reg2 asm ("2") = (unsigned char *)config;
293
294 asm volatile(
295 ".long 0xb2af0000\n" /* PQAP(QCI) */
296 "0: la %1,0\n"
297 "1:\n"
298 EX_TABLE(0b, 1b)
299 : "+d" (reg0), "+d" (reg1), "+d" (reg2)
300 :
301 : "cc");
302
303 return reg1;
304}
305#endif
306
Holger Dengler6bed05b2011-07-24 10:48:25 +0200307/**
308 * ap_query_functions(): Query supported functions.
309 * @qid: The AP queue number
310 * @functions: Pointer to functions field.
311 *
312 * Returns
313 * 0 on success.
314 * -ENODEV if queue not valid.
315 * -EBUSY if device busy.
316 * -EINVAL if query function is not supported
317 */
318static int ap_query_functions(ap_qid_t qid, unsigned int *functions)
319{
320#ifdef CONFIG_64BIT
321 struct ap_queue_status status;
322 int i;
323 status = __ap_query_functions(qid, functions);
324
325 for (i = 0; i < AP_MAX_RESET; i++) {
326 if (ap_queue_status_invalid_test(&status))
327 return -ENODEV;
328
329 switch (status.response_code) {
330 case AP_RESPONSE_NORMAL:
331 return 0;
332 case AP_RESPONSE_RESET_IN_PROGRESS:
333 case AP_RESPONSE_BUSY:
334 break;
335 case AP_RESPONSE_Q_NOT_AVAIL:
336 case AP_RESPONSE_DECONFIGURED:
337 case AP_RESPONSE_CHECKSTOPPED:
338 case AP_RESPONSE_INVALID_ADDRESS:
339 return -ENODEV;
340 case AP_RESPONSE_OTHERWISE_CHANGED:
341 break;
342 default:
343 break;
344 }
345 if (i < AP_MAX_RESET - 1) {
346 udelay(5);
347 status = __ap_query_functions(qid, functions);
348 }
349 }
350 return -EBUSY;
351#else
352 return -EINVAL;
353#endif
354}
Felix Beckb1f933d2011-01-05 12:47:44 +0100355
356/**
Felix Beckcb17a632008-12-25 13:38:41 +0100357 * ap_queue_enable_interruption(): Enable interruption on an AP.
358 * @qid: The AP queue number
359 * @ind: the notification indicator byte
360 *
361 * Enables interruption on AP queue via ap_queue_interruption_control(). Based
362 * on the return value it waits a while and tests the AP queue if interrupts
363 * have been switched on using ap_test_queue().
364 */
365static int ap_queue_enable_interruption(ap_qid_t qid, void *ind)
366{
367#ifdef CONFIG_64BIT
368 struct ap_queue_status status;
369 int t_depth, t_device_type, rc, i;
370
371 rc = -EBUSY;
372 status = ap_queue_interruption_control(qid, ind);
373
374 for (i = 0; i < AP_MAX_RESET; i++) {
375 switch (status.response_code) {
376 case AP_RESPONSE_NORMAL:
377 if (status.int_enabled)
378 return 0;
379 break;
380 case AP_RESPONSE_RESET_IN_PROGRESS:
381 case AP_RESPONSE_BUSY:
Holger Dengler8738e072012-07-02 12:39:59 +0200382 if (i < AP_MAX_RESET - 1) {
383 udelay(5);
384 status = ap_queue_interruption_control(qid,
385 ind);
386 continue;
387 }
Felix Beckcb17a632008-12-25 13:38:41 +0100388 break;
389 case AP_RESPONSE_Q_NOT_AVAIL:
390 case AP_RESPONSE_DECONFIGURED:
391 case AP_RESPONSE_CHECKSTOPPED:
392 case AP_RESPONSE_INVALID_ADDRESS:
393 return -ENODEV;
394 case AP_RESPONSE_OTHERWISE_CHANGED:
395 if (status.int_enabled)
396 return 0;
397 break;
398 default:
399 break;
400 }
401 if (i < AP_MAX_RESET - 1) {
402 udelay(5);
403 status = ap_test_queue(qid, &t_depth, &t_device_type);
404 }
405 }
406 return rc;
407#else
408 return -EINVAL;
409#endif
410}
411
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200412/**
Felix Beck1749a812008-04-17 07:46:28 +0200413 * __ap_send(): Send message to adjunct processor queue.
414 * @qid: The AP queue number
415 * @psmid: The program supplied message identifier
416 * @msg: The message text
417 * @length: The message length
Felix Becka6a5d732009-12-07 12:51:55 +0100418 * @special: Special Bit
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200419 *
Felix Beck1749a812008-04-17 07:46:28 +0200420 * Returns AP queue status structure.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200421 * Condition code 1 on NQAP can't happen because the L bit is 1.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200422 * Condition code 2 on NQAP also means the send is incomplete,
423 * because a segment boundary was reached. The NQAP is repeated.
424 */
425static inline struct ap_queue_status
Felix Becka6a5d732009-12-07 12:51:55 +0100426__ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length,
427 unsigned int special)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200428{
429 typedef struct { char _[length]; } msgblock;
430 register unsigned long reg0 asm ("0") = qid | 0x40000000UL;
431 register struct ap_queue_status reg1 asm ("1");
432 register unsigned long reg2 asm ("2") = (unsigned long) msg;
433 register unsigned long reg3 asm ("3") = (unsigned long) length;
434 register unsigned long reg4 asm ("4") = (unsigned int) (psmid >> 32);
Heiko Carstens7d6c3b42013-09-07 11:07:22 +0200435 register unsigned long reg5 asm ("5") = psmid & 0xffffffff;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200436
Felix Becka6a5d732009-12-07 12:51:55 +0100437 if (special == 1)
438 reg0 |= 0x400000UL;
439
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200440 asm volatile (
Holger Denglera7475af2012-05-16 14:10:26 +0200441 "0: .long 0xb2ad0042\n" /* NQAP */
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200442 " brc 2,0b"
443 : "+d" (reg0), "=d" (reg1), "+d" (reg2), "+d" (reg3)
444 : "d" (reg4), "d" (reg5), "m" (*(msgblock *) msg)
445 : "cc" );
446 return reg1;
447}
448
449int ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length)
450{
451 struct ap_queue_status status;
452
Felix Becka6a5d732009-12-07 12:51:55 +0100453 status = __ap_send(qid, psmid, msg, length, 0);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200454 switch (status.response_code) {
455 case AP_RESPONSE_NORMAL:
456 return 0;
457 case AP_RESPONSE_Q_FULL:
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200458 case AP_RESPONSE_RESET_IN_PROGRESS:
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200459 return -EBUSY;
Felix Becka6a5d732009-12-07 12:51:55 +0100460 case AP_RESPONSE_REQ_FAC_NOT_INST:
461 return -EINVAL;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200462 default: /* Device is gone. */
463 return -ENODEV;
464 }
465}
466EXPORT_SYMBOL(ap_send);
467
Felix Beck1749a812008-04-17 07:46:28 +0200468/**
469 * __ap_recv(): Receive message from adjunct processor queue.
470 * @qid: The AP queue number
471 * @psmid: Pointer to program supplied message identifier
472 * @msg: The message text
473 * @length: The message length
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200474 *
Felix Beck1749a812008-04-17 07:46:28 +0200475 * Returns AP queue status structure.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200476 * Condition code 1 on DQAP means the receive has taken place
477 * but only partially. The response is incomplete, hence the
478 * DQAP is repeated.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200479 * Condition code 2 on DQAP also means the receive is incomplete,
480 * this time because a segment boundary was reached. Again, the
481 * DQAP is repeated.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200482 * Note that gpr2 is used by the DQAP instruction to keep track of
483 * any 'residual' length, in case the instruction gets interrupted.
484 * Hence it gets zeroed before the instruction.
485 */
486static inline struct ap_queue_status
487__ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length)
488{
489 typedef struct { char _[length]; } msgblock;
490 register unsigned long reg0 asm("0") = qid | 0x80000000UL;
491 register struct ap_queue_status reg1 asm ("1");
492 register unsigned long reg2 asm("2") = 0UL;
493 register unsigned long reg4 asm("4") = (unsigned long) msg;
494 register unsigned long reg5 asm("5") = (unsigned long) length;
495 register unsigned long reg6 asm("6") = 0UL;
496 register unsigned long reg7 asm("7") = 0UL;
497
498
499 asm volatile(
Holger Denglera7475af2012-05-16 14:10:26 +0200500 "0: .long 0xb2ae0064\n" /* DQAP */
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200501 " brc 6,0b\n"
502 : "+d" (reg0), "=d" (reg1), "+d" (reg2),
503 "+d" (reg4), "+d" (reg5), "+d" (reg6), "+d" (reg7),
504 "=m" (*(msgblock *) msg) : : "cc" );
505 *psmid = (((unsigned long long) reg6) << 32) + reg7;
506 return reg1;
507}
508
509int ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length)
510{
511 struct ap_queue_status status;
512
513 status = __ap_recv(qid, psmid, msg, length);
514 switch (status.response_code) {
515 case AP_RESPONSE_NORMAL:
516 return 0;
517 case AP_RESPONSE_NO_PENDING_REPLY:
518 if (status.queue_empty)
519 return -ENOENT;
520 return -EBUSY;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200521 case AP_RESPONSE_RESET_IN_PROGRESS:
522 return -EBUSY;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200523 default:
524 return -ENODEV;
525 }
526}
527EXPORT_SYMBOL(ap_recv);
528
529/**
Felix Beck1749a812008-04-17 07:46:28 +0200530 * ap_query_queue(): Check if an AP queue is available.
531 * @qid: The AP queue number
532 * @queue_depth: Pointer to queue depth value
533 * @device_type: Pointer to device type value
534 *
535 * The test is repeated for AP_MAX_RESET times.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200536 */
537static int ap_query_queue(ap_qid_t qid, int *queue_depth, int *device_type)
538{
539 struct ap_queue_status status;
540 int t_depth, t_device_type, rc, i;
541
542 rc = -EBUSY;
543 for (i = 0; i < AP_MAX_RESET; i++) {
544 status = ap_test_queue(qid, &t_depth, &t_device_type);
545 switch (status.response_code) {
546 case AP_RESPONSE_NORMAL:
547 *queue_depth = t_depth + 1;
548 *device_type = t_device_type;
549 rc = 0;
550 break;
551 case AP_RESPONSE_Q_NOT_AVAIL:
552 rc = -ENODEV;
553 break;
554 case AP_RESPONSE_RESET_IN_PROGRESS:
555 break;
556 case AP_RESPONSE_DECONFIGURED:
557 rc = -ENODEV;
558 break;
559 case AP_RESPONSE_CHECKSTOPPED:
560 rc = -ENODEV;
561 break;
Felix Beckcb17a632008-12-25 13:38:41 +0100562 case AP_RESPONSE_INVALID_ADDRESS:
563 rc = -ENODEV;
564 break;
565 case AP_RESPONSE_OTHERWISE_CHANGED:
566 break;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200567 case AP_RESPONSE_BUSY:
568 break;
569 default:
570 BUG();
571 }
572 if (rc != -EBUSY)
573 break;
574 if (i < AP_MAX_RESET - 1)
575 udelay(5);
576 }
577 return rc;
578}
579
580/**
Felix Beck1749a812008-04-17 07:46:28 +0200581 * ap_init_queue(): Reset an AP queue.
582 * @qid: The AP queue number
583 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200584 * Reset an AP queue and wait for it to become available again.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200585 */
586static int ap_init_queue(ap_qid_t qid)
587{
588 struct ap_queue_status status;
589 int rc, dummy, i;
590
591 rc = -ENODEV;
592 status = ap_reset_queue(qid);
593 for (i = 0; i < AP_MAX_RESET; i++) {
594 switch (status.response_code) {
595 case AP_RESPONSE_NORMAL:
596 if (status.queue_empty)
597 rc = 0;
598 break;
599 case AP_RESPONSE_Q_NOT_AVAIL:
600 case AP_RESPONSE_DECONFIGURED:
601 case AP_RESPONSE_CHECKSTOPPED:
602 i = AP_MAX_RESET; /* return with -ENODEV */
603 break;
604 case AP_RESPONSE_RESET_IN_PROGRESS:
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200605 rc = -EBUSY;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200606 case AP_RESPONSE_BUSY:
607 default:
608 break;
609 }
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200610 if (rc != -ENODEV && rc != -EBUSY)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200611 break;
612 if (i < AP_MAX_RESET - 1) {
Ingo Tuchscherer91f3e3e2013-11-20 10:47:13 +0100613 /* Time we are waiting until we give up (0.7sec * 90).
614 * Since the actual request (in progress) will not
615 * interrupted immediately for the reset command,
616 * we have to be patient. In worst case we have to
617 * wait 60sec + reset time (some msec).
618 */
619 schedule_timeout(AP_RESET_TIMEOUT);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200620 status = ap_test_queue(qid, &dummy, &dummy);
621 }
622 }
Felix Beckcb17a632008-12-25 13:38:41 +0100623 if (rc == 0 && ap_using_interrupts()) {
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200624 rc = ap_queue_enable_interruption(qid, ap_airq.lsi_ptr);
Felix Beckcb17a632008-12-25 13:38:41 +0100625 /* If interruption mode is supported by the machine,
626 * but an AP can not be enabled for interruption then
627 * the AP will be discarded. */
628 if (rc)
629 pr_err("Registering adapter interrupts for "
630 "AP %d failed\n", AP_QID_DEVICE(qid));
631 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200632 return rc;
633}
634
635/**
Felix Beck1749a812008-04-17 07:46:28 +0200636 * ap_increase_queue_count(): Arm request timeout.
637 * @ap_dev: Pointer to an AP device.
638 *
639 * Arm request timeout if an AP device was idle and a new request is submitted.
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200640 */
641static void ap_increase_queue_count(struct ap_device *ap_dev)
642{
643 int timeout = ap_dev->drv->request_timeout;
644
645 ap_dev->queue_count++;
646 if (ap_dev->queue_count == 1) {
647 mod_timer(&ap_dev->timeout, jiffies + timeout);
648 ap_dev->reset = AP_RESET_ARMED;
649 }
650}
651
652/**
Felix Beck1749a812008-04-17 07:46:28 +0200653 * ap_decrease_queue_count(): Decrease queue count.
654 * @ap_dev: Pointer to an AP device.
655 *
656 * If AP device is still alive, re-schedule request timeout if there are still
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200657 * pending requests.
658 */
659static void ap_decrease_queue_count(struct ap_device *ap_dev)
660{
661 int timeout = ap_dev->drv->request_timeout;
662
663 ap_dev->queue_count--;
664 if (ap_dev->queue_count > 0)
665 mod_timer(&ap_dev->timeout, jiffies + timeout);
666 else
Felix Beck1749a812008-04-17 07:46:28 +0200667 /*
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200668 * The timeout timer should to be disabled now - since
669 * del_timer_sync() is very expensive, we just tell via the
670 * reset flag to ignore the pending timeout timer.
671 */
672 ap_dev->reset = AP_RESET_IGNORE;
673}
674
Felix Beck1749a812008-04-17 07:46:28 +0200675/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200676 * AP device related attributes.
677 */
678static ssize_t ap_hwtype_show(struct device *dev,
679 struct device_attribute *attr, char *buf)
680{
681 struct ap_device *ap_dev = to_ap_dev(dev);
682 return snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->device_type);
683}
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200684
Christian Maaser43c207e62008-12-25 13:38:42 +0100685static DEVICE_ATTR(hwtype, 0444, ap_hwtype_show, NULL);
Ingo Tuchscherer42f4dd612014-10-02 14:48:46 +0200686
687static ssize_t ap_raw_hwtype_show(struct device *dev,
688 struct device_attribute *attr, char *buf)
689{
690 struct ap_device *ap_dev = to_ap_dev(dev);
691
692 return snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->raw_hwtype);
693}
694
695static DEVICE_ATTR(raw_hwtype, 0444, ap_raw_hwtype_show, NULL);
696
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200697static ssize_t ap_depth_show(struct device *dev, struct device_attribute *attr,
698 char *buf)
699{
700 struct ap_device *ap_dev = to_ap_dev(dev);
701 return snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->queue_depth);
702}
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200703
Christian Maaser43c207e62008-12-25 13:38:42 +0100704static DEVICE_ATTR(depth, 0444, ap_depth_show, NULL);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200705static ssize_t ap_request_count_show(struct device *dev,
706 struct device_attribute *attr,
707 char *buf)
708{
709 struct ap_device *ap_dev = to_ap_dev(dev);
710 int rc;
711
712 spin_lock_bh(&ap_dev->lock);
713 rc = snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->total_request_count);
714 spin_unlock_bh(&ap_dev->lock);
715 return rc;
716}
717
718static DEVICE_ATTR(request_count, 0444, ap_request_count_show, NULL);
719
Holger Denglerb26bd942012-08-28 16:43:48 +0200720static ssize_t ap_requestq_count_show(struct device *dev,
721 struct device_attribute *attr, char *buf)
722{
723 struct ap_device *ap_dev = to_ap_dev(dev);
724 int rc;
725
726 spin_lock_bh(&ap_dev->lock);
727 rc = snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->requestq_count);
728 spin_unlock_bh(&ap_dev->lock);
729 return rc;
730}
731
732static DEVICE_ATTR(requestq_count, 0444, ap_requestq_count_show, NULL);
733
734static ssize_t ap_pendingq_count_show(struct device *dev,
735 struct device_attribute *attr, char *buf)
736{
737 struct ap_device *ap_dev = to_ap_dev(dev);
738 int rc;
739
740 spin_lock_bh(&ap_dev->lock);
741 rc = snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->pendingq_count);
742 spin_unlock_bh(&ap_dev->lock);
743 return rc;
744}
745
746static DEVICE_ATTR(pendingq_count, 0444, ap_pendingq_count_show, NULL);
747
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200748static ssize_t ap_modalias_show(struct device *dev,
749 struct device_attribute *attr, char *buf)
750{
751 return sprintf(buf, "ap:t%02X", to_ap_dev(dev)->device_type);
752}
753
754static DEVICE_ATTR(modalias, 0444, ap_modalias_show, NULL);
755
Holger Denglerb26bd942012-08-28 16:43:48 +0200756static ssize_t ap_functions_show(struct device *dev,
757 struct device_attribute *attr, char *buf)
758{
759 struct ap_device *ap_dev = to_ap_dev(dev);
760 return snprintf(buf, PAGE_SIZE, "0x%08X\n", ap_dev->functions);
761}
762
763static DEVICE_ATTR(ap_functions, 0444, ap_functions_show, NULL);
764
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200765static struct attribute *ap_dev_attrs[] = {
766 &dev_attr_hwtype.attr,
Ingo Tuchscherer42f4dd612014-10-02 14:48:46 +0200767 &dev_attr_raw_hwtype.attr,
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200768 &dev_attr_depth.attr,
769 &dev_attr_request_count.attr,
Holger Denglerb26bd942012-08-28 16:43:48 +0200770 &dev_attr_requestq_count.attr,
771 &dev_attr_pendingq_count.attr,
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200772 &dev_attr_modalias.attr,
Holger Denglerb26bd942012-08-28 16:43:48 +0200773 &dev_attr_ap_functions.attr,
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200774 NULL
775};
776static struct attribute_group ap_dev_attr_group = {
777 .attrs = ap_dev_attrs
778};
779
780/**
Felix Beck1749a812008-04-17 07:46:28 +0200781 * ap_bus_match()
782 * @dev: Pointer to device
783 * @drv: Pointer to device_driver
784 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200785 * AP bus driver registration/unregistration.
786 */
787static int ap_bus_match(struct device *dev, struct device_driver *drv)
788{
789 struct ap_device *ap_dev = to_ap_dev(dev);
790 struct ap_driver *ap_drv = to_ap_drv(drv);
791 struct ap_device_id *id;
792
Felix Beck1749a812008-04-17 07:46:28 +0200793 /*
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200794 * Compare device type of the device with the list of
795 * supported types of the device_driver.
796 */
797 for (id = ap_drv->ids; id->match_flags; id++) {
798 if ((id->match_flags & AP_DEVICE_ID_MATCH_DEVICE_TYPE) &&
799 (id->dev_type != ap_dev->device_type))
800 continue;
801 return 1;
802 }
803 return 0;
804}
805
806/**
Felix Beck1749a812008-04-17 07:46:28 +0200807 * ap_uevent(): Uevent function for AP devices.
808 * @dev: Pointer to device
809 * @env: Pointer to kobj_uevent_env
810 *
811 * It sets up a single environment variable DEV_TYPE which contains the
812 * hardware device type.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200813 */
Kay Sievers7eff2e72007-08-14 15:15:12 +0200814static int ap_uevent (struct device *dev, struct kobj_uevent_env *env)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200815{
816 struct ap_device *ap_dev = to_ap_dev(dev);
Kay Sievers7eff2e72007-08-14 15:15:12 +0200817 int retval = 0;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200818
819 if (!ap_dev)
820 return -ENODEV;
821
822 /* Set up DEV_TYPE environment variable. */
Kay Sievers7eff2e72007-08-14 15:15:12 +0200823 retval = add_uevent_var(env, "DEV_TYPE=%04X", ap_dev->device_type);
Eric Rannaudbf624562007-03-30 22:23:12 -0700824 if (retval)
825 return retval;
826
Cornelia Huck66a4263b2006-12-04 15:40:10 +0100827 /* Add MODALIAS= */
Kay Sievers7eff2e72007-08-14 15:15:12 +0200828 retval = add_uevent_var(env, "MODALIAS=ap:t%02X", ap_dev->device_type);
Eric Rannaudbf624562007-03-30 22:23:12 -0700829
Eric Rannaudbf624562007-03-30 22:23:12 -0700830 return retval;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200831}
832
Felix Beck772f5472009-06-22 12:08:16 +0200833static int ap_bus_suspend(struct device *dev, pm_message_t state)
834{
835 struct ap_device *ap_dev = to_ap_dev(dev);
836 unsigned long flags;
837
838 if (!ap_suspend_flag) {
839 ap_suspend_flag = 1;
840
841 /* Disable scanning for devices, thus we do not want to scan
842 * for them after removing.
843 */
844 del_timer_sync(&ap_config_timer);
845 if (ap_work_queue != NULL) {
846 destroy_workqueue(ap_work_queue);
847 ap_work_queue = NULL;
848 }
Felix Beck5314af62009-09-22 22:58:51 +0200849
Felix Beck772f5472009-06-22 12:08:16 +0200850 tasklet_disable(&ap_tasklet);
851 }
852 /* Poll on the device until all requests are finished. */
853 do {
854 flags = 0;
Felix Beck95f15562009-09-11 10:28:51 +0200855 spin_lock_bh(&ap_dev->lock);
Felix Beck772f5472009-06-22 12:08:16 +0200856 __ap_poll_device(ap_dev, &flags);
Felix Beck95f15562009-09-11 10:28:51 +0200857 spin_unlock_bh(&ap_dev->lock);
Felix Beck772f5472009-06-22 12:08:16 +0200858 } while ((flags & 1) || (flags & 2));
859
Felix Beck5314af62009-09-22 22:58:51 +0200860 spin_lock_bh(&ap_dev->lock);
861 ap_dev->unregistered = 1;
862 spin_unlock_bh(&ap_dev->lock);
863
Felix Beck772f5472009-06-22 12:08:16 +0200864 return 0;
865}
866
867static int ap_bus_resume(struct device *dev)
868{
Felix Beck772f5472009-06-22 12:08:16 +0200869 struct ap_device *ap_dev = to_ap_dev(dev);
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200870 int rc;
Felix Beck772f5472009-06-22 12:08:16 +0200871
872 if (ap_suspend_flag) {
873 ap_suspend_flag = 0;
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200874 if (ap_interrupts_available()) {
875 if (!ap_using_interrupts()) {
876 rc = register_adapter_interrupt(&ap_airq);
877 ap_airq_flag = (rc == 0);
878 }
879 } else {
880 if (ap_using_interrupts()) {
881 unregister_adapter_interrupt(&ap_airq);
882 ap_airq_flag = 0;
883 }
884 }
Holger Dengler75014552012-08-28 16:41:50 +0200885 ap_query_configuration();
Felix Beck5314af62009-09-22 22:58:51 +0200886 if (!user_set_domain) {
887 ap_domain_index = -1;
888 ap_select_domain();
889 }
Felix Beck772f5472009-06-22 12:08:16 +0200890 init_timer(&ap_config_timer);
891 ap_config_timer.function = ap_config_timeout;
892 ap_config_timer.data = 0;
893 ap_config_timer.expires = jiffies + ap_config_time * HZ;
894 add_timer(&ap_config_timer);
895 ap_work_queue = create_singlethread_workqueue("kapwork");
896 if (!ap_work_queue)
897 return -ENOMEM;
898 tasklet_enable(&ap_tasklet);
899 if (!ap_using_interrupts())
900 ap_schedule_poll_timer();
901 else
902 tasklet_schedule(&ap_tasklet);
903 if (ap_thread_flag)
904 rc = ap_poll_thread_start();
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200905 else
906 rc = 0;
907 } else
908 rc = 0;
Felix Beck5314af62009-09-22 22:58:51 +0200909 if (AP_QID_QUEUE(ap_dev->qid) != ap_domain_index) {
910 spin_lock_bh(&ap_dev->lock);
911 ap_dev->qid = AP_MKQID(AP_QID_DEVICE(ap_dev->qid),
912 ap_domain_index);
913 spin_unlock_bh(&ap_dev->lock);
914 }
915 queue_work(ap_work_queue, &ap_config_work);
Felix Beck772f5472009-06-22 12:08:16 +0200916
917 return rc;
918}
919
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200920static struct bus_type ap_bus_type = {
921 .name = "ap",
922 .match = &ap_bus_match,
923 .uevent = &ap_uevent,
Felix Beck772f5472009-06-22 12:08:16 +0200924 .suspend = ap_bus_suspend,
925 .resume = ap_bus_resume
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200926};
927
928static int ap_device_probe(struct device *dev)
929{
930 struct ap_device *ap_dev = to_ap_dev(dev);
931 struct ap_driver *ap_drv = to_ap_drv(dev->driver);
932 int rc;
933
934 ap_dev->drv = ap_drv;
Ingo Tuchscherer666e68e2014-07-14 19:11:48 +0200935
936 spin_lock_bh(&ap_device_list_lock);
937 list_add(&ap_dev->list, &ap_device_list);
938 spin_unlock_bh(&ap_device_list_lock);
939
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200940 rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV;
Ingo Tuchscherer666e68e2014-07-14 19:11:48 +0200941 if (rc) {
Christian Maaser43c207e62008-12-25 13:38:42 +0100942 spin_lock_bh(&ap_device_list_lock);
Ingo Tuchscherer666e68e2014-07-14 19:11:48 +0200943 list_del_init(&ap_dev->list);
Christian Maaser43c207e62008-12-25 13:38:42 +0100944 spin_unlock_bh(&ap_device_list_lock);
Ralph Wuerthnerfaa582c2008-03-05 12:37:13 +0100945 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200946 return rc;
947}
948
949/**
Felix Beck1749a812008-04-17 07:46:28 +0200950 * __ap_flush_queue(): Flush requests.
951 * @ap_dev: Pointer to the AP device
952 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200953 * Flush all requests from the request/pending queue of an AP device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200954 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +0100955static void __ap_flush_queue(struct ap_device *ap_dev)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200956{
957 struct ap_message *ap_msg, *next;
958
959 list_for_each_entry_safe(ap_msg, next, &ap_dev->pendingq, list) {
960 list_del_init(&ap_msg->list);
961 ap_dev->pendingq_count--;
Holger Dengler54a8f562012-05-16 14:08:22 +0200962 ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200963 }
964 list_for_each_entry_safe(ap_msg, next, &ap_dev->requestq, list) {
965 list_del_init(&ap_msg->list);
966 ap_dev->requestq_count--;
Holger Dengler54a8f562012-05-16 14:08:22 +0200967 ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200968 }
969}
970
971void ap_flush_queue(struct ap_device *ap_dev)
972{
973 spin_lock_bh(&ap_dev->lock);
974 __ap_flush_queue(ap_dev);
975 spin_unlock_bh(&ap_dev->lock);
976}
977EXPORT_SYMBOL(ap_flush_queue);
978
979static int ap_device_remove(struct device *dev)
980{
981 struct ap_device *ap_dev = to_ap_dev(dev);
982 struct ap_driver *ap_drv = ap_dev->drv;
983
Ralph Wuerthner4e562962006-10-04 20:02:05 +0200984 ap_flush_queue(ap_dev);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200985 del_timer_sync(&ap_dev->timeout);
Christian Maaser43c207e62008-12-25 13:38:42 +0100986 spin_lock_bh(&ap_device_list_lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +0100987 list_del_init(&ap_dev->list);
Christian Maaser43c207e62008-12-25 13:38:42 +0100988 spin_unlock_bh(&ap_device_list_lock);
Ralph Wuerthnerfaa582c2008-03-05 12:37:13 +0100989 if (ap_drv->remove)
990 ap_drv->remove(ap_dev);
Ralph Wuerthnere675c0d2007-03-26 20:42:43 +0200991 spin_lock_bh(&ap_dev->lock);
992 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
993 spin_unlock_bh(&ap_dev->lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200994 return 0;
995}
996
997int ap_driver_register(struct ap_driver *ap_drv, struct module *owner,
998 char *name)
999{
1000 struct device_driver *drv = &ap_drv->driver;
1001
1002 drv->bus = &ap_bus_type;
1003 drv->probe = ap_device_probe;
1004 drv->remove = ap_device_remove;
1005 drv->owner = owner;
1006 drv->name = name;
1007 return driver_register(drv);
1008}
1009EXPORT_SYMBOL(ap_driver_register);
1010
1011void ap_driver_unregister(struct ap_driver *ap_drv)
1012{
1013 driver_unregister(&ap_drv->driver);
1014}
1015EXPORT_SYMBOL(ap_driver_unregister);
1016
Holger Denglerdabecb22012-09-10 21:34:26 +02001017void ap_bus_force_rescan(void)
1018{
Ingo Tuchscherer56bbe682013-04-12 17:52:08 +02001019 /* reconfigure the AP bus rescan timer. */
1020 mod_timer(&ap_config_timer, jiffies + ap_config_time * HZ);
1021 /* processing a asynchronous bus rescan */
1022 queue_work(ap_work_queue, &ap_config_work);
1023 flush_work(&ap_config_work);
Holger Denglerdabecb22012-09-10 21:34:26 +02001024}
1025EXPORT_SYMBOL(ap_bus_force_rescan);
1026
Felix Beck1749a812008-04-17 07:46:28 +02001027/*
Ingo Tuchscherer5bc334b2015-01-23 13:27:04 +01001028 * ap_test_config(): helper function to extract the nrth bit
1029 * within the unsigned int array field.
1030 */
1031static inline int ap_test_config(unsigned int *field, unsigned int nr)
1032{
1033 if (nr > 0xFFu)
1034 return 0;
1035 return ap_test_bit((field + (nr >> 5)), (nr & 0x1f));
1036}
1037
1038/*
1039 * ap_test_config_card_id(): Test, whether an AP card ID is configured.
1040 * @id AP card ID
1041 *
1042 * Returns 0 if the card is not configured
1043 * 1 if the card is configured or
1044 * if the configuration information is not available
1045 */
1046static inline int ap_test_config_card_id(unsigned int id)
1047{
1048 if (!ap_configuration)
1049 return 1;
1050 return ap_test_config(ap_configuration->apm, id);
1051}
1052
1053/*
1054 * ap_test_config_domain(): Test, whether an AP usage domain is configured.
1055 * @domain AP usage domain ID
1056 *
1057 * Returns 0 if the usage domain is not configured
1058 * 1 if the usage domain is configured or
1059 * if the configuration information is not available
1060 */
1061static inline int ap_test_config_domain(unsigned int domain)
1062{
Ingo Tuchschererea96f782015-02-02 17:50:17 +01001063 if (!ap_configuration) /* QCI not supported */
1064 if (domain < 16)
1065 return 1; /* then domains 0...15 are configured */
1066 else
1067 return 0;
1068 else
1069 return ap_test_config(ap_configuration->aqm, domain);
Ingo Tuchscherer5bc334b2015-01-23 13:27:04 +01001070}
1071
1072/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001073 * AP bus attributes.
1074 */
1075static ssize_t ap_domain_show(struct bus_type *bus, char *buf)
1076{
1077 return snprintf(buf, PAGE_SIZE, "%d\n", ap_domain_index);
1078}
1079
1080static BUS_ATTR(ap_domain, 0444, ap_domain_show, NULL);
1081
Ingo Tuchscherer91f3e3e2013-11-20 10:47:13 +01001082static ssize_t ap_control_domain_mask_show(struct bus_type *bus, char *buf)
1083{
1084 if (ap_configuration != NULL) { /* QCI not supported */
1085 if (test_facility(76)) { /* format 1 - 256 bit domain field */
1086 return snprintf(buf, PAGE_SIZE,
1087 "0x%08x%08x%08x%08x%08x%08x%08x%08x\n",
1088 ap_configuration->adm[0], ap_configuration->adm[1],
1089 ap_configuration->adm[2], ap_configuration->adm[3],
1090 ap_configuration->adm[4], ap_configuration->adm[5],
1091 ap_configuration->adm[6], ap_configuration->adm[7]);
1092 } else { /* format 0 - 16 bit domain field */
1093 return snprintf(buf, PAGE_SIZE, "%08x%08x\n",
1094 ap_configuration->adm[0], ap_configuration->adm[1]);
1095 }
1096 } else {
1097 return snprintf(buf, PAGE_SIZE, "not supported\n");
1098 }
1099}
1100
1101static BUS_ATTR(ap_control_domain_mask, 0444,
1102 ap_control_domain_mask_show, NULL);
1103
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001104static ssize_t ap_config_time_show(struct bus_type *bus, char *buf)
1105{
1106 return snprintf(buf, PAGE_SIZE, "%d\n", ap_config_time);
1107}
1108
Felix Beckcb17a632008-12-25 13:38:41 +01001109static ssize_t ap_interrupts_show(struct bus_type *bus, char *buf)
1110{
1111 return snprintf(buf, PAGE_SIZE, "%d\n",
1112 ap_using_interrupts() ? 1 : 0);
1113}
1114
1115static BUS_ATTR(ap_interrupts, 0444, ap_interrupts_show, NULL);
1116
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001117static ssize_t ap_config_time_store(struct bus_type *bus,
1118 const char *buf, size_t count)
1119{
1120 int time;
1121
1122 if (sscanf(buf, "%d\n", &time) != 1 || time < 5 || time > 120)
1123 return -EINVAL;
1124 ap_config_time = time;
1125 if (!timer_pending(&ap_config_timer) ||
1126 !mod_timer(&ap_config_timer, jiffies + ap_config_time * HZ)) {
1127 ap_config_timer.expires = jiffies + ap_config_time * HZ;
1128 add_timer(&ap_config_timer);
1129 }
1130 return count;
1131}
1132
1133static BUS_ATTR(config_time, 0644, ap_config_time_show, ap_config_time_store);
1134
1135static ssize_t ap_poll_thread_show(struct bus_type *bus, char *buf)
1136{
1137 return snprintf(buf, PAGE_SIZE, "%d\n", ap_poll_kthread ? 1 : 0);
1138}
1139
1140static ssize_t ap_poll_thread_store(struct bus_type *bus,
1141 const char *buf, size_t count)
1142{
1143 int flag, rc;
1144
1145 if (sscanf(buf, "%d\n", &flag) != 1)
1146 return -EINVAL;
1147 if (flag) {
1148 rc = ap_poll_thread_start();
1149 if (rc)
1150 return rc;
1151 }
1152 else
1153 ap_poll_thread_stop();
1154 return count;
1155}
1156
1157static BUS_ATTR(poll_thread, 0644, ap_poll_thread_show, ap_poll_thread_store);
1158
Felix Beckfe137232008-07-14 09:59:08 +02001159static ssize_t poll_timeout_show(struct bus_type *bus, char *buf)
1160{
1161 return snprintf(buf, PAGE_SIZE, "%llu\n", poll_timeout);
1162}
1163
1164static ssize_t poll_timeout_store(struct bus_type *bus, const char *buf,
1165 size_t count)
1166{
1167 unsigned long long time;
1168 ktime_t hr_time;
1169
1170 /* 120 seconds = maximum poll interval */
Felix Beckcb17a632008-12-25 13:38:41 +01001171 if (sscanf(buf, "%llu\n", &time) != 1 || time < 1 ||
1172 time > 120000000000ULL)
Felix Beckfe137232008-07-14 09:59:08 +02001173 return -EINVAL;
1174 poll_timeout = time;
1175 hr_time = ktime_set(0, poll_timeout);
1176
1177 if (!hrtimer_is_queued(&ap_poll_timer) ||
Arjan van de Ven6c644ea2008-09-01 15:20:30 -07001178 !hrtimer_forward(&ap_poll_timer, hrtimer_get_expires(&ap_poll_timer), hr_time)) {
1179 hrtimer_set_expires(&ap_poll_timer, hr_time);
1180 hrtimer_start_expires(&ap_poll_timer, HRTIMER_MODE_ABS);
Felix Beckfe137232008-07-14 09:59:08 +02001181 }
1182 return count;
1183}
1184
1185static BUS_ATTR(poll_timeout, 0644, poll_timeout_show, poll_timeout_store);
1186
Ingo Tuchscherer5bc334b2015-01-23 13:27:04 +01001187static ssize_t ap_max_domain_id_show(struct bus_type *bus, char *buf)
1188{
1189 ap_qid_t qid;
1190 int i, nd, max_domain_id = -1;
1191 unsigned long fbits;
1192
1193 if (ap_configuration) {
1194 if (ap_domain_index >= 0 && ap_domain_index < AP_DOMAINS) {
1195 for (i = 0; i < AP_DEVICES; i++) {
1196 if (!ap_test_config_card_id(i))
1197 continue;
1198 qid = AP_MKQID(i, ap_domain_index);
1199 fbits = ap_query_facilities(qid);
1200 if (fbits & (1UL << 57)) {
1201 /* the N bit is 0, Nd field is filled */
1202 nd = (int)((fbits & 0x00FF0000UL)>>16);
1203 if (nd > 0)
1204 max_domain_id = nd;
1205 else
1206 max_domain_id = 15;
1207 } else {
1208 /* N bit is 1, max 16 domains */
1209 max_domain_id = 15;
1210 }
1211 break;
1212 }
1213 }
1214 } else {
1215 /* no APXA support, older machines with max 16 domains */
1216 max_domain_id = 15;
1217 }
1218 return snprintf(buf, PAGE_SIZE, "%d\n", max_domain_id);
1219}
1220
1221static BUS_ATTR(ap_max_domain_id, 0444, ap_max_domain_id_show, NULL);
1222
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001223static struct bus_attribute *const ap_bus_attrs[] = {
1224 &bus_attr_ap_domain,
Ingo Tuchscherer91f3e3e2013-11-20 10:47:13 +01001225 &bus_attr_ap_control_domain_mask,
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001226 &bus_attr_config_time,
1227 &bus_attr_poll_thread,
Felix Beckcb17a632008-12-25 13:38:41 +01001228 &bus_attr_ap_interrupts,
Felix Beckfe137232008-07-14 09:59:08 +02001229 &bus_attr_poll_timeout,
Ingo Tuchscherer5bc334b2015-01-23 13:27:04 +01001230 &bus_attr_ap_max_domain_id,
Felix Beckfe137232008-07-14 09:59:08 +02001231 NULL,
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001232};
1233
Holger Dengler75014552012-08-28 16:41:50 +02001234/**
1235 * ap_query_configuration(): Query AP configuration information.
1236 *
1237 * Query information of installed cards and configured domains from AP.
1238 */
1239static void ap_query_configuration(void)
1240{
1241#ifdef CONFIG_64BIT
1242 if (ap_configuration_available()) {
1243 if (!ap_configuration)
1244 ap_configuration =
1245 kzalloc(sizeof(struct ap_config_info),
1246 GFP_KERNEL);
1247 if (ap_configuration)
1248 __ap_query_configuration(ap_configuration);
1249 } else
1250 ap_configuration = NULL;
1251#else
1252 ap_configuration = NULL;
1253#endif
1254}
1255
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001256/**
Felix Beck1749a812008-04-17 07:46:28 +02001257 * ap_select_domain(): Select an AP domain.
1258 *
1259 * Pick one of the 16 AP domains.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001260 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +01001261static int ap_select_domain(void)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001262{
1263 int queue_depth, device_type, count, max_count, best_domain;
Holger Dengler75014552012-08-28 16:41:50 +02001264 ap_qid_t qid;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001265 int rc, i, j;
1266
Ingo Tuchscherer170387a2014-09-08 13:24:13 +02001267 /* IF APXA isn't installed, only 16 domains could be defined */
1268 if (!ap_configuration->ap_extended && (ap_domain_index > 15))
1269 return -EINVAL;
1270
Felix Beck1749a812008-04-17 07:46:28 +02001271 /*
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001272 * We want to use a single domain. Either the one specified with
1273 * the "domain=" parameter or the domain with the maximum number
1274 * of devices.
1275 */
1276 if (ap_domain_index >= 0 && ap_domain_index < AP_DOMAINS)
1277 /* Domain has already been selected. */
1278 return 0;
1279 best_domain = -1;
1280 max_count = 0;
1281 for (i = 0; i < AP_DOMAINS; i++) {
Holger Dengler75014552012-08-28 16:41:50 +02001282 if (!ap_test_config_domain(i))
1283 continue;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001284 count = 0;
1285 for (j = 0; j < AP_DEVICES; j++) {
Holger Dengler75014552012-08-28 16:41:50 +02001286 if (!ap_test_config_card_id(j))
1287 continue;
1288 qid = AP_MKQID(j, i);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001289 rc = ap_query_queue(qid, &queue_depth, &device_type);
1290 if (rc)
1291 continue;
1292 count++;
1293 }
1294 if (count > max_count) {
1295 max_count = count;
1296 best_domain = i;
1297 }
1298 }
1299 if (best_domain >= 0){
1300 ap_domain_index = best_domain;
1301 return 0;
1302 }
1303 return -ENODEV;
1304}
1305
1306/**
Felix Beck1749a812008-04-17 07:46:28 +02001307 * ap_probe_device_type(): Find the device type of an AP.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001308 * @ap_dev: pointer to the AP device.
Felix Beck1749a812008-04-17 07:46:28 +02001309 *
1310 * Find the device type if query queue returned a device type of 0.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001311 */
1312static int ap_probe_device_type(struct ap_device *ap_dev)
1313{
1314 static unsigned char msg[] = {
1315 0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
1316 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1317 0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,
1318 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1319 0x01,0x00,0x43,0x43,0x41,0x2d,0x41,0x50,
1320 0x50,0x4c,0x20,0x20,0x20,0x01,0x01,0x01,
1321 0x00,0x00,0x00,0x00,0x50,0x4b,0x00,0x00,
1322 0x00,0x00,0x01,0x1c,0x00,0x00,0x00,0x00,
1323 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1324 0x00,0x00,0x05,0xb8,0x00,0x00,0x00,0x00,
1325 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1326 0x70,0x00,0x41,0x00,0x00,0x00,0x00,0x00,
1327 0x00,0x00,0x54,0x32,0x01,0x00,0xa0,0x00,
1328 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1329 0x00,0x00,0x00,0x00,0xb8,0x05,0x00,0x00,
1330 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1331 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1332 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1333 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1334 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1335 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1336 0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,
1337 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1338 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,
1339 0x49,0x43,0x53,0x46,0x20,0x20,0x20,0x20,
1340 0x50,0x4b,0x0a,0x00,0x50,0x4b,0x43,0x53,
1341 0x2d,0x31,0x2e,0x32,0x37,0x00,0x11,0x22,
1342 0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,
1343 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,
1344 0x99,0x00,0x11,0x22,0x33,0x44,0x55,0x66,
1345 0x77,0x88,0x99,0x00,0x11,0x22,0x33,0x44,
1346 0x55,0x66,0x77,0x88,0x99,0x00,0x11,0x22,
1347 0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,
1348 0x11,0x22,0x33,0x5d,0x00,0x5b,0x00,0x77,
1349 0x88,0x1e,0x00,0x00,0x57,0x00,0x00,0x00,
1350 0x00,0x04,0x00,0x00,0x4f,0x00,0x00,0x00,
1351 0x03,0x02,0x00,0x00,0x40,0x01,0x00,0x01,
1352 0xce,0x02,0x68,0x2d,0x5f,0xa9,0xde,0x0c,
1353 0xf6,0xd2,0x7b,0x58,0x4b,0xf9,0x28,0x68,
1354 0x3d,0xb4,0xf4,0xef,0x78,0xd5,0xbe,0x66,
1355 0x63,0x42,0xef,0xf8,0xfd,0xa4,0xf8,0xb0,
1356 0x8e,0x29,0xc2,0xc9,0x2e,0xd8,0x45,0xb8,
1357 0x53,0x8c,0x6f,0x4e,0x72,0x8f,0x6c,0x04,
1358 0x9c,0x88,0xfc,0x1e,0xc5,0x83,0x55,0x57,
1359 0xf7,0xdd,0xfd,0x4f,0x11,0x36,0x95,0x5d,
1360 };
1361 struct ap_queue_status status;
1362 unsigned long long psmid;
1363 char *reply;
1364 int rc, i;
1365
1366 reply = (void *) get_zeroed_page(GFP_KERNEL);
1367 if (!reply) {
1368 rc = -ENOMEM;
1369 goto out;
1370 }
1371
1372 status = __ap_send(ap_dev->qid, 0x0102030405060708ULL,
Felix Becka6a5d732009-12-07 12:51:55 +01001373 msg, sizeof(msg), 0);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001374 if (status.response_code != AP_RESPONSE_NORMAL) {
1375 rc = -ENODEV;
1376 goto out_free;
1377 }
1378
1379 /* Wait for the test message to complete. */
1380 for (i = 0; i < 6; i++) {
1381 mdelay(300);
1382 status = __ap_recv(ap_dev->qid, &psmid, reply, 4096);
1383 if (status.response_code == AP_RESPONSE_NORMAL &&
1384 psmid == 0x0102030405060708ULL)
1385 break;
1386 }
1387 if (i < 6) {
1388 /* Got an answer. */
1389 if (reply[0] == 0x00 && reply[1] == 0x86)
1390 ap_dev->device_type = AP_DEVICE_TYPE_PCICC;
1391 else
1392 ap_dev->device_type = AP_DEVICE_TYPE_PCICA;
1393 rc = 0;
1394 } else
1395 rc = -ENODEV;
1396
1397out_free:
1398 free_page((unsigned long) reply);
1399out:
1400 return rc;
1401}
1402
Martin Schwidefskyf4eae942013-06-24 10:30:41 +02001403static void ap_interrupt_handler(struct airq_struct *airq)
Felix Beckcb17a632008-12-25 13:38:41 +01001404{
Heiko Carstens420f42e2013-01-02 15:18:18 +01001405 inc_irq_stat(IRQIO_APB);
Felix Beckcb17a632008-12-25 13:38:41 +01001406 tasklet_schedule(&ap_tasklet);
1407}
1408
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001409/**
Felix Beck1749a812008-04-17 07:46:28 +02001410 * __ap_scan_bus(): Scan the AP bus.
1411 * @dev: Pointer to device
1412 * @data: Pointer to data
1413 *
1414 * Scan the AP bus for new devices.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001415 */
1416static int __ap_scan_bus(struct device *dev, void *data)
1417{
1418 return to_ap_dev(dev)->qid == (ap_qid_t)(unsigned long) data;
1419}
1420
1421static void ap_device_release(struct device *dev)
1422{
1423 struct ap_device *ap_dev = to_ap_dev(dev);
1424
1425 kfree(ap_dev);
1426}
1427
Al Viro4927b3f2006-12-06 19:18:20 +00001428static void ap_scan_bus(struct work_struct *unused)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001429{
1430 struct ap_device *ap_dev;
1431 struct device *dev;
1432 ap_qid_t qid;
1433 int queue_depth, device_type;
Holger Dengler6bed05b2011-07-24 10:48:25 +02001434 unsigned int device_functions;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001435 int rc, i;
1436
Holger Dengler75014552012-08-28 16:41:50 +02001437 ap_query_configuration();
Ingo Tuchscherer56bbe682013-04-12 17:52:08 +02001438 if (ap_select_domain() != 0) {
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001439 return;
Ingo Tuchscherer56bbe682013-04-12 17:52:08 +02001440 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001441 for (i = 0; i < AP_DEVICES; i++) {
1442 qid = AP_MKQID(i, ap_domain_index);
1443 dev = bus_find_device(&ap_bus_type, NULL,
1444 (void *)(unsigned long)qid,
1445 __ap_scan_bus);
Holger Dengler75014552012-08-28 16:41:50 +02001446 if (ap_test_config_card_id(i))
1447 rc = ap_query_queue(qid, &queue_depth, &device_type);
1448 else
1449 rc = -ENODEV;
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001450 if (dev) {
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001451 if (rc == -EBUSY) {
1452 set_current_state(TASK_UNINTERRUPTIBLE);
1453 schedule_timeout(AP_RESET_TIMEOUT);
1454 rc = ap_query_queue(qid, &queue_depth,
1455 &device_type);
1456 }
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001457 ap_dev = to_ap_dev(dev);
1458 spin_lock_bh(&ap_dev->lock);
1459 if (rc || ap_dev->unregistered) {
1460 spin_unlock_bh(&ap_dev->lock);
Felix Beck5314af62009-09-22 22:58:51 +02001461 if (ap_dev->unregistered)
1462 i--;
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001463 device_unregister(dev);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001464 put_device(dev);
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001465 continue;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001466 }
1467 spin_unlock_bh(&ap_dev->lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001468 put_device(dev);
1469 continue;
1470 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001471 if (rc)
1472 continue;
1473 rc = ap_init_queue(qid);
1474 if (rc)
1475 continue;
1476 ap_dev = kzalloc(sizeof(*ap_dev), GFP_KERNEL);
1477 if (!ap_dev)
1478 break;
1479 ap_dev->qid = qid;
1480 ap_dev->queue_depth = queue_depth;
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001481 ap_dev->unregistered = 1;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001482 spin_lock_init(&ap_dev->lock);
1483 INIT_LIST_HEAD(&ap_dev->pendingq);
1484 INIT_LIST_HEAD(&ap_dev->requestq);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001485 INIT_LIST_HEAD(&ap_dev->list);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001486 setup_timer(&ap_dev->timeout, ap_request_timeout,
1487 (unsigned long) ap_dev);
Holger Dengler6bed05b2011-07-24 10:48:25 +02001488 switch (device_type) {
1489 case 0:
Holger Dengler1e2076f2012-08-28 16:48:29 +02001490 /* device type probing for old cards */
Holger Denglercf2d0072011-05-23 10:24:30 +02001491 if (ap_probe_device_type(ap_dev)) {
1492 kfree(ap_dev);
1493 continue;
1494 }
Holger Dengler6bed05b2011-07-24 10:48:25 +02001495 break;
Holger Dengler6bed05b2011-07-24 10:48:25 +02001496 default:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001497 ap_dev->device_type = device_type;
Holger Dengler6bed05b2011-07-24 10:48:25 +02001498 }
Ingo Tuchscherer42f4dd612014-10-02 14:48:46 +02001499 ap_dev->raw_hwtype = device_type;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001500
Holger Dengler1e2076f2012-08-28 16:48:29 +02001501 rc = ap_query_functions(qid, &device_functions);
1502 if (!rc)
1503 ap_dev->functions = device_functions;
1504 else
1505 ap_dev->functions = 0u;
1506
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001507 ap_dev->device.bus = &ap_bus_type;
1508 ap_dev->device.parent = ap_root_device;
Felix Beckedc44fa2009-09-11 10:28:52 +02001509 if (dev_set_name(&ap_dev->device, "card%02x",
1510 AP_QID_DEVICE(ap_dev->qid))) {
1511 kfree(ap_dev);
1512 continue;
1513 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001514 ap_dev->device.release = ap_device_release;
1515 rc = device_register(&ap_dev->device);
1516 if (rc) {
Sebastian Ottc6304932009-09-11 10:28:38 +02001517 put_device(&ap_dev->device);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001518 continue;
1519 }
1520 /* Add device attributes. */
1521 rc = sysfs_create_group(&ap_dev->device.kobj,
1522 &ap_dev_attr_group);
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001523 if (!rc) {
1524 spin_lock_bh(&ap_dev->lock);
1525 ap_dev->unregistered = 0;
1526 spin_unlock_bh(&ap_dev->lock);
1527 }
1528 else
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001529 device_unregister(&ap_dev->device);
1530 }
1531}
1532
1533static void
1534ap_config_timeout(unsigned long ptr)
1535{
1536 queue_work(ap_work_queue, &ap_config_work);
1537 ap_config_timer.expires = jiffies + ap_config_time * HZ;
1538 add_timer(&ap_config_timer);
1539}
1540
1541/**
Holger Denglerbc615de2011-11-14 11:19:04 +01001542 * __ap_schedule_poll_timer(): Schedule poll timer.
Felix Beck1749a812008-04-17 07:46:28 +02001543 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001544 * Set up the timer to run the poll tasklet
1545 */
Holger Denglerbc615de2011-11-14 11:19:04 +01001546static inline void __ap_schedule_poll_timer(void)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001547{
Felix Beck8d406c62009-07-24 12:39:53 +02001548 ktime_t hr_time;
Felix Beck93521312009-12-07 12:52:00 +01001549
1550 spin_lock_bh(&ap_poll_timer_lock);
Holger Denglerbc615de2011-11-14 11:19:04 +01001551 if (hrtimer_is_queued(&ap_poll_timer) || ap_suspend_flag)
Felix Beck93521312009-12-07 12:52:00 +01001552 goto out;
Felix Beck8d406c62009-07-24 12:39:53 +02001553 if (ktime_to_ns(hrtimer_expires_remaining(&ap_poll_timer)) <= 0) {
1554 hr_time = ktime_set(0, poll_timeout);
1555 hrtimer_forward_now(&ap_poll_timer, hr_time);
1556 hrtimer_restart(&ap_poll_timer);
1557 }
Felix Beck93521312009-12-07 12:52:00 +01001558out:
1559 spin_unlock_bh(&ap_poll_timer_lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001560}
1561
1562/**
Holger Denglerbc615de2011-11-14 11:19:04 +01001563 * ap_schedule_poll_timer(): Schedule poll timer.
1564 *
1565 * Set up the timer to run the poll tasklet
1566 */
1567static inline void ap_schedule_poll_timer(void)
1568{
1569 if (ap_using_interrupts())
1570 return;
1571 __ap_schedule_poll_timer();
1572}
1573
1574/**
Felix Beck1749a812008-04-17 07:46:28 +02001575 * ap_poll_read(): Receive pending reply messages from an AP device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001576 * @ap_dev: pointer to the AP device
1577 * @flags: pointer to control flags, bit 2^0 is set if another poll is
1578 * required, bit 2^1 is set if the poll timer needs to get armed
Felix Beck1749a812008-04-17 07:46:28 +02001579 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001580 * Returns 0 if the device is still present, -ENODEV if not.
1581 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +01001582static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001583{
1584 struct ap_queue_status status;
1585 struct ap_message *ap_msg;
1586
1587 if (ap_dev->queue_count <= 0)
1588 return 0;
1589 status = __ap_recv(ap_dev->qid, &ap_dev->reply->psmid,
1590 ap_dev->reply->message, ap_dev->reply->length);
1591 switch (status.response_code) {
1592 case AP_RESPONSE_NORMAL:
1593 atomic_dec(&ap_poll_requests);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001594 ap_decrease_queue_count(ap_dev);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001595 list_for_each_entry(ap_msg, &ap_dev->pendingq, list) {
1596 if (ap_msg->psmid != ap_dev->reply->psmid)
1597 continue;
1598 list_del_init(&ap_msg->list);
1599 ap_dev->pendingq_count--;
Holger Dengler54a8f562012-05-16 14:08:22 +02001600 ap_msg->receive(ap_dev, ap_msg, ap_dev->reply);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001601 break;
1602 }
1603 if (ap_dev->queue_count > 0)
1604 *flags |= 1;
1605 break;
1606 case AP_RESPONSE_NO_PENDING_REPLY:
1607 if (status.queue_empty) {
1608 /* The card shouldn't forget requests but who knows. */
Ralph Wuerthnere675c0d2007-03-26 20:42:43 +02001609 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001610 ap_dev->queue_count = 0;
1611 list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
1612 ap_dev->requestq_count += ap_dev->pendingq_count;
1613 ap_dev->pendingq_count = 0;
1614 } else
1615 *flags |= 2;
1616 break;
1617 default:
1618 return -ENODEV;
1619 }
1620 return 0;
1621}
1622
1623/**
Felix Beck1749a812008-04-17 07:46:28 +02001624 * ap_poll_write(): Send messages from the request queue to an AP device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001625 * @ap_dev: pointer to the AP device
1626 * @flags: pointer to control flags, bit 2^0 is set if another poll is
1627 * required, bit 2^1 is set if the poll timer needs to get armed
Felix Beck1749a812008-04-17 07:46:28 +02001628 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001629 * Returns 0 if the device is still present, -ENODEV if not.
1630 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +01001631static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001632{
1633 struct ap_queue_status status;
1634 struct ap_message *ap_msg;
1635
1636 if (ap_dev->requestq_count <= 0 ||
1637 ap_dev->queue_count >= ap_dev->queue_depth)
1638 return 0;
1639 /* Start the next request on the queue. */
1640 ap_msg = list_entry(ap_dev->requestq.next, struct ap_message, list);
1641 status = __ap_send(ap_dev->qid, ap_msg->psmid,
Felix Becka6a5d732009-12-07 12:51:55 +01001642 ap_msg->message, ap_msg->length, ap_msg->special);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001643 switch (status.response_code) {
1644 case AP_RESPONSE_NORMAL:
1645 atomic_inc(&ap_poll_requests);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001646 ap_increase_queue_count(ap_dev);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001647 list_move_tail(&ap_msg->list, &ap_dev->pendingq);
1648 ap_dev->requestq_count--;
1649 ap_dev->pendingq_count++;
1650 if (ap_dev->queue_count < ap_dev->queue_depth &&
1651 ap_dev->requestq_count > 0)
1652 *flags |= 1;
1653 *flags |= 2;
1654 break;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001655 case AP_RESPONSE_RESET_IN_PROGRESS:
Holger Denglerbc615de2011-11-14 11:19:04 +01001656 __ap_schedule_poll_timer();
1657 case AP_RESPONSE_Q_FULL:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001658 *flags |= 2;
1659 break;
1660 case AP_RESPONSE_MESSAGE_TOO_BIG:
Felix Becka6a5d732009-12-07 12:51:55 +01001661 case AP_RESPONSE_REQ_FAC_NOT_INST:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001662 return -EINVAL;
1663 default:
1664 return -ENODEV;
1665 }
1666 return 0;
1667}
1668
1669/**
Felix Beck1749a812008-04-17 07:46:28 +02001670 * ap_poll_queue(): Poll AP device for pending replies and send new messages.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001671 * @ap_dev: pointer to the bus device
1672 * @flags: pointer to control flags, bit 2^0 is set if another poll is
1673 * required, bit 2^1 is set if the poll timer needs to get armed
Felix Beck1749a812008-04-17 07:46:28 +02001674 *
1675 * Poll AP device for pending replies and send new messages. If either
1676 * ap_poll_read or ap_poll_write returns -ENODEV unregister the device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001677 * Returns 0.
1678 */
1679static inline int ap_poll_queue(struct ap_device *ap_dev, unsigned long *flags)
1680{
1681 int rc;
1682
1683 rc = ap_poll_read(ap_dev, flags);
1684 if (rc)
1685 return rc;
1686 return ap_poll_write(ap_dev, flags);
1687}
1688
1689/**
Felix Beck1749a812008-04-17 07:46:28 +02001690 * __ap_queue_message(): Queue a message to a device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001691 * @ap_dev: pointer to the AP device
1692 * @ap_msg: the message to be queued
Felix Beck1749a812008-04-17 07:46:28 +02001693 *
1694 * Queue a message to a device. Returns 0 if successful.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001695 */
1696static int __ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
1697{
1698 struct ap_queue_status status;
1699
1700 if (list_empty(&ap_dev->requestq) &&
1701 ap_dev->queue_count < ap_dev->queue_depth) {
1702 status = __ap_send(ap_dev->qid, ap_msg->psmid,
Felix Becka6a5d732009-12-07 12:51:55 +01001703 ap_msg->message, ap_msg->length,
1704 ap_msg->special);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001705 switch (status.response_code) {
1706 case AP_RESPONSE_NORMAL:
1707 list_add_tail(&ap_msg->list, &ap_dev->pendingq);
1708 atomic_inc(&ap_poll_requests);
1709 ap_dev->pendingq_count++;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001710 ap_increase_queue_count(ap_dev);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001711 ap_dev->total_request_count++;
1712 break;
1713 case AP_RESPONSE_Q_FULL:
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001714 case AP_RESPONSE_RESET_IN_PROGRESS:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001715 list_add_tail(&ap_msg->list, &ap_dev->requestq);
1716 ap_dev->requestq_count++;
1717 ap_dev->total_request_count++;
1718 return -EBUSY;
Felix Becka6a5d732009-12-07 12:51:55 +01001719 case AP_RESPONSE_REQ_FAC_NOT_INST:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001720 case AP_RESPONSE_MESSAGE_TOO_BIG:
Holger Dengler54a8f562012-05-16 14:08:22 +02001721 ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL));
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001722 return -EINVAL;
1723 default: /* Device is gone. */
Holger Dengler54a8f562012-05-16 14:08:22 +02001724 ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001725 return -ENODEV;
1726 }
1727 } else {
1728 list_add_tail(&ap_msg->list, &ap_dev->requestq);
1729 ap_dev->requestq_count++;
1730 ap_dev->total_request_count++;
1731 return -EBUSY;
1732 }
1733 ap_schedule_poll_timer();
1734 return 0;
1735}
1736
1737void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
1738{
1739 unsigned long flags;
1740 int rc;
1741
Holger Dengler54a8f562012-05-16 14:08:22 +02001742 /* For asynchronous message handling a valid receive-callback
1743 * is required. */
1744 BUG_ON(!ap_msg->receive);
1745
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001746 spin_lock_bh(&ap_dev->lock);
1747 if (!ap_dev->unregistered) {
1748 /* Make room on the queue by polling for finished requests. */
1749 rc = ap_poll_queue(ap_dev, &flags);
1750 if (!rc)
1751 rc = __ap_queue_message(ap_dev, ap_msg);
1752 if (!rc)
1753 wake_up(&ap_poll_wait);
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001754 if (rc == -ENODEV)
1755 ap_dev->unregistered = 1;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001756 } else {
Holger Dengler54a8f562012-05-16 14:08:22 +02001757 ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001758 rc = -ENODEV;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001759 }
1760 spin_unlock_bh(&ap_dev->lock);
1761 if (rc == -ENODEV)
1762 device_unregister(&ap_dev->device);
1763}
1764EXPORT_SYMBOL(ap_queue_message);
1765
1766/**
Felix Beck1749a812008-04-17 07:46:28 +02001767 * ap_cancel_message(): Cancel a crypto request.
1768 * @ap_dev: The AP device that has the message queued
1769 * @ap_msg: The message that is to be removed
1770 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001771 * Cancel a crypto request. This is done by removing the request
Felix Beck1749a812008-04-17 07:46:28 +02001772 * from the device pending or request queue. Note that the
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001773 * request stays on the AP queue. When it finishes the message
1774 * reply will be discarded because the psmid can't be found.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001775 */
1776void ap_cancel_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
1777{
1778 struct ap_message *tmp;
1779
1780 spin_lock_bh(&ap_dev->lock);
1781 if (!list_empty(&ap_msg->list)) {
1782 list_for_each_entry(tmp, &ap_dev->pendingq, list)
1783 if (tmp->psmid == ap_msg->psmid) {
1784 ap_dev->pendingq_count--;
1785 goto found;
1786 }
1787 ap_dev->requestq_count--;
1788 found:
1789 list_del_init(&ap_msg->list);
1790 }
1791 spin_unlock_bh(&ap_dev->lock);
1792}
1793EXPORT_SYMBOL(ap_cancel_message);
1794
1795/**
Felix Beck1749a812008-04-17 07:46:28 +02001796 * ap_poll_timeout(): AP receive polling for finished AP requests.
Felix Beckfe137232008-07-14 09:59:08 +02001797 * @unused: Unused pointer.
Felix Beck1749a812008-04-17 07:46:28 +02001798 *
Felix Beckfe137232008-07-14 09:59:08 +02001799 * Schedules the AP tasklet using a high resolution timer.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001800 */
Felix Beckfe137232008-07-14 09:59:08 +02001801static enum hrtimer_restart ap_poll_timeout(struct hrtimer *unused)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001802{
1803 tasklet_schedule(&ap_tasklet);
Felix Beckfe137232008-07-14 09:59:08 +02001804 return HRTIMER_NORESTART;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001805}
1806
1807/**
Felix Beck1749a812008-04-17 07:46:28 +02001808 * ap_reset(): Reset a not responding AP device.
1809 * @ap_dev: Pointer to the AP device
1810 *
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001811 * Reset a not responding AP device and move all requests from the
1812 * pending queue to the request queue.
1813 */
1814static void ap_reset(struct ap_device *ap_dev)
1815{
1816 int rc;
1817
1818 ap_dev->reset = AP_RESET_IGNORE;
1819 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
1820 ap_dev->queue_count = 0;
1821 list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
1822 ap_dev->requestq_count += ap_dev->pendingq_count;
1823 ap_dev->pendingq_count = 0;
1824 rc = ap_init_queue(ap_dev->qid);
1825 if (rc == -ENODEV)
1826 ap_dev->unregistered = 1;
Holger Dengler75464962011-12-01 13:32:23 +01001827 else
1828 __ap_schedule_poll_timer();
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001829}
1830
Christian Maaser43c207e62008-12-25 13:38:42 +01001831static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001832{
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001833 if (!ap_dev->unregistered) {
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001834 if (ap_poll_queue(ap_dev, flags))
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001835 ap_dev->unregistered = 1;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001836 if (ap_dev->reset == AP_RESET_DO)
1837 ap_reset(ap_dev);
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001838 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001839 return 0;
1840}
1841
Felix Beck1749a812008-04-17 07:46:28 +02001842/**
1843 * ap_poll_all(): Poll all AP devices.
1844 * @dummy: Unused variable
1845 *
1846 * Poll all AP devices on the bus in a round robin fashion. Continue
1847 * polling until bit 2^0 of the control flags is not set. If bit 2^1
1848 * of the control flags has been set arm the poll timer.
1849 */
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001850static void ap_poll_all(unsigned long dummy)
1851{
1852 unsigned long flags;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001853 struct ap_device *ap_dev;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001854
Felix Beckcb17a632008-12-25 13:38:41 +01001855 /* Reset the indicator if interrupts are used. Thus new interrupts can
1856 * be received. Doing it in the beginning of the tasklet is therefor
1857 * important that no requests on any AP get lost.
1858 */
1859 if (ap_using_interrupts())
Martin Schwidefskyf4eae942013-06-24 10:30:41 +02001860 xchg(ap_airq.lsi_ptr, 0);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001861 do {
1862 flags = 0;
Christian Maaser43c207e62008-12-25 13:38:42 +01001863 spin_lock(&ap_device_list_lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001864 list_for_each_entry(ap_dev, &ap_device_list, list) {
Felix Beck95f15562009-09-11 10:28:51 +02001865 spin_lock(&ap_dev->lock);
Christian Maaser43c207e62008-12-25 13:38:42 +01001866 __ap_poll_device(ap_dev, &flags);
Felix Beck95f15562009-09-11 10:28:51 +02001867 spin_unlock(&ap_dev->lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001868 }
Christian Maaser43c207e62008-12-25 13:38:42 +01001869 spin_unlock(&ap_device_list_lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001870 } while (flags & 1);
1871 if (flags & 2)
1872 ap_schedule_poll_timer();
1873}
1874
1875/**
Felix Beck1749a812008-04-17 07:46:28 +02001876 * ap_poll_thread(): Thread that polls for finished requests.
1877 * @data: Unused pointer
1878 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001879 * AP bus poll thread. The purpose of this thread is to poll for
1880 * finished requests in a loop if there is a "free" cpu - that is
1881 * a cpu that doesn't have anything better to do. The polling stops
1882 * as soon as there is another task or if all messages have been
1883 * delivered.
1884 */
1885static int ap_poll_thread(void *data)
1886{
1887 DECLARE_WAITQUEUE(wait, current);
1888 unsigned long flags;
1889 int requests;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001890 struct ap_device *ap_dev;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001891
Dongsheng Yang8698a742014-03-11 18:09:12 +08001892 set_user_nice(current, MAX_NICE);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001893 while (1) {
Felix Beck772f5472009-06-22 12:08:16 +02001894 if (ap_suspend_flag)
1895 return 0;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001896 if (need_resched()) {
1897 schedule();
1898 continue;
1899 }
1900 add_wait_queue(&ap_poll_wait, &wait);
1901 set_current_state(TASK_INTERRUPTIBLE);
1902 if (kthread_should_stop())
1903 break;
1904 requests = atomic_read(&ap_poll_requests);
1905 if (requests <= 0)
1906 schedule();
1907 set_current_state(TASK_RUNNING);
1908 remove_wait_queue(&ap_poll_wait, &wait);
1909
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001910 flags = 0;
Christian Maaser43c207e62008-12-25 13:38:42 +01001911 spin_lock_bh(&ap_device_list_lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001912 list_for_each_entry(ap_dev, &ap_device_list, list) {
Felix Beck95f15562009-09-11 10:28:51 +02001913 spin_lock(&ap_dev->lock);
Christian Maaser43c207e62008-12-25 13:38:42 +01001914 __ap_poll_device(ap_dev, &flags);
Felix Beck95f15562009-09-11 10:28:51 +02001915 spin_unlock(&ap_dev->lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001916 }
Christian Maaser43c207e62008-12-25 13:38:42 +01001917 spin_unlock_bh(&ap_device_list_lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001918 }
1919 set_current_state(TASK_RUNNING);
1920 remove_wait_queue(&ap_poll_wait, &wait);
1921 return 0;
1922}
1923
1924static int ap_poll_thread_start(void)
1925{
1926 int rc;
1927
Felix Beck772f5472009-06-22 12:08:16 +02001928 if (ap_using_interrupts() || ap_suspend_flag)
Felix Beckcb17a632008-12-25 13:38:41 +01001929 return 0;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001930 mutex_lock(&ap_poll_thread_mutex);
1931 if (!ap_poll_kthread) {
1932 ap_poll_kthread = kthread_run(ap_poll_thread, NULL, "appoll");
Thomas Meyerba8da212013-06-01 11:51:13 +02001933 rc = PTR_RET(ap_poll_kthread);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001934 if (rc)
1935 ap_poll_kthread = NULL;
1936 }
1937 else
1938 rc = 0;
1939 mutex_unlock(&ap_poll_thread_mutex);
1940 return rc;
1941}
1942
1943static void ap_poll_thread_stop(void)
1944{
1945 mutex_lock(&ap_poll_thread_mutex);
1946 if (ap_poll_kthread) {
1947 kthread_stop(ap_poll_kthread);
1948 ap_poll_kthread = NULL;
1949 }
1950 mutex_unlock(&ap_poll_thread_mutex);
1951}
1952
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001953/**
Felix Beck1749a812008-04-17 07:46:28 +02001954 * ap_request_timeout(): Handling of request timeouts
1955 * @data: Holds the AP device.
1956 *
1957 * Handles request timeouts.
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001958 */
1959static void ap_request_timeout(unsigned long data)
1960{
1961 struct ap_device *ap_dev = (struct ap_device *) data;
1962
Felix Beckcb17a632008-12-25 13:38:41 +01001963 if (ap_dev->reset == AP_RESET_ARMED) {
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001964 ap_dev->reset = AP_RESET_DO;
Felix Beckcb17a632008-12-25 13:38:41 +01001965
1966 if (ap_using_interrupts())
1967 tasklet_schedule(&ap_tasklet);
1968 }
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001969}
1970
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001971static void ap_reset_domain(void)
1972{
1973 int i;
1974
Ralph Wuerthner39aa7cf2007-10-12 16:11:29 +02001975 if (ap_domain_index != -1)
1976 for (i = 0; i < AP_DEVICES; i++)
1977 ap_reset_queue(AP_MKQID(i, ap_domain_index));
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001978}
1979
1980static void ap_reset_all(void)
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001981{
1982 int i, j;
1983
Ingo Tuchscherer170387a2014-09-08 13:24:13 +02001984 for (i = 0; i < AP_DOMAINS; i++) {
1985 if (!ap_test_config_domain(i))
1986 continue;
1987 for (j = 0; j < AP_DEVICES; j++) {
1988 if (!ap_test_config_card_id(j))
1989 continue;
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001990 ap_reset_queue(AP_MKQID(j, i));
Ingo Tuchscherer170387a2014-09-08 13:24:13 +02001991 }
1992 }
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001993}
1994
1995static struct reset_call ap_reset_call = {
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001996 .fn = ap_reset_all,
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001997};
1998
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001999/**
Felix Beck1749a812008-04-17 07:46:28 +02002000 * ap_module_init(): The module initialization code.
2001 *
2002 * Initializes the module.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002003 */
2004int __init ap_module_init(void)
2005{
2006 int rc, i;
2007
2008 if (ap_domain_index < -1 || ap_domain_index >= AP_DOMAINS) {
Martin Schwidefsky136f7a12008-12-25 13:39:46 +01002009 pr_warning("%d is not a valid cryptographic domain\n",
2010 ap_domain_index);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002011 return -EINVAL;
2012 }
Felix Beck5314af62009-09-22 22:58:51 +02002013 /* In resume callback we need to know if the user had set the domain.
2014 * If so, we can not just reset it.
2015 */
2016 if (ap_domain_index >= 0)
2017 user_set_domain = 1;
2018
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002019 if (ap_instructions_available() != 0) {
Martin Schwidefsky136f7a12008-12-25 13:39:46 +01002020 pr_warning("The hardware system does not support "
2021 "AP instructions\n");
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002022 return -ENODEV;
2023 }
Felix Beckcb17a632008-12-25 13:38:41 +01002024 if (ap_interrupts_available()) {
Martin Schwidefskyf4eae942013-06-24 10:30:41 +02002025 rc = register_adapter_interrupt(&ap_airq);
2026 ap_airq_flag = (rc == 0);
Felix Beckcb17a632008-12-25 13:38:41 +01002027 }
2028
Ralph Wuerthner85eca852006-12-08 15:54:07 +01002029 register_reset_call(&ap_reset_call);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002030
2031 /* Create /sys/bus/ap. */
2032 rc = bus_register(&ap_bus_type);
2033 if (rc)
2034 goto out;
2035 for (i = 0; ap_bus_attrs[i]; i++) {
2036 rc = bus_create_file(&ap_bus_type, ap_bus_attrs[i]);
2037 if (rc)
2038 goto out_bus;
2039 }
2040
2041 /* Create /sys/devices/ap. */
Mark McLoughlin035da162008-12-15 12:58:29 +00002042 ap_root_device = root_device_register("ap");
Thomas Meyerba8da212013-06-01 11:51:13 +02002043 rc = PTR_RET(ap_root_device);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002044 if (rc)
2045 goto out_bus;
2046
2047 ap_work_queue = create_singlethread_workqueue("kapwork");
2048 if (!ap_work_queue) {
2049 rc = -ENOMEM;
2050 goto out_root;
2051 }
2052
Holger Dengler75014552012-08-28 16:41:50 +02002053 ap_query_configuration();
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002054 if (ap_select_domain() == 0)
2055 ap_scan_bus(NULL);
2056
Felix Beck1749a812008-04-17 07:46:28 +02002057 /* Setup the AP bus rescan timer. */
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002058 init_timer(&ap_config_timer);
2059 ap_config_timer.function = ap_config_timeout;
2060 ap_config_timer.data = 0;
2061 ap_config_timer.expires = jiffies + ap_config_time * HZ;
2062 add_timer(&ap_config_timer);
2063
Felix Beckfe137232008-07-14 09:59:08 +02002064 /* Setup the high resultion poll timer.
2065 * If we are running under z/VM adjust polling to z/VM polling rate.
2066 */
2067 if (MACHINE_IS_VM)
2068 poll_timeout = 1500000;
Felix Beck93521312009-12-07 12:52:00 +01002069 spin_lock_init(&ap_poll_timer_lock);
Felix Beckfe137232008-07-14 09:59:08 +02002070 hrtimer_init(&ap_poll_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
2071 ap_poll_timer.function = ap_poll_timeout;
2072
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002073 /* Start the low priority AP bus poll thread. */
2074 if (ap_thread_flag) {
2075 rc = ap_poll_thread_start();
2076 if (rc)
2077 goto out_work;
2078 }
2079
2080 return 0;
2081
2082out_work:
2083 del_timer_sync(&ap_config_timer);
Felix Beckfe137232008-07-14 09:59:08 +02002084 hrtimer_cancel(&ap_poll_timer);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002085 destroy_workqueue(ap_work_queue);
2086out_root:
Mark McLoughlin035da162008-12-15 12:58:29 +00002087 root_device_unregister(ap_root_device);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002088out_bus:
2089 while (i--)
2090 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
2091 bus_unregister(&ap_bus_type);
2092out:
Ralph Wuerthner85eca852006-12-08 15:54:07 +01002093 unregister_reset_call(&ap_reset_call);
Martin Schwidefskyf4eae942013-06-24 10:30:41 +02002094 if (ap_using_interrupts())
2095 unregister_adapter_interrupt(&ap_airq);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002096 return rc;
2097}
2098
2099static int __ap_match_all(struct device *dev, void *data)
2100{
2101 return 1;
2102}
2103
2104/**
Felix Beck1749a812008-04-17 07:46:28 +02002105 * ap_modules_exit(): The module termination code
2106 *
2107 * Terminates the module.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002108 */
2109void ap_module_exit(void)
2110{
2111 int i;
2112 struct device *dev;
2113
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01002114 ap_reset_domain();
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002115 ap_poll_thread_stop();
2116 del_timer_sync(&ap_config_timer);
Felix Beckfe137232008-07-14 09:59:08 +02002117 hrtimer_cancel(&ap_poll_timer);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002118 destroy_workqueue(ap_work_queue);
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01002119 tasklet_kill(&ap_tasklet);
Mark McLoughlin035da162008-12-15 12:58:29 +00002120 root_device_unregister(ap_root_device);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002121 while ((dev = bus_find_device(&ap_bus_type, NULL, NULL,
2122 __ap_match_all)))
2123 {
2124 device_unregister(dev);
2125 put_device(dev);
2126 }
2127 for (i = 0; ap_bus_attrs[i]; i++)
2128 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
2129 bus_unregister(&ap_bus_type);
Ralph Wuerthner85eca852006-12-08 15:54:07 +01002130 unregister_reset_call(&ap_reset_call);
Martin Schwidefskyf4eae942013-06-24 10:30:41 +02002131 if (ap_using_interrupts())
2132 unregister_adapter_interrupt(&ap_airq);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002133}
2134
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002135module_init(ap_module_init);
2136module_exit(ap_module_exit);