blob: 7b9a493a3e51f1b5c3d2b4c9cfbcba6f7abd8d06 [file] [log] [blame]
Greg Kroah-Hartman812141a2017-11-14 18:38:01 +01001// SPDX-License-Identifier: GPL-2.0+
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002/*
Holger Dengler75014552012-08-28 16:41:50 +02003 * Copyright IBM Corp. 2006, 2012
Martin Schwidefsky1534c382006-09-20 15:58:25 +02004 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
5 * Martin Schwidefsky <schwidefsky@de.ibm.com>
6 * Ralph Wuerthner <rwuerthn@de.ibm.com>
Felix Beckcb17a632008-12-25 13:38:41 +01007 * Felix Beck <felix.beck@de.ibm.com>
Holger Dengler6bed05b2011-07-24 10:48:25 +02008 * Holger Dengler <hd@linux.vnet.ibm.com>
Martin Schwidefsky1534c382006-09-20 15:58:25 +02009 *
10 * Adjunct processor bus.
Martin Schwidefsky1534c382006-09-20 15:58:25 +020011 */
12
Martin Schwidefsky136f7a12008-12-25 13:39:46 +010013#define KMSG_COMPONENT "ap"
14#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
15
Holger Dengler62d146f2011-01-05 12:47:38 +010016#include <linux/kernel_stat.h>
Paul Gortmaker50a0d462017-02-09 09:48:10 -050017#include <linux/moduleparam.h>
Martin Schwidefsky1534c382006-09-20 15:58:25 +020018#include <linux/init.h>
19#include <linux/delay.h>
20#include <linux/err.h>
21#include <linux/interrupt.h>
22#include <linux/workqueue.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090023#include <linux/slab.h>
Martin Schwidefsky1534c382006-09-20 15:58:25 +020024#include <linux/notifier.h>
25#include <linux/kthread.h>
26#include <linux/mutex.h>
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +020027#include <linux/suspend.h>
Felix Beckcb17a632008-12-25 13:38:41 +010028#include <asm/airq.h>
Arun Sharma600634972011-07-26 16:09:06 -070029#include <linux/atomic.h>
Felix Beckcb17a632008-12-25 13:38:41 +010030#include <asm/isc.h>
Felix Beckfe137232008-07-14 09:59:08 +020031#include <linux/hrtimer.h>
32#include <linux/ktime.h>
David Howellsa0616cd2012-03-28 18:30:02 +010033#include <asm/facility.h>
Kees Cook5d26a102014-11-20 17:05:53 -080034#include <linux/crypto.h>
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +020035#include <linux/mod_devicetable.h>
Harald Freudenbergercccd85b2016-11-24 06:45:21 +010036#include <linux/debugfs.h>
Martin Schwidefsky1534c382006-09-20 15:58:25 +020037
38#include "ap_bus.h"
Harald Freudenbergercccd85b2016-11-24 06:45:21 +010039#include "ap_debug.h"
Martin Schwidefsky1534c382006-09-20 15:58:25 +020040
Felix Beck1749a812008-04-17 07:46:28 +020041/*
Paul Gortmaker50a0d462017-02-09 09:48:10 -050042 * Module parameters; note though this file itself isn't modular.
Martin Schwidefsky1534c382006-09-20 15:58:25 +020043 */
44int ap_domain_index = -1; /* Adjunct Processor Domain Index */
Ingo Tuchschererfc1d3f02016-08-25 11:11:30 +020045static DEFINE_SPINLOCK(ap_domain_lock);
Michael Veigelc1a42f42014-04-14 14:28:27 +020046module_param_named(domain, ap_domain_index, int, S_IRUSR|S_IRGRP);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020047MODULE_PARM_DESC(domain, "domain index for ap devices");
48EXPORT_SYMBOL(ap_domain_index);
49
Felix Beckb90b34c2008-02-09 18:24:30 +010050static int ap_thread_flag = 0;
Michael Veigelc1a42f42014-04-14 14:28:27 +020051module_param_named(poll_thread, ap_thread_flag, int, S_IRUSR|S_IRGRP);
Felix Beckb90b34c2008-02-09 18:24:30 +010052MODULE_PARM_DESC(poll_thread, "Turn on/off poll thread, default is 0 (off).");
Martin Schwidefsky1534c382006-09-20 15:58:25 +020053
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +020054static struct device *ap_root_device;
55
56DEFINE_SPINLOCK(ap_list_lock);
57LIST_HEAD(ap_card_list);
58
Holger Dengler75014552012-08-28 16:41:50 +020059static struct ap_config_info *ap_configuration;
Sascha Silbee3877532015-10-27 18:29:52 +010060static bool initialised;
Martin Schwidefsky1534c382006-09-20 15:58:25 +020061
Felix Beck1749a812008-04-17 07:46:28 +020062/*
Harald Freudenbergercccd85b2016-11-24 06:45:21 +010063 * AP bus related debug feature things.
64 */
Harald Freudenbergercccd85b2016-11-24 06:45:21 +010065debug_info_t *ap_dbf_info;
66
67/*
Martin Schwidefsky8139b892015-07-27 12:47:40 +020068 * Workqueue timer for bus rescan.
Martin Schwidefsky1534c382006-09-20 15:58:25 +020069 */
Martin Schwidefsky1534c382006-09-20 15:58:25 +020070static struct timer_list ap_config_timer;
71static int ap_config_time = AP_CONFIG_TIME;
Martin Schwidefsky3f3007a2015-09-14 17:01:23 +020072static void ap_scan_bus(struct work_struct *);
Martin Schwidefsky8139b892015-07-27 12:47:40 +020073static DECLARE_WORK(ap_scan_work, ap_scan_bus);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020074
Felix Beck1749a812008-04-17 07:46:28 +020075/*
Felix Beckcb17a632008-12-25 13:38:41 +010076 * Tasklet & timer for AP request polling and interrupts
Martin Schwidefsky1534c382006-09-20 15:58:25 +020077 */
Martin Schwidefsky3f3007a2015-09-14 17:01:23 +020078static void ap_tasklet_fn(unsigned long);
79static DECLARE_TASKLET(ap_tasklet, ap_tasklet_fn, 0);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020080static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait);
81static struct task_struct *ap_poll_kthread = NULL;
82static DEFINE_MUTEX(ap_poll_thread_mutex);
Felix Beck93521312009-12-07 12:52:00 +010083static DEFINE_SPINLOCK(ap_poll_timer_lock);
Felix Beckfe137232008-07-14 09:59:08 +020084static struct hrtimer ap_poll_timer;
85/* In LPAR poll with 4kHz frequency. Poll every 250000 nanoseconds.
86 * If z/VM change to 1500000 nanoseconds to adjust to z/VM polling.*/
87static unsigned long long poll_timeout = 250000;
Martin Schwidefsky1534c382006-09-20 15:58:25 +020088
Felix Beck772f5472009-06-22 12:08:16 +020089/* Suspend flag */
90static int ap_suspend_flag;
Martin Schwidefsky889875a2015-06-26 16:55:35 +020091/* Maximum domain id */
92static int ap_max_domain_id;
Felix Beck5314af62009-09-22 22:58:51 +020093/* Flag to check if domain was set through module parameter domain=. This is
94 * important when supsend and resume is done in a z/VM environment where the
95 * domain might change. */
96static int user_set_domain = 0;
Felix Beck772f5472009-06-22 12:08:16 +020097static struct bus_type ap_bus_type;
98
Martin Schwidefskyf4eae942013-06-24 10:30:41 +020099/* Adapter interrupt definitions */
Martin Schwidefsky3f3007a2015-09-14 17:01:23 +0200100static void ap_interrupt_handler(struct airq_struct *airq);
101
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200102static int ap_airq_flag;
103
104static struct airq_struct ap_airq = {
105 .handler = ap_interrupt_handler,
106 .isc = AP_ISC,
107};
108
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200109/**
Felix Beckcb17a632008-12-25 13:38:41 +0100110 * ap_using_interrupts() - Returns non-zero if interrupt support is
111 * available.
112 */
113static inline int ap_using_interrupts(void)
114{
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200115 return ap_airq_flag;
Felix Beckcb17a632008-12-25 13:38:41 +0100116}
117
118/**
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200119 * ap_airq_ptr() - Get the address of the adapter interrupt indicator
120 *
121 * Returns the address of the local-summary-indicator of the adapter
122 * interrupt handler for AP, or NULL if adapter interrupts are not
123 * available.
124 */
125void *ap_airq_ptr(void)
126{
127 if (ap_using_interrupts())
128 return ap_airq.lsi_ptr;
129 return NULL;
130}
131
132/**
Felix Beckcb17a632008-12-25 13:38:41 +0100133 * ap_interrupts_available(): Test if AP interrupts are available.
134 *
135 * Returns 1 if AP interrupts are available.
136 */
137static int ap_interrupts_available(void)
138{
Heiko Carstens86cd7412015-02-14 11:23:21 +0100139 return test_facility(65);
Felix Beckcb17a632008-12-25 13:38:41 +0100140}
141
142/**
Holger Dengler75014552012-08-28 16:41:50 +0200143 * ap_configuration_available(): Test if AP configuration
144 * information is available.
145 *
146 * Returns 1 if AP configuration information is available.
147 */
148static int ap_configuration_available(void)
149{
Heiko Carstens86cd7412015-02-14 11:23:21 +0100150 return test_facility(12);
Holger Dengler75014552012-08-28 16:41:50 +0200151}
152
153/**
Tony Krowiake7fc5142016-11-08 07:09:13 +0100154 * ap_apft_available(): Test if AP facilities test (APFT)
155 * facility is available.
156 *
157 * Returns 1 if APFT is is available.
158 */
159static int ap_apft_available(void)
160{
161 return test_facility(15);
162}
163
Harald Freudenberger9a564102017-10-16 12:28:35 +0200164/*
165 * ap_qact_available(): Test if the PQAP(QACT) subfunction is available.
166 *
167 * Returns 1 if the QACT subfunction is available.
168 */
169static inline int ap_qact_available(void)
170{
171 if (ap_configuration)
172 return ap_configuration->qact;
173 return 0;
174}
175
Harald Freudenberger050349b2016-11-08 11:54:28 +0100176/*
177 * ap_query_configuration(): Fetch cryptographic config info
178 *
179 * Returns the ap configuration info fetched via PQAP(QCI).
180 * On success 0 is returned, on failure a negative errno
181 * is returned, e.g. if the PQAP(QCI) instruction is not
182 * available, the return value will be -EOPNOTSUPP.
183 */
Harald Freudenbergerf1b0a4342018-06-12 15:42:36 +0200184static inline int ap_query_configuration(struct ap_config_info *info)
Heiko Carstens11d37672016-06-20 14:00:27 +0200185{
Harald Freudenberger050349b2016-11-08 11:54:28 +0100186 if (!ap_configuration_available())
Heiko Carstens11d37672016-06-20 14:00:27 +0200187 return -EOPNOTSUPP;
Harald Freudenberger050349b2016-11-08 11:54:28 +0100188 if (!info)
189 return -EINVAL;
190 return ap_qci(info);
Heiko Carstens11d37672016-06-20 14:00:27 +0200191}
Harald Freudenberger050349b2016-11-08 11:54:28 +0100192EXPORT_SYMBOL(ap_query_configuration);
Heiko Carstens11d37672016-06-20 14:00:27 +0200193
Holger Dengler6bed05b2011-07-24 10:48:25 +0200194/**
Martin Schwidefsky889875a2015-06-26 16:55:35 +0200195 * ap_init_configuration(): Allocate and query configuration array.
196 */
197static void ap_init_configuration(void)
198{
199 if (!ap_configuration_available())
200 return;
201
202 ap_configuration = kzalloc(sizeof(*ap_configuration), GFP_KERNEL);
203 if (!ap_configuration)
204 return;
Harald Freudenberger050349b2016-11-08 11:54:28 +0100205 if (ap_query_configuration(ap_configuration) != 0) {
Martin Schwidefsky889875a2015-06-26 16:55:35 +0200206 kfree(ap_configuration);
207 ap_configuration = NULL;
208 return;
209 }
210}
211
212/*
213 * ap_test_config(): helper function to extract the nrth bit
214 * within the unsigned int array field.
215 */
216static inline int ap_test_config(unsigned int *field, unsigned int nr)
217{
218 return ap_test_bit((field + (nr >> 5)), (nr & 0x1f));
219}
220
221/*
222 * ap_test_config_card_id(): Test, whether an AP card ID is configured.
223 * @id AP card ID
224 *
225 * Returns 0 if the card is not configured
226 * 1 if the card is configured or
227 * if the configuration information is not available
228 */
229static inline int ap_test_config_card_id(unsigned int id)
230{
231 if (!ap_configuration) /* QCI not supported */
232 return 1;
233 return ap_test_config(ap_configuration->apm, id);
234}
235
236/*
237 * ap_test_config_domain(): Test, whether an AP usage domain is configured.
238 * @domain AP usage domain ID
239 *
240 * Returns 0 if the usage domain is not configured
241 * 1 if the usage domain is configured or
242 * if the configuration information is not available
243 */
244static inline int ap_test_config_domain(unsigned int domain)
245{
246 if (!ap_configuration) /* QCI not supported */
247 return domain < 16;
248 return ap_test_config(ap_configuration->aqm, domain);
249}
250
251/**
Felix Beck1749a812008-04-17 07:46:28 +0200252 * ap_query_queue(): Check if an AP queue is available.
253 * @qid: The AP queue number
254 * @queue_depth: Pointer to queue depth value
255 * @device_type: Pointer to device type value
Martin Schwidefsky6acbe212015-06-26 15:40:41 +0200256 * @facilities: Pointer to facility indicator
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200257 */
Martin Schwidefsky6acbe212015-06-26 15:40:41 +0200258static int ap_query_queue(ap_qid_t qid, int *queue_depth, int *device_type,
259 unsigned int *facilities)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200260{
261 struct ap_queue_status status;
Martin Schwidefsky6acbe212015-06-26 15:40:41 +0200262 unsigned long info;
Martin Schwidefsky889875a2015-06-26 16:55:35 +0200263 int nd;
264
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200265 if (!ap_test_config_card_id(AP_QID_CARD(qid)))
Martin Schwidefsky889875a2015-06-26 16:55:35 +0200266 return -ENODEV;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200267
Tony Krowiake7fc5142016-11-08 07:09:13 +0100268 status = ap_test_queue(qid, ap_apft_available(), &info);
Ingo Tuchschererc50a1602015-06-17 16:19:15 +0200269 switch (status.response_code) {
270 case AP_RESPONSE_NORMAL:
Martin Schwidefsky6acbe212015-06-26 15:40:41 +0200271 *queue_depth = (int)(info & 0xff);
272 *device_type = (int)((info >> 24) & 0xff);
273 *facilities = (unsigned int)(info >> 32);
Martin Schwidefsky889875a2015-06-26 16:55:35 +0200274 /* Update maximum domain id */
275 nd = (info >> 16) & 0xff;
Ingo Tuchschererc1c13682016-11-02 10:23:24 +0100276 /* if N bit is available, z13 and newer */
Martin Schwidefsky889875a2015-06-26 16:55:35 +0200277 if ((info & (1UL << 57)) && nd > 0)
278 ap_max_domain_id = nd;
Ingo Tuchschererc1c13682016-11-02 10:23:24 +0100279 else /* older machine types */
280 ap_max_domain_id = 15;
Harald Freudenberger14878422016-10-27 08:57:39 +0200281 switch (*device_type) {
282 /* For CEX2 and CEX3 the available functions
283 * are not refrected by the facilities bits.
284 * Instead it is coded into the type. So here
285 * modify the function bits based on the type.
286 */
287 case AP_DEVICE_TYPE_CEX2A:
288 case AP_DEVICE_TYPE_CEX3A:
289 *facilities |= 0x08000000;
290 break;
291 case AP_DEVICE_TYPE_CEX2C:
292 case AP_DEVICE_TYPE_CEX3C:
293 *facilities |= 0x10000000;
294 break;
295 default:
296 break;
297 }
Ingo Tuchschererc50a1602015-06-17 16:19:15 +0200298 return 0;
299 case AP_RESPONSE_Q_NOT_AVAIL:
300 case AP_RESPONSE_DECONFIGURED:
301 case AP_RESPONSE_CHECKSTOPPED:
302 case AP_RESPONSE_INVALID_ADDRESS:
303 return -ENODEV;
304 case AP_RESPONSE_RESET_IN_PROGRESS:
305 case AP_RESPONSE_OTHERWISE_CHANGED:
306 case AP_RESPONSE_BUSY:
307 return -EBUSY;
308 default:
309 BUG();
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200310 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200311}
312
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200313void ap_wait(enum ap_wait wait)
Martin Schwidefsky3f3007a2015-09-14 17:01:23 +0200314{
315 ktime_t hr_time;
316
317 switch (wait) {
318 case AP_WAIT_AGAIN:
319 case AP_WAIT_INTERRUPT:
320 if (ap_using_interrupts())
321 break;
322 if (ap_poll_kthread) {
323 wake_up(&ap_poll_wait);
324 break;
325 }
326 /* Fall through */
327 case AP_WAIT_TIMEOUT:
328 spin_lock_bh(&ap_poll_timer_lock);
329 if (!hrtimer_is_queued(&ap_poll_timer)) {
Thomas Gleixner8b0e1952016-12-25 12:30:41 +0100330 hr_time = poll_timeout;
Martin Schwidefsky3f3007a2015-09-14 17:01:23 +0200331 hrtimer_forward_now(&ap_poll_timer, hr_time);
332 hrtimer_restart(&ap_poll_timer);
333 }
334 spin_unlock_bh(&ap_poll_timer_lock);
335 break;
336 case AP_WAIT_NONE:
337 default:
338 break;
339 }
340}
341
Martin Schwidefsky3f3007a2015-09-14 17:01:23 +0200342/**
343 * ap_request_timeout(): Handling of request timeouts
Kees Cookcefbeb52017-10-25 03:27:37 -0700344 * @t: timer making this callback
Martin Schwidefsky3f3007a2015-09-14 17:01:23 +0200345 *
346 * Handles request timeouts.
347 */
Kees Cookcefbeb52017-10-25 03:27:37 -0700348void ap_request_timeout(struct timer_list *t)
Martin Schwidefsky3f3007a2015-09-14 17:01:23 +0200349{
Kees Cookcefbeb52017-10-25 03:27:37 -0700350 struct ap_queue *aq = from_timer(aq, t, timeout);
Martin Schwidefsky3f3007a2015-09-14 17:01:23 +0200351
352 if (ap_suspend_flag)
353 return;
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200354 spin_lock_bh(&aq->lock);
355 ap_wait(ap_sm_event(aq, AP_EVENT_TIMEOUT));
356 spin_unlock_bh(&aq->lock);
Martin Schwidefsky3f3007a2015-09-14 17:01:23 +0200357}
358
359/**
360 * ap_poll_timeout(): AP receive polling for finished AP requests.
361 * @unused: Unused pointer.
362 *
363 * Schedules the AP tasklet using a high resolution timer.
364 */
365static enum hrtimer_restart ap_poll_timeout(struct hrtimer *unused)
366{
367 if (!ap_suspend_flag)
368 tasklet_schedule(&ap_tasklet);
369 return HRTIMER_NORESTART;
370}
371
372/**
373 * ap_interrupt_handler() - Schedule ap_tasklet on interrupt
374 * @airq: pointer to adapter interrupt descriptor
375 */
376static void ap_interrupt_handler(struct airq_struct *airq)
377{
378 inc_irq_stat(IRQIO_APB);
379 if (!ap_suspend_flag)
380 tasklet_schedule(&ap_tasklet);
381}
382
383/**
384 * ap_tasklet_fn(): Tasklet to poll all AP devices.
385 * @dummy: Unused variable
386 *
387 * Poll all AP devices on the bus.
388 */
389static void ap_tasklet_fn(unsigned long dummy)
390{
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200391 struct ap_card *ac;
392 struct ap_queue *aq;
Martin Schwidefsky3f3007a2015-09-14 17:01:23 +0200393 enum ap_wait wait = AP_WAIT_NONE;
394
395 /* Reset the indicator if interrupts are used. Thus new interrupts can
396 * be received. Doing it in the beginning of the tasklet is therefor
397 * important that no requests on any AP get lost.
398 */
399 if (ap_using_interrupts())
400 xchg(ap_airq.lsi_ptr, 0);
401
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200402 spin_lock_bh(&ap_list_lock);
403 for_each_ap_card(ac) {
404 for_each_ap_queue(aq, ac) {
405 spin_lock_bh(&aq->lock);
406 wait = min(wait, ap_sm_event_loop(aq, AP_EVENT_POLL));
407 spin_unlock_bh(&aq->lock);
408 }
Martin Schwidefsky3f3007a2015-09-14 17:01:23 +0200409 }
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200410 spin_unlock_bh(&ap_list_lock);
411
412 ap_wait(wait);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200413}
414
Martin Schwidefsky9af3e042016-09-21 14:12:53 +0200415static int ap_pending_requests(void)
416{
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200417 struct ap_card *ac;
418 struct ap_queue *aq;
Martin Schwidefsky9af3e042016-09-21 14:12:53 +0200419
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200420 spin_lock_bh(&ap_list_lock);
421 for_each_ap_card(ac) {
422 for_each_ap_queue(aq, ac) {
423 if (aq->queue_count == 0)
424 continue;
425 spin_unlock_bh(&ap_list_lock);
426 return 1;
Martin Schwidefsky9af3e042016-09-21 14:12:53 +0200427 }
Martin Schwidefsky9af3e042016-09-21 14:12:53 +0200428 }
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200429 spin_unlock_bh(&ap_list_lock);
430 return 0;
Martin Schwidefsky9af3e042016-09-21 14:12:53 +0200431}
432
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200433/**
434 * ap_poll_thread(): Thread that polls for finished requests.
435 * @data: Unused pointer
436 *
437 * AP bus poll thread. The purpose of this thread is to poll for
438 * finished requests in a loop if there is a "free" cpu - that is
439 * a cpu that doesn't have anything better to do. The polling stops
440 * as soon as there is another task or if all messages have been
441 * delivered.
442 */
443static int ap_poll_thread(void *data)
444{
445 DECLARE_WAITQUEUE(wait, current);
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200446
447 set_user_nice(current, MAX_NICE);
448 set_freezable();
449 while (!kthread_should_stop()) {
450 add_wait_queue(&ap_poll_wait, &wait);
451 set_current_state(TASK_INTERRUPTIBLE);
Martin Schwidefsky9af3e042016-09-21 14:12:53 +0200452 if (ap_suspend_flag || !ap_pending_requests()) {
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200453 schedule();
454 try_to_freeze();
455 }
456 set_current_state(TASK_RUNNING);
457 remove_wait_queue(&ap_poll_wait, &wait);
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200458 if (need_resched()) {
459 schedule();
460 try_to_freeze();
461 continue;
462 }
Martin Schwidefsky3f3007a2015-09-14 17:01:23 +0200463 ap_tasklet_fn(0);
Martin Schwidefsky9af3e042016-09-21 14:12:53 +0200464 }
465
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200466 return 0;
467}
468
469static int ap_poll_thread_start(void)
470{
471 int rc;
472
473 if (ap_using_interrupts() || ap_poll_kthread)
474 return 0;
475 mutex_lock(&ap_poll_thread_mutex);
476 ap_poll_kthread = kthread_run(ap_poll_thread, NULL, "appoll");
Gustavo A. R. Silva9c705202018-07-18 23:42:05 -0500477 rc = PTR_ERR_OR_ZERO(ap_poll_kthread);
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200478 if (rc)
479 ap_poll_kthread = NULL;
480 mutex_unlock(&ap_poll_thread_mutex);
481 return rc;
482}
483
484static void ap_poll_thread_stop(void)
485{
486 if (!ap_poll_kthread)
487 return;
488 mutex_lock(&ap_poll_thread_mutex);
489 kthread_stop(ap_poll_kthread);
490 ap_poll_kthread = NULL;
491 mutex_unlock(&ap_poll_thread_mutex);
492}
493
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200494#define is_card_dev(x) ((x)->parent == ap_root_device)
495#define is_queue_dev(x) ((x)->parent != ap_root_device)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200496
497/**
Felix Beck1749a812008-04-17 07:46:28 +0200498 * ap_bus_match()
499 * @dev: Pointer to device
500 * @drv: Pointer to device_driver
501 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200502 * AP bus driver registration/unregistration.
503 */
504static int ap_bus_match(struct device *dev, struct device_driver *drv)
505{
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200506 struct ap_driver *ap_drv = to_ap_drv(drv);
507 struct ap_device_id *id;
508
Felix Beck1749a812008-04-17 07:46:28 +0200509 /*
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200510 * Compare device type of the device with the list of
511 * supported types of the device_driver.
512 */
513 for (id = ap_drv->ids; id->match_flags; id++) {
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200514 if (is_card_dev(dev) &&
515 id->match_flags & AP_DEVICE_ID_MATCH_CARD_TYPE &&
516 id->dev_type == to_ap_dev(dev)->device_type)
517 return 1;
518 if (is_queue_dev(dev) &&
519 id->match_flags & AP_DEVICE_ID_MATCH_QUEUE_TYPE &&
520 id->dev_type == to_ap_dev(dev)->device_type)
521 return 1;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200522 }
523 return 0;
524}
525
526/**
Felix Beck1749a812008-04-17 07:46:28 +0200527 * ap_uevent(): Uevent function for AP devices.
528 * @dev: Pointer to device
529 * @env: Pointer to kobj_uevent_env
530 *
531 * It sets up a single environment variable DEV_TYPE which contains the
532 * hardware device type.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200533 */
Kay Sievers7eff2e72007-08-14 15:15:12 +0200534static int ap_uevent (struct device *dev, struct kobj_uevent_env *env)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200535{
536 struct ap_device *ap_dev = to_ap_dev(dev);
Kay Sievers7eff2e72007-08-14 15:15:12 +0200537 int retval = 0;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200538
539 if (!ap_dev)
540 return -ENODEV;
541
542 /* Set up DEV_TYPE environment variable. */
Kay Sievers7eff2e72007-08-14 15:15:12 +0200543 retval = add_uevent_var(env, "DEV_TYPE=%04X", ap_dev->device_type);
Eric Rannaudbf624562007-03-30 22:23:12 -0700544 if (retval)
545 return retval;
546
Cornelia Huck66a4263b2006-12-04 15:40:10 +0100547 /* Add MODALIAS= */
Kay Sievers7eff2e72007-08-14 15:15:12 +0200548 retval = add_uevent_var(env, "MODALIAS=ap:t%02X", ap_dev->device_type);
Eric Rannaudbf624562007-03-30 22:23:12 -0700549
Eric Rannaudbf624562007-03-30 22:23:12 -0700550 return retval;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200551}
552
Lars-Peter Clausen3e488c92016-11-22 22:06:00 +0100553static int ap_dev_suspend(struct device *dev)
Felix Beck772f5472009-06-22 12:08:16 +0200554{
555 struct ap_device *ap_dev = to_ap_dev(dev);
Felix Beck772f5472009-06-22 12:08:16 +0200556
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200557 if (ap_dev->drv && ap_dev->drv->suspend)
558 ap_dev->drv->suspend(ap_dev);
559 return 0;
560}
561
562static int ap_dev_resume(struct device *dev)
563{
564 struct ap_device *ap_dev = to_ap_dev(dev);
565
566 if (ap_dev->drv && ap_dev->drv->resume)
567 ap_dev->drv->resume(ap_dev);
Felix Beck772f5472009-06-22 12:08:16 +0200568 return 0;
569}
570
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200571static void ap_bus_suspend(void)
572{
Harald Freudenbergercccd85b2016-11-24 06:45:21 +0100573 AP_DBF(DBF_DEBUG, "ap_bus_suspend running\n");
574
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200575 ap_suspend_flag = 1;
576 /*
577 * Disable scanning for devices, thus we do not want to scan
578 * for them after removing.
579 */
Martin Schwidefsky8139b892015-07-27 12:47:40 +0200580 flush_work(&ap_scan_work);
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200581 tasklet_disable(&ap_tasklet);
582}
583
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200584static int __ap_card_devices_unregister(struct device *dev, void *dummy)
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200585{
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200586 if (is_card_dev(dev))
587 device_unregister(dev);
588 return 0;
589}
590
591static int __ap_queue_devices_unregister(struct device *dev, void *dummy)
592{
593 if (is_queue_dev(dev))
594 device_unregister(dev);
595 return 0;
596}
597
598static int __ap_queue_devices_with_id_unregister(struct device *dev, void *data)
599{
600 if (is_queue_dev(dev) &&
601 AP_QID_CARD(to_ap_queue(dev)->qid) == (int)(long) data)
602 device_unregister(dev);
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200603 return 0;
604}
605
606static void ap_bus_resume(void)
607{
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200608 int rc;
Felix Beck772f5472009-06-22 12:08:16 +0200609
Harald Freudenbergercccd85b2016-11-24 06:45:21 +0100610 AP_DBF(DBF_DEBUG, "ap_bus_resume running\n");
611
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200612 /* remove all queue devices */
613 bus_for_each_dev(&ap_bus_type, NULL, NULL,
614 __ap_queue_devices_unregister);
615 /* remove all card devices */
616 bus_for_each_dev(&ap_bus_type, NULL, NULL,
617 __ap_card_devices_unregister);
618
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200619 /* Reset thin interrupt setting */
620 if (ap_interrupts_available() && !ap_using_interrupts()) {
621 rc = register_adapter_interrupt(&ap_airq);
622 ap_airq_flag = (rc == 0);
Felix Beck5314af62009-09-22 22:58:51 +0200623 }
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200624 if (!ap_interrupts_available() && ap_using_interrupts()) {
625 unregister_adapter_interrupt(&ap_airq);
626 ap_airq_flag = 0;
627 }
628 /* Reset domain */
629 if (!user_set_domain)
630 ap_domain_index = -1;
631 /* Get things going again */
632 ap_suspend_flag = 0;
633 if (ap_airq_flag)
634 xchg(ap_airq.lsi_ptr, 0);
635 tasklet_enable(&ap_tasklet);
Martin Schwidefsky8139b892015-07-27 12:47:40 +0200636 queue_work(system_long_wq, &ap_scan_work);
Felix Beck772f5472009-06-22 12:08:16 +0200637}
638
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200639static int ap_power_event(struct notifier_block *this, unsigned long event,
640 void *ptr)
641{
642 switch (event) {
643 case PM_HIBERNATION_PREPARE:
644 case PM_SUSPEND_PREPARE:
645 ap_bus_suspend();
646 break;
647 case PM_POST_HIBERNATION:
648 case PM_POST_SUSPEND:
649 ap_bus_resume();
650 break;
651 default:
652 break;
653 }
654 return NOTIFY_DONE;
655}
656static struct notifier_block ap_power_notifier = {
657 .notifier_call = ap_power_event,
658};
659
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200660static SIMPLE_DEV_PM_OPS(ap_bus_pm_ops, ap_dev_suspend, ap_dev_resume);
Lars-Peter Clausen3e488c92016-11-22 22:06:00 +0100661
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200662static struct bus_type ap_bus_type = {
663 .name = "ap",
664 .match = &ap_bus_match,
665 .uevent = &ap_uevent,
Lars-Peter Clausen3e488c92016-11-22 22:06:00 +0100666 .pm = &ap_bus_pm_ops,
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200667};
668
669static int ap_device_probe(struct device *dev)
670{
671 struct ap_device *ap_dev = to_ap_dev(dev);
672 struct ap_driver *ap_drv = to_ap_drv(dev->driver);
673 int rc;
674
Harald Freudenbergere3850502017-05-24 10:26:29 +0200675 /* Add queue/card to list of active queues/cards */
676 spin_lock_bh(&ap_list_lock);
677 if (is_card_dev(dev))
678 list_add(&to_ap_card(dev)->list, &ap_card_list);
679 else
680 list_add(&to_ap_queue(dev)->list,
681 &to_ap_queue(dev)->card->queues);
682 spin_unlock_bh(&ap_list_lock);
683
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200684 ap_dev->drv = ap_drv;
685 rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV;
Harald Freudenbergere3850502017-05-24 10:26:29 +0200686
687 if (rc) {
688 spin_lock_bh(&ap_list_lock);
689 if (is_card_dev(dev))
690 list_del_init(&to_ap_card(dev)->list);
691 else
692 list_del_init(&to_ap_queue(dev)->list);
693 spin_unlock_bh(&ap_list_lock);
Martin Schwidefsky3f3007a2015-09-14 17:01:23 +0200694 ap_dev->drv = NULL;
Harald Freudenbergere3850502017-05-24 10:26:29 +0200695 }
696
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200697 return rc;
698}
699
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200700static int ap_device_remove(struct device *dev)
701{
702 struct ap_device *ap_dev = to_ap_dev(dev);
703 struct ap_driver *ap_drv = ap_dev->drv;
704
Harald Freudenbergere3850502017-05-24 10:26:29 +0200705 if (ap_drv->remove)
706 ap_drv->remove(ap_dev);
707
708 /* Remove queue/card from list of active queues/cards */
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200709 spin_lock_bh(&ap_list_lock);
710 if (is_card_dev(dev))
711 list_del_init(&to_ap_card(dev)->list);
712 else
713 list_del_init(&to_ap_queue(dev)->list);
714 spin_unlock_bh(&ap_list_lock);
Harald Freudenbergere3850502017-05-24 10:26:29 +0200715
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200716 return 0;
717}
718
719int ap_driver_register(struct ap_driver *ap_drv, struct module *owner,
720 char *name)
721{
722 struct device_driver *drv = &ap_drv->driver;
723
Sascha Silbee3877532015-10-27 18:29:52 +0100724 if (!initialised)
725 return -ENODEV;
726
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200727 drv->bus = &ap_bus_type;
728 drv->probe = ap_device_probe;
729 drv->remove = ap_device_remove;
730 drv->owner = owner;
731 drv->name = name;
732 return driver_register(drv);
733}
734EXPORT_SYMBOL(ap_driver_register);
735
736void ap_driver_unregister(struct ap_driver *ap_drv)
737{
738 driver_unregister(&ap_drv->driver);
739}
740EXPORT_SYMBOL(ap_driver_unregister);
741
Holger Denglerdabecb22012-09-10 21:34:26 +0200742void ap_bus_force_rescan(void)
743{
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200744 if (ap_suspend_flag)
745 return;
Ingo Tuchscherer56bbe682013-04-12 17:52:08 +0200746 /* processing a asynchronous bus rescan */
Martin Schwidefskyfcd0d1f2015-07-23 10:55:59 +0200747 del_timer(&ap_config_timer);
Martin Schwidefsky8139b892015-07-27 12:47:40 +0200748 queue_work(system_long_wq, &ap_scan_work);
749 flush_work(&ap_scan_work);
Holger Denglerdabecb22012-09-10 21:34:26 +0200750}
751EXPORT_SYMBOL(ap_bus_force_rescan);
752
Felix Beck1749a812008-04-17 07:46:28 +0200753/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200754 * AP bus attributes.
755 */
756static ssize_t ap_domain_show(struct bus_type *bus, char *buf)
757{
758 return snprintf(buf, PAGE_SIZE, "%d\n", ap_domain_index);
759}
760
Ingo Tuchschererfc1d3f02016-08-25 11:11:30 +0200761static ssize_t ap_domain_store(struct bus_type *bus,
762 const char *buf, size_t count)
763{
764 int domain;
765
766 if (sscanf(buf, "%i\n", &domain) != 1 ||
767 domain < 0 || domain > ap_max_domain_id)
768 return -EINVAL;
769 spin_lock_bh(&ap_domain_lock);
770 ap_domain_index = domain;
771 spin_unlock_bh(&ap_domain_lock);
Harald Freudenbergercccd85b2016-11-24 06:45:21 +0100772
Harald Freudenbergerac994e82017-05-12 16:35:14 +0200773 AP_DBF(DBF_DEBUG, "stored new default domain=%d\n", domain);
Harald Freudenbergercccd85b2016-11-24 06:45:21 +0100774
Ingo Tuchschererfc1d3f02016-08-25 11:11:30 +0200775 return count;
776}
777
778static BUS_ATTR(ap_domain, 0644, ap_domain_show, ap_domain_store);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200779
Ingo Tuchscherer91f3e3ea2013-11-20 10:47:13 +0100780static ssize_t ap_control_domain_mask_show(struct bus_type *bus, char *buf)
781{
Martin Schwidefsky889875a2015-06-26 16:55:35 +0200782 if (!ap_configuration) /* QCI not supported */
783 return snprintf(buf, PAGE_SIZE, "not supported\n");
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200784
Martin Schwidefsky889875a2015-06-26 16:55:35 +0200785 return snprintf(buf, PAGE_SIZE,
786 "0x%08x%08x%08x%08x%08x%08x%08x%08x\n",
Ingo Tuchscherer91f3e3ea2013-11-20 10:47:13 +0100787 ap_configuration->adm[0], ap_configuration->adm[1],
788 ap_configuration->adm[2], ap_configuration->adm[3],
789 ap_configuration->adm[4], ap_configuration->adm[5],
790 ap_configuration->adm[6], ap_configuration->adm[7]);
Ingo Tuchscherer91f3e3ea2013-11-20 10:47:13 +0100791}
792
793static BUS_ATTR(ap_control_domain_mask, 0444,
794 ap_control_domain_mask_show, NULL);
795
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200796static ssize_t ap_usage_domain_mask_show(struct bus_type *bus, char *buf)
797{
798 if (!ap_configuration) /* QCI not supported */
799 return snprintf(buf, PAGE_SIZE, "not supported\n");
800
801 return snprintf(buf, PAGE_SIZE,
802 "0x%08x%08x%08x%08x%08x%08x%08x%08x\n",
803 ap_configuration->aqm[0], ap_configuration->aqm[1],
804 ap_configuration->aqm[2], ap_configuration->aqm[3],
805 ap_configuration->aqm[4], ap_configuration->aqm[5],
806 ap_configuration->aqm[6], ap_configuration->aqm[7]);
807}
808
809static BUS_ATTR(ap_usage_domain_mask, 0444,
810 ap_usage_domain_mask_show, NULL);
811
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200812static ssize_t ap_config_time_show(struct bus_type *bus, char *buf)
813{
814 return snprintf(buf, PAGE_SIZE, "%d\n", ap_config_time);
815}
816
Felix Beckcb17a632008-12-25 13:38:41 +0100817static ssize_t ap_interrupts_show(struct bus_type *bus, char *buf)
818{
819 return snprintf(buf, PAGE_SIZE, "%d\n",
820 ap_using_interrupts() ? 1 : 0);
821}
822
823static BUS_ATTR(ap_interrupts, 0444, ap_interrupts_show, NULL);
824
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200825static ssize_t ap_config_time_store(struct bus_type *bus,
826 const char *buf, size_t count)
827{
828 int time;
829
830 if (sscanf(buf, "%d\n", &time) != 1 || time < 5 || time > 120)
831 return -EINVAL;
832 ap_config_time = time;
Martin Schwidefskyfcd0d1f2015-07-23 10:55:59 +0200833 mod_timer(&ap_config_timer, jiffies + ap_config_time * HZ);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200834 return count;
835}
836
837static BUS_ATTR(config_time, 0644, ap_config_time_show, ap_config_time_store);
838
839static ssize_t ap_poll_thread_show(struct bus_type *bus, char *buf)
840{
841 return snprintf(buf, PAGE_SIZE, "%d\n", ap_poll_kthread ? 1 : 0);
842}
843
844static ssize_t ap_poll_thread_store(struct bus_type *bus,
845 const char *buf, size_t count)
846{
847 int flag, rc;
848
849 if (sscanf(buf, "%d\n", &flag) != 1)
850 return -EINVAL;
851 if (flag) {
852 rc = ap_poll_thread_start();
853 if (rc)
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200854 count = rc;
855 } else
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200856 ap_poll_thread_stop();
857 return count;
858}
859
860static BUS_ATTR(poll_thread, 0644, ap_poll_thread_show, ap_poll_thread_store);
861
Felix Beckfe137232008-07-14 09:59:08 +0200862static ssize_t poll_timeout_show(struct bus_type *bus, char *buf)
863{
864 return snprintf(buf, PAGE_SIZE, "%llu\n", poll_timeout);
865}
866
867static ssize_t poll_timeout_store(struct bus_type *bus, const char *buf,
868 size_t count)
869{
870 unsigned long long time;
871 ktime_t hr_time;
872
873 /* 120 seconds = maximum poll interval */
Felix Beckcb17a632008-12-25 13:38:41 +0100874 if (sscanf(buf, "%llu\n", &time) != 1 || time < 1 ||
875 time > 120000000000ULL)
Felix Beckfe137232008-07-14 09:59:08 +0200876 return -EINVAL;
877 poll_timeout = time;
Thomas Gleixner8b0e1952016-12-25 12:30:41 +0100878 hr_time = poll_timeout;
Felix Beckfe137232008-07-14 09:59:08 +0200879
Ingo Tuchscherer8cc2af72015-04-28 10:31:44 +0200880 spin_lock_bh(&ap_poll_timer_lock);
881 hrtimer_cancel(&ap_poll_timer);
882 hrtimer_set_expires(&ap_poll_timer, hr_time);
883 hrtimer_start_expires(&ap_poll_timer, HRTIMER_MODE_ABS);
884 spin_unlock_bh(&ap_poll_timer_lock);
885
Felix Beckfe137232008-07-14 09:59:08 +0200886 return count;
887}
888
889static BUS_ATTR(poll_timeout, 0644, poll_timeout_show, poll_timeout_store);
890
Ingo Tuchscherer5bc334b2015-01-23 13:27:04 +0100891static ssize_t ap_max_domain_id_show(struct bus_type *bus, char *buf)
892{
Martin Schwidefsky889875a2015-06-26 16:55:35 +0200893 int max_domain_id;
Ingo Tuchscherer5bc334b2015-01-23 13:27:04 +0100894
Martin Schwidefsky889875a2015-06-26 16:55:35 +0200895 if (ap_configuration)
896 max_domain_id = ap_max_domain_id ? : -1;
897 else
Ingo Tuchscherer5bc334b2015-01-23 13:27:04 +0100898 max_domain_id = 15;
Ingo Tuchscherer5bc334b2015-01-23 13:27:04 +0100899 return snprintf(buf, PAGE_SIZE, "%d\n", max_domain_id);
900}
901
902static BUS_ATTR(ap_max_domain_id, 0444, ap_max_domain_id_show, NULL);
903
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200904static struct bus_attribute *const ap_bus_attrs[] = {
905 &bus_attr_ap_domain,
Ingo Tuchscherer91f3e3ea2013-11-20 10:47:13 +0100906 &bus_attr_ap_control_domain_mask,
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200907 &bus_attr_ap_usage_domain_mask,
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200908 &bus_attr_config_time,
909 &bus_attr_poll_thread,
Felix Beckcb17a632008-12-25 13:38:41 +0100910 &bus_attr_ap_interrupts,
Felix Beckfe137232008-07-14 09:59:08 +0200911 &bus_attr_poll_timeout,
Ingo Tuchscherer5bc334b2015-01-23 13:27:04 +0100912 &bus_attr_ap_max_domain_id,
Felix Beckfe137232008-07-14 09:59:08 +0200913 NULL,
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200914};
915
Holger Dengler75014552012-08-28 16:41:50 +0200916/**
Felix Beck1749a812008-04-17 07:46:28 +0200917 * ap_select_domain(): Select an AP domain.
918 *
919 * Pick one of the 16 AP domains.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200920 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +0100921static int ap_select_domain(void)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200922{
Martin Schwidefsky6acbe212015-06-26 15:40:41 +0200923 int count, max_count, best_domain;
924 struct ap_queue_status status;
925 int i, j;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200926
Felix Beck1749a812008-04-17 07:46:28 +0200927 /*
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200928 * We want to use a single domain. Either the one specified with
929 * the "domain=" parameter or the domain with the maximum number
930 * of devices.
931 */
Ingo Tuchschererfc1d3f02016-08-25 11:11:30 +0200932 spin_lock_bh(&ap_domain_lock);
933 if (ap_domain_index >= 0) {
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200934 /* Domain has already been selected. */
Ingo Tuchschererfc1d3f02016-08-25 11:11:30 +0200935 spin_unlock_bh(&ap_domain_lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200936 return 0;
Ingo Tuchschererfc1d3f02016-08-25 11:11:30 +0200937 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200938 best_domain = -1;
939 max_count = 0;
940 for (i = 0; i < AP_DOMAINS; i++) {
Holger Dengler75014552012-08-28 16:41:50 +0200941 if (!ap_test_config_domain(i))
942 continue;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200943 count = 0;
944 for (j = 0; j < AP_DEVICES; j++) {
Holger Dengler75014552012-08-28 16:41:50 +0200945 if (!ap_test_config_card_id(j))
946 continue;
Tony Krowiake7fc5142016-11-08 07:09:13 +0100947 status = ap_test_queue(AP_MKQID(j, i),
948 ap_apft_available(),
949 NULL);
Martin Schwidefsky6acbe212015-06-26 15:40:41 +0200950 if (status.response_code != AP_RESPONSE_NORMAL)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200951 continue;
952 count++;
953 }
954 if (count > max_count) {
955 max_count = count;
956 best_domain = i;
957 }
958 }
959 if (best_domain >= 0){
960 ap_domain_index = best_domain;
Harald Freudenbergerac994e82017-05-12 16:35:14 +0200961 AP_DBF(DBF_DEBUG, "new ap_domain_index=%d\n", ap_domain_index);
Ingo Tuchschererfc1d3f02016-08-25 11:11:30 +0200962 spin_unlock_bh(&ap_domain_lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200963 return 0;
964 }
Ingo Tuchschererfc1d3f02016-08-25 11:11:30 +0200965 spin_unlock_bh(&ap_domain_lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200966 return -ENODEV;
967}
968
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +0200969/*
Harald Freudenberger9a564102017-10-16 12:28:35 +0200970 * This function checks the type and returns either 0 for not
971 * supported or the highest compatible type value (which may
972 * include the input type value).
973 */
974static int ap_get_compatible_type(ap_qid_t qid, int rawtype, unsigned int func)
975{
976 int comp_type = 0;
977
978 /* < CEX2A is not supported */
979 if (rawtype < AP_DEVICE_TYPE_CEX2A)
980 return 0;
981 /* up to CEX6 known and fully supported */
982 if (rawtype <= AP_DEVICE_TYPE_CEX6)
983 return rawtype;
984 /*
985 * unknown new type > CEX6, check for compatibility
986 * to the highest known and supported type which is
987 * currently CEX6 with the help of the QACT function.
988 */
989 if (ap_qact_available()) {
990 struct ap_queue_status status;
Harald Freudenberger56c5c682017-10-30 12:10:54 +0100991 union ap_qact_ap_info apinfo = {0};
Harald Freudenberger9a564102017-10-16 12:28:35 +0200992
993 apinfo.mode = (func >> 26) & 0x07;
994 apinfo.cat = AP_DEVICE_TYPE_CEX6;
995 status = ap_qact(qid, 0, &apinfo);
996 if (status.response_code == AP_RESPONSE_NORMAL
997 && apinfo.cat >= AP_DEVICE_TYPE_CEX2A
998 && apinfo.cat <= AP_DEVICE_TYPE_CEX6)
999 comp_type = apinfo.cat;
1000 }
1001 if (!comp_type)
1002 AP_DBF(DBF_WARN, "queue=%02x.%04x unable to map type %d\n",
1003 AP_QID_CARD(qid), AP_QID_QUEUE(qid), rawtype);
1004 else if (comp_type != rawtype)
1005 AP_DBF(DBF_INFO, "queue=%02x.%04x map type %d to %d\n",
1006 AP_QID_CARD(qid), AP_QID_QUEUE(qid), rawtype, comp_type);
1007 return comp_type;
1008}
1009
1010/*
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +02001011 * helper function to be used with bus_find_dev
1012 * matches for the card device with the given id
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001013 */
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +02001014static int __match_card_device_with_id(struct device *dev, void *data)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001015{
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +02001016 return is_card_dev(dev) && to_ap_card(dev)->id == (int)(long) data;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001017}
1018
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +02001019/* helper function to be used with bus_find_dev
1020 * matches for the queue device with a given qid
1021 */
1022static int __match_queue_device_with_qid(struct device *dev, void *data)
1023{
1024 return is_queue_dev(dev) && to_ap_queue(dev)->qid == (int)(long) data;
1025}
1026
1027/**
1028 * ap_scan_bus(): Scan the AP bus for new devices
1029 * Runs periodically, workqueue timer (ap_config_time)
1030 */
Al Viro4927b3f2006-12-06 19:18:20 +00001031static void ap_scan_bus(struct work_struct *unused)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001032{
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +02001033 struct ap_queue *aq;
1034 struct ap_card *ac;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001035 struct device *dev;
1036 ap_qid_t qid;
Harald Freudenberger9a564102017-10-16 12:28:35 +02001037 int comp_type, depth = 0, type = 0;
1038 unsigned int func = 0;
Harald Freudenbergerac994e82017-05-12 16:35:14 +02001039 int rc, id, dom, borked, domains, defdomdevs = 0;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001040
Harald Freudenbergercccd85b2016-11-24 06:45:21 +01001041 AP_DBF(DBF_DEBUG, "ap_scan_bus running\n");
1042
Harald Freudenberger050349b2016-11-08 11:54:28 +01001043 ap_query_configuration(ap_configuration);
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +02001044 if (ap_select_domain() != 0)
Martin Schwidefskyfcd0d1f2015-07-23 10:55:59 +02001045 goto out;
Martin Schwidefsky889875a2015-06-26 16:55:35 +02001046
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +02001047 for (id = 0; id < AP_DEVICES; id++) {
1048 /* check if device is registered */
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001049 dev = bus_find_device(&ap_bus_type, NULL,
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +02001050 (void *)(long) id,
1051 __match_card_device_with_id);
1052 ac = dev ? to_ap_card(dev) : NULL;
1053 if (!ap_test_config_card_id(id)) {
1054 if (dev) {
1055 /* Card device has been removed from
1056 * configuration, remove the belonging
1057 * queue devices.
1058 */
1059 bus_for_each_dev(&ap_bus_type, NULL,
1060 (void *)(long) id,
1061 __ap_queue_devices_with_id_unregister);
1062 /* now remove the card device */
Martin Schwidefsky3f3007a2015-09-14 17:01:23 +02001063 device_unregister(dev);
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +02001064 put_device(dev);
1065 }
1066 continue;
1067 }
1068 /* According to the configuration there should be a card
1069 * device, so check if there is at least one valid queue
1070 * and maybe create queue devices and the card device.
1071 */
1072 domains = 0;
1073 for (dom = 0; dom < AP_DOMAINS; dom++) {
1074 qid = AP_MKQID(id, dom);
1075 dev = bus_find_device(&ap_bus_type, NULL,
1076 (void *)(long) qid,
1077 __match_queue_device_with_qid);
1078 aq = dev ? to_ap_queue(dev) : NULL;
1079 if (!ap_test_config_domain(dom)) {
1080 if (dev) {
1081 /* Queue device exists but has been
1082 * removed from configuration.
1083 */
1084 device_unregister(dev);
1085 put_device(dev);
1086 }
Martin Schwidefsky3f3007a2015-09-14 17:01:23 +02001087 continue;
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +02001088 }
Harald Freudenberger9a564102017-10-16 12:28:35 +02001089 rc = ap_query_queue(qid, &depth, &type, &func);
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +02001090 if (dev) {
1091 spin_lock_bh(&aq->lock);
1092 if (rc == -ENODEV ||
1093 /* adapter reconfiguration */
Harald Freudenberger9a564102017-10-16 12:28:35 +02001094 (ac && ac->functions != func))
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +02001095 aq->state = AP_STATE_BORKED;
1096 borked = aq->state == AP_STATE_BORKED;
1097 spin_unlock_bh(&aq->lock);
1098 if (borked) /* Remove broken device */
1099 device_unregister(dev);
1100 put_device(dev);
1101 if (!borked) {
1102 domains++;
Harald Freudenbergerac994e82017-05-12 16:35:14 +02001103 if (dom == ap_domain_index)
1104 defdomdevs++;
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +02001105 continue;
1106 }
1107 }
1108 if (rc)
1109 continue;
Harald Freudenberger9a564102017-10-16 12:28:35 +02001110 /* a new queue device is needed, check out comp type */
1111 comp_type = ap_get_compatible_type(qid, type, func);
1112 if (!comp_type)
1113 continue;
1114 /* maybe a card device needs to be created first */
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +02001115 if (!ac) {
Harald Freudenberger9a564102017-10-16 12:28:35 +02001116 ac = ap_card_create(id, depth, type,
1117 comp_type, func);
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +02001118 if (!ac)
1119 continue;
1120 ac->ap_dev.device.bus = &ap_bus_type;
1121 ac->ap_dev.device.parent = ap_root_device;
1122 dev_set_name(&ac->ap_dev.device,
1123 "card%02x", id);
1124 /* Register card with AP bus */
1125 rc = device_register(&ac->ap_dev.device);
1126 if (rc) {
1127 put_device(&ac->ap_dev.device);
1128 ac = NULL;
1129 break;
1130 }
1131 /* get it and thus adjust reference counter */
1132 get_device(&ac->ap_dev.device);
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +02001133 }
1134 /* now create the new queue device */
Harald Freudenberger9a564102017-10-16 12:28:35 +02001135 aq = ap_queue_create(qid, comp_type);
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +02001136 if (!aq)
1137 continue;
1138 aq->card = ac;
1139 aq->ap_dev.device.bus = &ap_bus_type;
1140 aq->ap_dev.device.parent = &ac->ap_dev.device;
1141 dev_set_name(&aq->ap_dev.device,
1142 "%02x.%04x", id, dom);
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +02001143 /* Start with a device reset */
1144 spin_lock_bh(&aq->lock);
1145 ap_wait(ap_sm_event(aq, AP_EVENT_POLL));
1146 spin_unlock_bh(&aq->lock);
1147 /* Register device */
1148 rc = device_register(&aq->ap_dev.device);
1149 if (rc) {
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +02001150 put_device(&aq->ap_dev.device);
1151 continue;
1152 }
1153 domains++;
Harald Freudenbergerac994e82017-05-12 16:35:14 +02001154 if (dom == ap_domain_index)
1155 defdomdevs++;
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +02001156 } /* end domain loop */
1157 if (ac) {
1158 /* remove card dev if there are no queue devices */
1159 if (!domains)
1160 device_unregister(&ac->ap_dev.device);
1161 put_device(&ac->ap_dev.device);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001162 }
Ingo Tuchscherere28d2af2016-08-25 11:16:03 +02001163 } /* end device loop */
Harald Freudenbergerac994e82017-05-12 16:35:14 +02001164
1165 if (defdomdevs < 1)
1166 AP_DBF(DBF_INFO, "no queue device with default domain %d available\n",
1167 ap_domain_index);
1168
Martin Schwidefskyfcd0d1f2015-07-23 10:55:59 +02001169out:
1170 mod_timer(&ap_config_timer, jiffies + ap_config_time * HZ);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001171}
1172
Kees Cookcefbeb52017-10-25 03:27:37 -07001173static void ap_config_timeout(struct timer_list *unused)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001174{
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +02001175 if (ap_suspend_flag)
1176 return;
Martin Schwidefsky8139b892015-07-27 12:47:40 +02001177 queue_work(system_long_wq, &ap_scan_work);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001178}
1179
Harald Freudenbergerefda7ad2018-04-04 07:14:17 +02001180static int __init ap_debug_init(void)
Harald Freudenbergercccd85b2016-11-24 06:45:21 +01001181{
Harald Freudenbergercccd85b2016-11-24 06:45:21 +01001182 ap_dbf_info = debug_register("ap", 1, 1,
1183 DBF_MAX_SPRINTF_ARGS * sizeof(long));
1184 debug_register_view(ap_dbf_info, &debug_sprintf_view);
1185 debug_set_level(ap_dbf_info, DBF_ERR);
1186
1187 return 0;
1188}
1189
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001190/**
Felix Beck1749a812008-04-17 07:46:28 +02001191 * ap_module_init(): The module initialization code.
1192 *
1193 * Initializes the module.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001194 */
Harald Freudenbergerefda7ad2018-04-04 07:14:17 +02001195static int __init ap_module_init(void)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001196{
Martin Schwidefsky889875a2015-06-26 16:55:35 +02001197 int max_domain_id;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001198 int rc, i;
1199
Harald Freudenbergercccd85b2016-11-24 06:45:21 +01001200 rc = ap_debug_init();
1201 if (rc)
1202 return rc;
1203
Harald Freudenberger23951032018-08-09 11:59:34 +02001204 if (!ap_instructions_available()) {
Martin Schwidefsky889875a2015-06-26 16:55:35 +02001205 pr_warn("The hardware system does not support AP instructions\n");
1206 return -ENODEV;
1207 }
1208
1209 /* Get AP configuration data if available */
1210 ap_init_configuration();
1211
1212 if (ap_configuration)
Harald Freudenbergerac994e82017-05-12 16:35:14 +02001213 max_domain_id =
1214 ap_max_domain_id ? ap_max_domain_id : AP_DOMAINS - 1;
Martin Schwidefsky889875a2015-06-26 16:55:35 +02001215 else
1216 max_domain_id = 15;
1217 if (ap_domain_index < -1 || ap_domain_index > max_domain_id) {
1218 pr_warn("%d is not a valid cryptographic domain\n",
1219 ap_domain_index);
Harald Freudenbergerac994e82017-05-12 16:35:14 +02001220 ap_domain_index = -1;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001221 }
Felix Beck5314af62009-09-22 22:58:51 +02001222 /* In resume callback we need to know if the user had set the domain.
1223 * If so, we can not just reset it.
1224 */
1225 if (ap_domain_index >= 0)
1226 user_set_domain = 1;
1227
Felix Beckcb17a632008-12-25 13:38:41 +01001228 if (ap_interrupts_available()) {
Martin Schwidefskyf4eae942013-06-24 10:30:41 +02001229 rc = register_adapter_interrupt(&ap_airq);
1230 ap_airq_flag = (rc == 0);
Felix Beckcb17a632008-12-25 13:38:41 +01001231 }
1232
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001233 /* Create /sys/bus/ap. */
1234 rc = bus_register(&ap_bus_type);
1235 if (rc)
1236 goto out;
1237 for (i = 0; ap_bus_attrs[i]; i++) {
1238 rc = bus_create_file(&ap_bus_type, ap_bus_attrs[i]);
1239 if (rc)
1240 goto out_bus;
1241 }
1242
1243 /* Create /sys/devices/ap. */
Mark McLoughlin035da162008-12-15 12:58:29 +00001244 ap_root_device = root_device_register("ap");
Gustavo A. R. Silva9c705202018-07-18 23:42:05 -05001245 rc = PTR_ERR_OR_ZERO(ap_root_device);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001246 if (rc)
1247 goto out_bus;
1248
Felix Beck1749a812008-04-17 07:46:28 +02001249 /* Setup the AP bus rescan timer. */
Kees Cookcefbeb52017-10-25 03:27:37 -07001250 timer_setup(&ap_config_timer, ap_config_timeout, 0);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001251
Martin Schwidefsky3f3007a2015-09-14 17:01:23 +02001252 /*
1253 * Setup the high resultion poll timer.
Felix Beckfe137232008-07-14 09:59:08 +02001254 * If we are running under z/VM adjust polling to z/VM polling rate.
1255 */
1256 if (MACHINE_IS_VM)
1257 poll_timeout = 1500000;
Felix Beck93521312009-12-07 12:52:00 +01001258 spin_lock_init(&ap_poll_timer_lock);
Felix Beckfe137232008-07-14 09:59:08 +02001259 hrtimer_init(&ap_poll_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
1260 ap_poll_timer.function = ap_poll_timeout;
1261
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001262 /* Start the low priority AP bus poll thread. */
1263 if (ap_thread_flag) {
1264 rc = ap_poll_thread_start();
1265 if (rc)
1266 goto out_work;
1267 }
1268
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +02001269 rc = register_pm_notifier(&ap_power_notifier);
1270 if (rc)
1271 goto out_pm;
1272
Martin Schwidefsky8139b892015-07-27 12:47:40 +02001273 queue_work(system_long_wq, &ap_scan_work);
Sascha Silbee3877532015-10-27 18:29:52 +01001274 initialised = true;
Martin Schwidefsky3f3007a2015-09-14 17:01:23 +02001275
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001276 return 0;
1277
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +02001278out_pm:
1279 ap_poll_thread_stop();
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001280out_work:
Felix Beckfe137232008-07-14 09:59:08 +02001281 hrtimer_cancel(&ap_poll_timer);
Mark McLoughlin035da162008-12-15 12:58:29 +00001282 root_device_unregister(ap_root_device);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001283out_bus:
1284 while (i--)
1285 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
1286 bus_unregister(&ap_bus_type);
1287out:
Martin Schwidefskyf4eae942013-06-24 10:30:41 +02001288 if (ap_using_interrupts())
1289 unregister_adapter_interrupt(&ap_airq);
Martin Schwidefsky889875a2015-06-26 16:55:35 +02001290 kfree(ap_configuration);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001291 return rc;
1292}
Paul Gortmaker50a0d462017-02-09 09:48:10 -05001293device_initcall(ap_module_init);