blob: ba1f806051b72babb00ca178a4b0e3c85932185d [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>
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +020040#include <linux/suspend.h>
Ralph Wuerthner85eca852006-12-08 15:54:07 +010041#include <asm/reset.h>
Felix Beckcb17a632008-12-25 13:38:41 +010042#include <asm/airq.h>
Arun Sharma600634972011-07-26 16:09:06 -070043#include <linux/atomic.h>
Felix Beckcb17a632008-12-25 13:38:41 +010044#include <asm/isc.h>
Felix Beckfe137232008-07-14 09:59:08 +020045#include <linux/hrtimer.h>
46#include <linux/ktime.h>
David Howellsa0616cd2012-03-28 18:30:02 +010047#include <asm/facility.h>
Kees Cook5d26a102014-11-20 17:05:53 -080048#include <linux/crypto.h>
Martin Schwidefsky1534c382006-09-20 15:58:25 +020049
50#include "ap_bus.h"
51
52/* Some prototypes. */
Al Viro4927b3f2006-12-06 19:18:20 +000053static void ap_scan_bus(struct work_struct *);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020054static void ap_poll_all(unsigned long);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +020055static void ap_request_timeout(unsigned long);
Felix Beck772f5472009-06-22 12:08:16 +020056static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags);
57static int ap_device_remove(struct device *dev);
58static int ap_device_probe(struct device *dev);
Martin Schwidefskyf4eae942013-06-24 10:30:41 +020059static void ap_interrupt_handler(struct airq_struct *airq);
Ingo Tuchschererc50a1602015-06-17 16:19:15 +020060static void ap_reset(struct ap_device *ap_dev, unsigned long *flags);
Felix Beck5314af62009-09-22 22:58:51 +020061static int ap_select_domain(void);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020062
Felix Beck1749a812008-04-17 07:46:28 +020063/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +020064 * Module description.
65 */
66MODULE_AUTHOR("IBM Corporation");
Holger Dengler75014552012-08-28 16:41:50 +020067MODULE_DESCRIPTION("Adjunct Processor Bus driver, " \
68 "Copyright IBM Corp. 2006, 2012");
Martin Schwidefsky1534c382006-09-20 15:58:25 +020069MODULE_LICENSE("GPL");
Kees Cook5d26a102014-11-20 17:05:53 -080070MODULE_ALIAS_CRYPTO("z90crypt");
Martin Schwidefsky1534c382006-09-20 15:58:25 +020071
Felix Beck1749a812008-04-17 07:46:28 +020072/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +020073 * Module parameter
74 */
75int ap_domain_index = -1; /* Adjunct Processor Domain Index */
Michael Veigelc1a42f42014-04-14 14:28:27 +020076module_param_named(domain, ap_domain_index, int, S_IRUSR|S_IRGRP);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020077MODULE_PARM_DESC(domain, "domain index for ap devices");
78EXPORT_SYMBOL(ap_domain_index);
79
Felix Beckb90b34c2008-02-09 18:24:30 +010080static int ap_thread_flag = 0;
Michael Veigelc1a42f42014-04-14 14:28:27 +020081module_param_named(poll_thread, ap_thread_flag, int, S_IRUSR|S_IRGRP);
Felix Beckb90b34c2008-02-09 18:24:30 +010082MODULE_PARM_DESC(poll_thread, "Turn on/off poll thread, default is 0 (off).");
Martin Schwidefsky1534c382006-09-20 15:58:25 +020083
84static struct device *ap_root_device = NULL;
Holger Dengler75014552012-08-28 16:41:50 +020085static struct ap_config_info *ap_configuration;
Christian Maaser43c207e62008-12-25 13:38:42 +010086static DEFINE_SPINLOCK(ap_device_list_lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +010087static LIST_HEAD(ap_device_list);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020088
Felix Beck1749a812008-04-17 07:46:28 +020089/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +020090 * Workqueue & timer for bus rescan.
91 */
92static struct workqueue_struct *ap_work_queue;
93static struct timer_list ap_config_timer;
94static int ap_config_time = AP_CONFIG_TIME;
Al Viro4927b3f2006-12-06 19:18:20 +000095static DECLARE_WORK(ap_config_work, ap_scan_bus);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020096
Felix Beck1749a812008-04-17 07:46:28 +020097/*
Felix Beckcb17a632008-12-25 13:38:41 +010098 * Tasklet & timer for AP request polling and interrupts
Martin Schwidefsky1534c382006-09-20 15:58:25 +020099 */
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200100static DECLARE_TASKLET(ap_tasklet, ap_poll_all, 0);
101static atomic_t ap_poll_requests = ATOMIC_INIT(0);
102static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait);
103static struct task_struct *ap_poll_kthread = NULL;
104static DEFINE_MUTEX(ap_poll_thread_mutex);
Felix Beck93521312009-12-07 12:52:00 +0100105static DEFINE_SPINLOCK(ap_poll_timer_lock);
Felix Beckfe137232008-07-14 09:59:08 +0200106static struct hrtimer ap_poll_timer;
107/* In LPAR poll with 4kHz frequency. Poll every 250000 nanoseconds.
108 * If z/VM change to 1500000 nanoseconds to adjust to z/VM polling.*/
109static unsigned long long poll_timeout = 250000;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200110
Felix Beck772f5472009-06-22 12:08:16 +0200111/* Suspend flag */
112static int ap_suspend_flag;
Martin Schwidefsky889875a2015-06-26 16:55:35 +0200113/* Maximum domain id */
114static int ap_max_domain_id;
Felix Beck5314af62009-09-22 22:58:51 +0200115/* Flag to check if domain was set through module parameter domain=. This is
116 * important when supsend and resume is done in a z/VM environment where the
117 * domain might change. */
118static int user_set_domain = 0;
Felix Beck772f5472009-06-22 12:08:16 +0200119static struct bus_type ap_bus_type;
120
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200121/* Adapter interrupt definitions */
122static int ap_airq_flag;
123
124static struct airq_struct ap_airq = {
125 .handler = ap_interrupt_handler,
126 .isc = AP_ISC,
127};
128
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200129/**
Felix Beckcb17a632008-12-25 13:38:41 +0100130 * ap_using_interrupts() - Returns non-zero if interrupt support is
131 * available.
132 */
133static inline int ap_using_interrupts(void)
134{
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200135 return ap_airq_flag;
Felix Beckcb17a632008-12-25 13:38:41 +0100136}
137
138/**
Felix Beck1749a812008-04-17 07:46:28 +0200139 * ap_intructions_available() - Test if AP instructions are available.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200140 *
Felix Beck1749a812008-04-17 07:46:28 +0200141 * Returns 0 if the AP instructions are installed.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200142 */
143static inline int ap_instructions_available(void)
144{
145 register unsigned long reg0 asm ("0") = AP_MKQID(0,0);
146 register unsigned long reg1 asm ("1") = -ENODEV;
147 register unsigned long reg2 asm ("2") = 0UL;
148
149 asm volatile(
150 " .long 0xb2af0000\n" /* PQAP(TAPQ) */
151 "0: la %1,0\n"
152 "1:\n"
153 EX_TABLE(0b, 1b)
154 : "+d" (reg0), "+d" (reg1), "+d" (reg2) : : "cc" );
155 return reg1;
156}
157
158/**
Felix Beckcb17a632008-12-25 13:38:41 +0100159 * ap_interrupts_available(): Test if AP interrupts are available.
160 *
161 * Returns 1 if AP interrupts are available.
162 */
163static int ap_interrupts_available(void)
164{
Heiko Carstens86cd7412015-02-14 11:23:21 +0100165 return test_facility(65);
Felix Beckcb17a632008-12-25 13:38:41 +0100166}
167
168/**
Holger Dengler75014552012-08-28 16:41:50 +0200169 * ap_configuration_available(): Test if AP configuration
170 * information is available.
171 *
172 * Returns 1 if AP configuration information is available.
173 */
174static int ap_configuration_available(void)
175{
Heiko Carstens86cd7412015-02-14 11:23:21 +0100176 return test_facility(12);
Holger Dengler75014552012-08-28 16:41:50 +0200177}
178
179/**
Felix Beck1749a812008-04-17 07:46:28 +0200180 * ap_test_queue(): Test adjunct processor queue.
181 * @qid: The AP queue number
Martin Schwidefsky6acbe212015-06-26 15:40:41 +0200182 * @info: Pointer to queue descriptor
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200183 *
Felix Beck1749a812008-04-17 07:46:28 +0200184 * Returns AP queue status structure.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200185 */
186static inline struct ap_queue_status
Martin Schwidefsky6acbe212015-06-26 15:40:41 +0200187ap_test_queue(ap_qid_t qid, unsigned long *info)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200188{
189 register unsigned long reg0 asm ("0") = qid;
190 register struct ap_queue_status reg1 asm ("1");
191 register unsigned long reg2 asm ("2") = 0UL;
192
Martin Schwidefsky6acbe212015-06-26 15:40:41 +0200193 if (test_facility(15))
194 reg0 |= 1UL << 23; /* set APFT T bit*/
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200195 asm volatile(".long 0xb2af0000" /* PQAP(TAPQ) */
196 : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
Martin Schwidefsky6acbe212015-06-26 15:40:41 +0200197 if (info)
198 *info = reg2;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200199 return reg1;
200}
201
202/**
Felix Beck1749a812008-04-17 07:46:28 +0200203 * ap_reset_queue(): Reset adjunct processor queue.
204 * @qid: The AP queue number
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200205 *
Felix Beck1749a812008-04-17 07:46:28 +0200206 * Returns AP queue status structure.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200207 */
208static inline struct ap_queue_status ap_reset_queue(ap_qid_t qid)
209{
210 register unsigned long reg0 asm ("0") = qid | 0x01000000UL;
211 register struct ap_queue_status reg1 asm ("1");
212 register unsigned long reg2 asm ("2") = 0UL;
213
214 asm volatile(
215 ".long 0xb2af0000" /* PQAP(RAPQ) */
216 : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
217 return reg1;
218}
219
Felix Beckcb17a632008-12-25 13:38:41 +0100220/**
221 * ap_queue_interruption_control(): Enable interruption for a specific AP.
222 * @qid: The AP queue number
223 * @ind: The notification indicator byte
224 *
225 * Returns AP queue status.
226 */
227static inline struct ap_queue_status
228ap_queue_interruption_control(ap_qid_t qid, void *ind)
229{
230 register unsigned long reg0 asm ("0") = qid | 0x03000000UL;
231 register unsigned long reg1_in asm ("1") = 0x0000800000000000UL | AP_ISC;
232 register struct ap_queue_status reg1_out asm ("1");
233 register void *reg2 asm ("2") = ind;
234 asm volatile(
Holger Denglera7475af2012-05-16 14:10:26 +0200235 ".long 0xb2af0000" /* PQAP(AQIC) */
Felix Beckcb17a632008-12-25 13:38:41 +0100236 : "+d" (reg0), "+d" (reg1_in), "=d" (reg1_out), "+d" (reg2)
237 :
238 : "cc" );
239 return reg1_out;
240}
Felix Beckcb17a632008-12-25 13:38:41 +0100241
Martin Schwidefsky889875a2015-06-26 16:55:35 +0200242/**
243 * ap_query_configuration(): Get AP configuration data
244 *
245 * Returns 0 on success, or -EOPNOTSUPP.
246 */
247static inline int ap_query_configuration(void)
Holger Dengler75014552012-08-28 16:41:50 +0200248{
249 register unsigned long reg0 asm ("0") = 0x04000000UL;
250 register unsigned long reg1 asm ("1") = -EINVAL;
Martin Schwidefsky889875a2015-06-26 16:55:35 +0200251 register void *reg2 asm ("2") = (void *) ap_configuration;
Holger Dengler75014552012-08-28 16:41:50 +0200252
Martin Schwidefsky889875a2015-06-26 16:55:35 +0200253 if (!ap_configuration)
254 return -EOPNOTSUPP;
Holger Dengler75014552012-08-28 16:41:50 +0200255 asm volatile(
256 ".long 0xb2af0000\n" /* PQAP(QCI) */
257 "0: la %1,0\n"
258 "1:\n"
259 EX_TABLE(0b, 1b)
260 : "+d" (reg0), "+d" (reg1), "+d" (reg2)
261 :
262 : "cc");
263
264 return reg1;
265}
Holger Dengler75014552012-08-28 16:41:50 +0200266
Holger Dengler6bed05b2011-07-24 10:48:25 +0200267/**
Martin Schwidefsky889875a2015-06-26 16:55:35 +0200268 * ap_init_configuration(): Allocate and query configuration array.
269 */
270static void ap_init_configuration(void)
271{
272 if (!ap_configuration_available())
273 return;
274
275 ap_configuration = kzalloc(sizeof(*ap_configuration), GFP_KERNEL);
276 if (!ap_configuration)
277 return;
278 if (ap_query_configuration() != 0) {
279 kfree(ap_configuration);
280 ap_configuration = NULL;
281 return;
282 }
283}
284
285/*
286 * ap_test_config(): helper function to extract the nrth bit
287 * within the unsigned int array field.
288 */
289static inline int ap_test_config(unsigned int *field, unsigned int nr)
290{
291 return ap_test_bit((field + (nr >> 5)), (nr & 0x1f));
292}
293
294/*
295 * ap_test_config_card_id(): Test, whether an AP card ID is configured.
296 * @id AP card ID
297 *
298 * Returns 0 if the card is not configured
299 * 1 if the card is configured or
300 * if the configuration information is not available
301 */
302static inline int ap_test_config_card_id(unsigned int id)
303{
304 if (!ap_configuration) /* QCI not supported */
305 return 1;
306 return ap_test_config(ap_configuration->apm, id);
307}
308
309/*
310 * ap_test_config_domain(): Test, whether an AP usage domain is configured.
311 * @domain AP usage domain ID
312 *
313 * Returns 0 if the usage domain is not configured
314 * 1 if the usage domain is configured or
315 * if the configuration information is not available
316 */
317static inline int ap_test_config_domain(unsigned int domain)
318{
319 if (!ap_configuration) /* QCI not supported */
320 return domain < 16;
321 return ap_test_config(ap_configuration->aqm, domain);
322}
323
324/**
Felix Beckcb17a632008-12-25 13:38:41 +0100325 * ap_queue_enable_interruption(): Enable interruption on an AP.
326 * @qid: The AP queue number
327 * @ind: the notification indicator byte
328 *
329 * Enables interruption on AP queue via ap_queue_interruption_control(). Based
330 * on the return value it waits a while and tests the AP queue if interrupts
331 * have been switched on using ap_test_queue().
332 */
Ingo Tuchschererc50a1602015-06-17 16:19:15 +0200333static int ap_queue_enable_interruption(struct ap_device *ap_dev, void *ind)
Felix Beckcb17a632008-12-25 13:38:41 +0100334{
Felix Beckcb17a632008-12-25 13:38:41 +0100335 struct ap_queue_status status;
Felix Beckcb17a632008-12-25 13:38:41 +0100336
Ingo Tuchschererc50a1602015-06-17 16:19:15 +0200337 status = ap_queue_interruption_control(ap_dev->qid, ind);
338 switch (status.response_code) {
339 case AP_RESPONSE_NORMAL:
340 case AP_RESPONSE_OTHERWISE_CHANGED:
341 return 0;
342 case AP_RESPONSE_Q_NOT_AVAIL:
343 case AP_RESPONSE_DECONFIGURED:
344 case AP_RESPONSE_CHECKSTOPPED:
345 case AP_RESPONSE_INVALID_ADDRESS:
346 return -ENODEV;
347 case AP_RESPONSE_RESET_IN_PROGRESS:
348 case AP_RESPONSE_BUSY:
349 default:
350 return -EBUSY;
Felix Beckcb17a632008-12-25 13:38:41 +0100351 }
Felix Beckcb17a632008-12-25 13:38:41 +0100352}
353
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200354/**
Felix Beck1749a812008-04-17 07:46:28 +0200355 * __ap_send(): Send message to adjunct processor queue.
356 * @qid: The AP queue number
357 * @psmid: The program supplied message identifier
358 * @msg: The message text
359 * @length: The message length
Felix Becka6a5d732009-12-07 12:51:55 +0100360 * @special: Special Bit
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200361 *
Felix Beck1749a812008-04-17 07:46:28 +0200362 * Returns AP queue status structure.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200363 * Condition code 1 on NQAP can't happen because the L bit is 1.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200364 * Condition code 2 on NQAP also means the send is incomplete,
365 * because a segment boundary was reached. The NQAP is repeated.
366 */
367static inline struct ap_queue_status
Felix Becka6a5d732009-12-07 12:51:55 +0100368__ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length,
369 unsigned int special)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200370{
371 typedef struct { char _[length]; } msgblock;
372 register unsigned long reg0 asm ("0") = qid | 0x40000000UL;
373 register struct ap_queue_status reg1 asm ("1");
374 register unsigned long reg2 asm ("2") = (unsigned long) msg;
375 register unsigned long reg3 asm ("3") = (unsigned long) length;
376 register unsigned long reg4 asm ("4") = (unsigned int) (psmid >> 32);
Heiko Carstens7d6c3b42013-09-07 11:07:22 +0200377 register unsigned long reg5 asm ("5") = psmid & 0xffffffff;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200378
Felix Becka6a5d732009-12-07 12:51:55 +0100379 if (special == 1)
380 reg0 |= 0x400000UL;
381
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200382 asm volatile (
Holger Denglera7475af2012-05-16 14:10:26 +0200383 "0: .long 0xb2ad0042\n" /* NQAP */
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200384 " brc 2,0b"
385 : "+d" (reg0), "=d" (reg1), "+d" (reg2), "+d" (reg3)
386 : "d" (reg4), "d" (reg5), "m" (*(msgblock *) msg)
387 : "cc" );
388 return reg1;
389}
390
391int ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length)
392{
393 struct ap_queue_status status;
394
Felix Becka6a5d732009-12-07 12:51:55 +0100395 status = __ap_send(qid, psmid, msg, length, 0);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200396 switch (status.response_code) {
397 case AP_RESPONSE_NORMAL:
398 return 0;
399 case AP_RESPONSE_Q_FULL:
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200400 case AP_RESPONSE_RESET_IN_PROGRESS:
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200401 return -EBUSY;
Felix Becka6a5d732009-12-07 12:51:55 +0100402 case AP_RESPONSE_REQ_FAC_NOT_INST:
403 return -EINVAL;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200404 default: /* Device is gone. */
405 return -ENODEV;
406 }
407}
408EXPORT_SYMBOL(ap_send);
409
Felix Beck1749a812008-04-17 07:46:28 +0200410/**
411 * __ap_recv(): Receive message from adjunct processor queue.
412 * @qid: The AP queue number
413 * @psmid: Pointer to program supplied message identifier
414 * @msg: The message text
415 * @length: The message length
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200416 *
Felix Beck1749a812008-04-17 07:46:28 +0200417 * Returns AP queue status structure.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200418 * Condition code 1 on DQAP means the receive has taken place
419 * but only partially. The response is incomplete, hence the
420 * DQAP is repeated.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200421 * Condition code 2 on DQAP also means the receive is incomplete,
422 * this time because a segment boundary was reached. Again, the
423 * DQAP is repeated.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200424 * Note that gpr2 is used by the DQAP instruction to keep track of
425 * any 'residual' length, in case the instruction gets interrupted.
426 * Hence it gets zeroed before the instruction.
427 */
428static inline struct ap_queue_status
429__ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length)
430{
431 typedef struct { char _[length]; } msgblock;
432 register unsigned long reg0 asm("0") = qid | 0x80000000UL;
433 register struct ap_queue_status reg1 asm ("1");
434 register unsigned long reg2 asm("2") = 0UL;
435 register unsigned long reg4 asm("4") = (unsigned long) msg;
436 register unsigned long reg5 asm("5") = (unsigned long) length;
437 register unsigned long reg6 asm("6") = 0UL;
438 register unsigned long reg7 asm("7") = 0UL;
439
440
441 asm volatile(
Holger Denglera7475af2012-05-16 14:10:26 +0200442 "0: .long 0xb2ae0064\n" /* DQAP */
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200443 " brc 6,0b\n"
444 : "+d" (reg0), "=d" (reg1), "+d" (reg2),
445 "+d" (reg4), "+d" (reg5), "+d" (reg6), "+d" (reg7),
446 "=m" (*(msgblock *) msg) : : "cc" );
447 *psmid = (((unsigned long long) reg6) << 32) + reg7;
448 return reg1;
449}
450
451int ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length)
452{
453 struct ap_queue_status status;
454
455 status = __ap_recv(qid, psmid, msg, length);
456 switch (status.response_code) {
457 case AP_RESPONSE_NORMAL:
458 return 0;
459 case AP_RESPONSE_NO_PENDING_REPLY:
460 if (status.queue_empty)
461 return -ENOENT;
462 return -EBUSY;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200463 case AP_RESPONSE_RESET_IN_PROGRESS:
464 return -EBUSY;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200465 default:
466 return -ENODEV;
467 }
468}
469EXPORT_SYMBOL(ap_recv);
470
471/**
Ingo Tuchschererc50a1602015-06-17 16:19:15 +0200472 * __ap_schedule_poll_timer(): Schedule poll timer.
473 *
474 * Set up the timer to run the poll tasklet
475 */
476static inline void __ap_schedule_poll_timer(void)
477{
478 ktime_t hr_time;
479
480 spin_lock_bh(&ap_poll_timer_lock);
481 if (!hrtimer_is_queued(&ap_poll_timer) && !ap_suspend_flag) {
482 hr_time = ktime_set(0, poll_timeout);
483 hrtimer_forward_now(&ap_poll_timer, hr_time);
484 hrtimer_restart(&ap_poll_timer);
485 }
486 spin_unlock_bh(&ap_poll_timer_lock);
487}
488
489/**
490 * ap_schedule_poll_timer(): Schedule poll timer.
491 *
492 * Set up the timer to run the poll tasklet
493 */
494static inline void ap_schedule_poll_timer(void)
495{
496 if (ap_using_interrupts())
497 return;
498 __ap_schedule_poll_timer();
499}
500
501
502/**
Felix Beck1749a812008-04-17 07:46:28 +0200503 * ap_query_queue(): Check if an AP queue is available.
504 * @qid: The AP queue number
505 * @queue_depth: Pointer to queue depth value
506 * @device_type: Pointer to device type value
Martin Schwidefsky6acbe212015-06-26 15:40:41 +0200507 * @facilities: Pointer to facility indicator
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200508 */
Martin Schwidefsky6acbe212015-06-26 15:40:41 +0200509static int ap_query_queue(ap_qid_t qid, int *queue_depth, int *device_type,
510 unsigned int *facilities)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200511{
512 struct ap_queue_status status;
Martin Schwidefsky6acbe212015-06-26 15:40:41 +0200513 unsigned long info;
Martin Schwidefsky889875a2015-06-26 16:55:35 +0200514 int nd;
515
516 if (!ap_test_config_card_id(AP_QID_DEVICE(qid)))
517 return -ENODEV;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200518
Martin Schwidefsky6acbe212015-06-26 15:40:41 +0200519 status = ap_test_queue(qid, &info);
Ingo Tuchschererc50a1602015-06-17 16:19:15 +0200520 switch (status.response_code) {
521 case AP_RESPONSE_NORMAL:
Martin Schwidefsky6acbe212015-06-26 15:40:41 +0200522 *queue_depth = (int)(info & 0xff);
523 *device_type = (int)((info >> 24) & 0xff);
524 *facilities = (unsigned int)(info >> 32);
Martin Schwidefsky889875a2015-06-26 16:55:35 +0200525 /* Update maximum domain id */
526 nd = (info >> 16) & 0xff;
527 if ((info & (1UL << 57)) && nd > 0)
528 ap_max_domain_id = nd;
Ingo Tuchschererc50a1602015-06-17 16:19:15 +0200529 return 0;
530 case AP_RESPONSE_Q_NOT_AVAIL:
531 case AP_RESPONSE_DECONFIGURED:
532 case AP_RESPONSE_CHECKSTOPPED:
533 case AP_RESPONSE_INVALID_ADDRESS:
534 return -ENODEV;
535 case AP_RESPONSE_RESET_IN_PROGRESS:
536 case AP_RESPONSE_OTHERWISE_CHANGED:
537 case AP_RESPONSE_BUSY:
538 return -EBUSY;
539 default:
540 BUG();
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200541 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200542}
543
544/**
Felix Beck1749a812008-04-17 07:46:28 +0200545 * ap_init_queue(): Reset an AP queue.
546 * @qid: The AP queue number
547 *
Ingo Tuchschererc50a1602015-06-17 16:19:15 +0200548 * Submit the Reset command to an AP queue.
549 * Since the reset is asynchron set the state to 'RESET_IN_PROGRESS'
550 * and check later via ap_poll_queue() if the reset is done.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200551 */
Ingo Tuchschererc50a1602015-06-17 16:19:15 +0200552static int ap_init_queue(struct ap_device *ap_dev)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200553{
554 struct ap_queue_status status;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200555
Ingo Tuchschererc50a1602015-06-17 16:19:15 +0200556 status = ap_reset_queue(ap_dev->qid);
557 switch (status.response_code) {
558 case AP_RESPONSE_NORMAL:
559 ap_dev->interrupt = AP_INTR_DISABLED;
560 ap_dev->reset = AP_RESET_IN_PROGRESS;
561 return 0;
562 case AP_RESPONSE_RESET_IN_PROGRESS:
563 case AP_RESPONSE_BUSY:
564 return -EBUSY;
565 case AP_RESPONSE_Q_NOT_AVAIL:
566 case AP_RESPONSE_DECONFIGURED:
567 case AP_RESPONSE_CHECKSTOPPED:
568 default:
569 return -ENODEV;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200570 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200571}
572
573/**
Felix Beck1749a812008-04-17 07:46:28 +0200574 * ap_increase_queue_count(): Arm request timeout.
575 * @ap_dev: Pointer to an AP device.
576 *
577 * Arm request timeout if an AP device was idle and a new request is submitted.
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200578 */
579static void ap_increase_queue_count(struct ap_device *ap_dev)
580{
581 int timeout = ap_dev->drv->request_timeout;
582
583 ap_dev->queue_count++;
584 if (ap_dev->queue_count == 1) {
585 mod_timer(&ap_dev->timeout, jiffies + timeout);
586 ap_dev->reset = AP_RESET_ARMED;
587 }
588}
589
590/**
Felix Beck1749a812008-04-17 07:46:28 +0200591 * ap_decrease_queue_count(): Decrease queue count.
592 * @ap_dev: Pointer to an AP device.
593 *
594 * If AP device is still alive, re-schedule request timeout if there are still
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200595 * pending requests.
596 */
597static void ap_decrease_queue_count(struct ap_device *ap_dev)
598{
599 int timeout = ap_dev->drv->request_timeout;
600
601 ap_dev->queue_count--;
602 if (ap_dev->queue_count > 0)
603 mod_timer(&ap_dev->timeout, jiffies + timeout);
604 else
Felix Beck1749a812008-04-17 07:46:28 +0200605 /*
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200606 * The timeout timer should to be disabled now - since
607 * del_timer_sync() is very expensive, we just tell via the
608 * reset flag to ignore the pending timeout timer.
609 */
610 ap_dev->reset = AP_RESET_IGNORE;
611}
612
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200613/**
614 * ap_poll_thread(): Thread that polls for finished requests.
615 * @data: Unused pointer
616 *
617 * AP bus poll thread. The purpose of this thread is to poll for
618 * finished requests in a loop if there is a "free" cpu - that is
619 * a cpu that doesn't have anything better to do. The polling stops
620 * as soon as there is another task or if all messages have been
621 * delivered.
622 */
623static int ap_poll_thread(void *data)
624{
625 DECLARE_WAITQUEUE(wait, current);
626 unsigned long flags;
627 struct ap_device *ap_dev;
628
629 set_user_nice(current, MAX_NICE);
630 set_freezable();
631 while (!kthread_should_stop()) {
632 add_wait_queue(&ap_poll_wait, &wait);
633 set_current_state(TASK_INTERRUPTIBLE);
634 if (ap_suspend_flag ||
635 atomic_read(&ap_poll_requests) <= 0) {
636 schedule();
637 try_to_freeze();
638 }
639 set_current_state(TASK_RUNNING);
640 remove_wait_queue(&ap_poll_wait, &wait);
641
642 if (need_resched()) {
643 schedule();
644 try_to_freeze();
645 continue;
646 }
647
648 flags = 0;
649 spin_lock_bh(&ap_device_list_lock);
650 list_for_each_entry(ap_dev, &ap_device_list, list) {
651 spin_lock(&ap_dev->lock);
652 __ap_poll_device(ap_dev, &flags);
653 spin_unlock(&ap_dev->lock);
654 }
655 spin_unlock_bh(&ap_device_list_lock);
656 } while (!kthread_should_stop());
657 return 0;
658}
659
660static int ap_poll_thread_start(void)
661{
662 int rc;
663
664 if (ap_using_interrupts() || ap_poll_kthread)
665 return 0;
666 mutex_lock(&ap_poll_thread_mutex);
667 ap_poll_kthread = kthread_run(ap_poll_thread, NULL, "appoll");
668 rc = PTR_RET(ap_poll_kthread);
669 if (rc)
670 ap_poll_kthread = NULL;
671 mutex_unlock(&ap_poll_thread_mutex);
672 return rc;
673}
674
675static void ap_poll_thread_stop(void)
676{
677 if (!ap_poll_kthread)
678 return;
679 mutex_lock(&ap_poll_thread_mutex);
680 kthread_stop(ap_poll_kthread);
681 ap_poll_kthread = NULL;
682 mutex_unlock(&ap_poll_thread_mutex);
683}
684
Felix Beck1749a812008-04-17 07:46:28 +0200685/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200686 * AP device related attributes.
687 */
688static ssize_t ap_hwtype_show(struct device *dev,
689 struct device_attribute *attr, char *buf)
690{
691 struct ap_device *ap_dev = to_ap_dev(dev);
692 return snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->device_type);
693}
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200694
Christian Maaser43c207e62008-12-25 13:38:42 +0100695static DEVICE_ATTR(hwtype, 0444, ap_hwtype_show, NULL);
Ingo Tuchscherer42f4dd612014-10-02 14:48:46 +0200696
697static ssize_t ap_raw_hwtype_show(struct device *dev,
698 struct device_attribute *attr, char *buf)
699{
700 struct ap_device *ap_dev = to_ap_dev(dev);
701
702 return snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->raw_hwtype);
703}
704
705static DEVICE_ATTR(raw_hwtype, 0444, ap_raw_hwtype_show, NULL);
706
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200707static ssize_t ap_depth_show(struct device *dev, struct device_attribute *attr,
708 char *buf)
709{
710 struct ap_device *ap_dev = to_ap_dev(dev);
711 return snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->queue_depth);
712}
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200713
Christian Maaser43c207e62008-12-25 13:38:42 +0100714static DEVICE_ATTR(depth, 0444, ap_depth_show, NULL);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200715static ssize_t ap_request_count_show(struct device *dev,
716 struct device_attribute *attr,
717 char *buf)
718{
719 struct ap_device *ap_dev = to_ap_dev(dev);
720 int rc;
721
722 spin_lock_bh(&ap_dev->lock);
723 rc = snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->total_request_count);
724 spin_unlock_bh(&ap_dev->lock);
725 return rc;
726}
727
728static DEVICE_ATTR(request_count, 0444, ap_request_count_show, NULL);
729
Holger Denglerb26bd942012-08-28 16:43:48 +0200730static ssize_t ap_requestq_count_show(struct device *dev,
731 struct device_attribute *attr, char *buf)
732{
733 struct ap_device *ap_dev = to_ap_dev(dev);
734 int rc;
735
736 spin_lock_bh(&ap_dev->lock);
737 rc = snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->requestq_count);
738 spin_unlock_bh(&ap_dev->lock);
739 return rc;
740}
741
742static DEVICE_ATTR(requestq_count, 0444, ap_requestq_count_show, NULL);
743
744static ssize_t ap_pendingq_count_show(struct device *dev,
745 struct device_attribute *attr, char *buf)
746{
747 struct ap_device *ap_dev = to_ap_dev(dev);
748 int rc;
749
750 spin_lock_bh(&ap_dev->lock);
751 rc = snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->pendingq_count);
752 spin_unlock_bh(&ap_dev->lock);
753 return rc;
754}
755
756static DEVICE_ATTR(pendingq_count, 0444, ap_pendingq_count_show, NULL);
757
Ingo Tuchschererc50a1602015-06-17 16:19:15 +0200758static ssize_t ap_reset_show(struct device *dev,
759 struct device_attribute *attr, char *buf)
760{
761 struct ap_device *ap_dev = to_ap_dev(dev);
762 int rc = 0;
763
764 spin_lock_bh(&ap_dev->lock);
765 switch (ap_dev->reset) {
766 case AP_RESET_IGNORE:
767 rc = snprintf(buf, PAGE_SIZE, "No Reset Timer set.\n");
768 break;
769 case AP_RESET_ARMED:
770 rc = snprintf(buf, PAGE_SIZE, "Reset Timer armed.\n");
771 break;
772 case AP_RESET_DO:
773 rc = snprintf(buf, PAGE_SIZE, "Reset Timer expired.\n");
774 break;
775 case AP_RESET_IN_PROGRESS:
776 rc = snprintf(buf, PAGE_SIZE, "Reset in progress.\n");
777 break;
778 default:
779 break;
780 }
781 spin_unlock_bh(&ap_dev->lock);
782 return rc;
783}
784
785static DEVICE_ATTR(reset, 0444, ap_reset_show, NULL);
786
787static ssize_t ap_interrupt_show(struct device *dev,
788 struct device_attribute *attr, char *buf)
789{
790 struct ap_device *ap_dev = to_ap_dev(dev);
791 int rc = 0;
792
793 spin_lock_bh(&ap_dev->lock);
794 switch (ap_dev->interrupt) {
795 case AP_INTR_DISABLED:
796 rc = snprintf(buf, PAGE_SIZE, "Interrupts disabled.\n");
797 break;
798 case AP_INTR_ENABLED:
799 rc = snprintf(buf, PAGE_SIZE, "Interrupts enabled.\n");
800 break;
801 case AP_INTR_IN_PROGRESS:
802 rc = snprintf(buf, PAGE_SIZE, "Enable Interrupt pending.\n");
803 break;
804 }
805 spin_unlock_bh(&ap_dev->lock);
806 return rc;
807}
808
809static DEVICE_ATTR(interrupt, 0444, ap_interrupt_show, NULL);
810
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200811static ssize_t ap_modalias_show(struct device *dev,
812 struct device_attribute *attr, char *buf)
813{
Ingo Tuchschererc50a1602015-06-17 16:19:15 +0200814 return sprintf(buf, "ap:t%02X\n", to_ap_dev(dev)->device_type);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200815}
816
817static DEVICE_ATTR(modalias, 0444, ap_modalias_show, NULL);
818
Holger Denglerb26bd942012-08-28 16:43:48 +0200819static ssize_t ap_functions_show(struct device *dev,
820 struct device_attribute *attr, char *buf)
821{
822 struct ap_device *ap_dev = to_ap_dev(dev);
823 return snprintf(buf, PAGE_SIZE, "0x%08X\n", ap_dev->functions);
824}
825
826static DEVICE_ATTR(ap_functions, 0444, ap_functions_show, NULL);
827
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200828static struct attribute *ap_dev_attrs[] = {
829 &dev_attr_hwtype.attr,
Ingo Tuchscherer42f4dd612014-10-02 14:48:46 +0200830 &dev_attr_raw_hwtype.attr,
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200831 &dev_attr_depth.attr,
832 &dev_attr_request_count.attr,
Holger Denglerb26bd942012-08-28 16:43:48 +0200833 &dev_attr_requestq_count.attr,
834 &dev_attr_pendingq_count.attr,
Ingo Tuchschererc50a1602015-06-17 16:19:15 +0200835 &dev_attr_reset.attr,
836 &dev_attr_interrupt.attr,
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200837 &dev_attr_modalias.attr,
Holger Denglerb26bd942012-08-28 16:43:48 +0200838 &dev_attr_ap_functions.attr,
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200839 NULL
840};
841static struct attribute_group ap_dev_attr_group = {
842 .attrs = ap_dev_attrs
843};
844
845/**
Felix Beck1749a812008-04-17 07:46:28 +0200846 * ap_bus_match()
847 * @dev: Pointer to device
848 * @drv: Pointer to device_driver
849 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200850 * AP bus driver registration/unregistration.
851 */
852static int ap_bus_match(struct device *dev, struct device_driver *drv)
853{
854 struct ap_device *ap_dev = to_ap_dev(dev);
855 struct ap_driver *ap_drv = to_ap_drv(drv);
856 struct ap_device_id *id;
857
Felix Beck1749a812008-04-17 07:46:28 +0200858 /*
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200859 * Compare device type of the device with the list of
860 * supported types of the device_driver.
861 */
862 for (id = ap_drv->ids; id->match_flags; id++) {
863 if ((id->match_flags & AP_DEVICE_ID_MATCH_DEVICE_TYPE) &&
864 (id->dev_type != ap_dev->device_type))
865 continue;
866 return 1;
867 }
868 return 0;
869}
870
871/**
Felix Beck1749a812008-04-17 07:46:28 +0200872 * ap_uevent(): Uevent function for AP devices.
873 * @dev: Pointer to device
874 * @env: Pointer to kobj_uevent_env
875 *
876 * It sets up a single environment variable DEV_TYPE which contains the
877 * hardware device type.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200878 */
Kay Sievers7eff2e72007-08-14 15:15:12 +0200879static int ap_uevent (struct device *dev, struct kobj_uevent_env *env)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200880{
881 struct ap_device *ap_dev = to_ap_dev(dev);
Kay Sievers7eff2e72007-08-14 15:15:12 +0200882 int retval = 0;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200883
884 if (!ap_dev)
885 return -ENODEV;
886
887 /* Set up DEV_TYPE environment variable. */
Kay Sievers7eff2e72007-08-14 15:15:12 +0200888 retval = add_uevent_var(env, "DEV_TYPE=%04X", ap_dev->device_type);
Eric Rannaudbf624562007-03-30 22:23:12 -0700889 if (retval)
890 return retval;
891
Cornelia Huck66a4263b2006-12-04 15:40:10 +0100892 /* Add MODALIAS= */
Kay Sievers7eff2e72007-08-14 15:15:12 +0200893 retval = add_uevent_var(env, "MODALIAS=ap:t%02X", ap_dev->device_type);
Eric Rannaudbf624562007-03-30 22:23:12 -0700894
Eric Rannaudbf624562007-03-30 22:23:12 -0700895 return retval;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200896}
897
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200898static int ap_dev_suspend(struct device *dev, pm_message_t state)
Felix Beck772f5472009-06-22 12:08:16 +0200899{
900 struct ap_device *ap_dev = to_ap_dev(dev);
901 unsigned long flags;
902
Felix Beck772f5472009-06-22 12:08:16 +0200903 /* Poll on the device until all requests are finished. */
904 do {
905 flags = 0;
Felix Beck95f15562009-09-11 10:28:51 +0200906 spin_lock_bh(&ap_dev->lock);
Felix Beck772f5472009-06-22 12:08:16 +0200907 __ap_poll_device(ap_dev, &flags);
Felix Beck95f15562009-09-11 10:28:51 +0200908 spin_unlock_bh(&ap_dev->lock);
Felix Beck772f5472009-06-22 12:08:16 +0200909 } while ((flags & 1) || (flags & 2));
910
Felix Beck772f5472009-06-22 12:08:16 +0200911 return 0;
912}
913
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200914static int ap_dev_resume(struct device *dev)
Felix Beck772f5472009-06-22 12:08:16 +0200915{
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200916 return 0;
917}
918
919static void ap_bus_suspend(void)
920{
921 ap_suspend_flag = 1;
922 /*
923 * Disable scanning for devices, thus we do not want to scan
924 * for them after removing.
925 */
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200926 flush_workqueue(ap_work_queue);
927 tasklet_disable(&ap_tasklet);
928}
929
930static int __ap_devices_unregister(struct device *dev, void *dummy)
931{
932 device_unregister(dev);
933 return 0;
934}
935
936static void ap_bus_resume(void)
937{
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200938 int rc;
Felix Beck772f5472009-06-22 12:08:16 +0200939
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200940 /* Unconditionally remove all AP devices */
941 bus_for_each_dev(&ap_bus_type, NULL, NULL, __ap_devices_unregister);
942 /* Reset thin interrupt setting */
943 if (ap_interrupts_available() && !ap_using_interrupts()) {
944 rc = register_adapter_interrupt(&ap_airq);
945 ap_airq_flag = (rc == 0);
Felix Beck5314af62009-09-22 22:58:51 +0200946 }
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200947 if (!ap_interrupts_available() && ap_using_interrupts()) {
948 unregister_adapter_interrupt(&ap_airq);
949 ap_airq_flag = 0;
950 }
951 /* Reset domain */
952 if (!user_set_domain)
953 ap_domain_index = -1;
954 /* Get things going again */
955 ap_suspend_flag = 0;
956 if (ap_airq_flag)
957 xchg(ap_airq.lsi_ptr, 0);
958 tasklet_enable(&ap_tasklet);
Felix Beck5314af62009-09-22 22:58:51 +0200959 queue_work(ap_work_queue, &ap_config_work);
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200960 wake_up(&ap_poll_wait);
Felix Beck772f5472009-06-22 12:08:16 +0200961}
962
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200963static int ap_power_event(struct notifier_block *this, unsigned long event,
964 void *ptr)
965{
966 switch (event) {
967 case PM_HIBERNATION_PREPARE:
968 case PM_SUSPEND_PREPARE:
969 ap_bus_suspend();
970 break;
971 case PM_POST_HIBERNATION:
972 case PM_POST_SUSPEND:
973 ap_bus_resume();
974 break;
975 default:
976 break;
977 }
978 return NOTIFY_DONE;
979}
980static struct notifier_block ap_power_notifier = {
981 .notifier_call = ap_power_event,
982};
983
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200984static struct bus_type ap_bus_type = {
985 .name = "ap",
986 .match = &ap_bus_match,
987 .uevent = &ap_uevent,
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +0200988 .suspend = ap_dev_suspend,
989 .resume = ap_dev_resume,
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200990};
991
992static int ap_device_probe(struct device *dev)
993{
994 struct ap_device *ap_dev = to_ap_dev(dev);
995 struct ap_driver *ap_drv = to_ap_drv(dev->driver);
996 int rc;
997
998 ap_dev->drv = ap_drv;
Ingo Tuchscherer666e68e2014-07-14 19:11:48 +0200999
1000 spin_lock_bh(&ap_device_list_lock);
1001 list_add(&ap_dev->list, &ap_device_list);
1002 spin_unlock_bh(&ap_device_list_lock);
1003
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001004 rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV;
Ingo Tuchscherer666e68e2014-07-14 19:11:48 +02001005 if (rc) {
Christian Maaser43c207e62008-12-25 13:38:42 +01001006 spin_lock_bh(&ap_device_list_lock);
Ingo Tuchscherer666e68e2014-07-14 19:11:48 +02001007 list_del_init(&ap_dev->list);
Christian Maaser43c207e62008-12-25 13:38:42 +01001008 spin_unlock_bh(&ap_device_list_lock);
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001009 } else {
1010 if (ap_dev->reset == AP_RESET_IN_PROGRESS ||
1011 ap_dev->interrupt == AP_INTR_IN_PROGRESS)
1012 __ap_schedule_poll_timer();
Ralph Wuerthnerfaa582c2008-03-05 12:37:13 +01001013 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001014 return rc;
1015}
1016
1017/**
Felix Beck1749a812008-04-17 07:46:28 +02001018 * __ap_flush_queue(): Flush requests.
1019 * @ap_dev: Pointer to the AP device
1020 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001021 * Flush all requests from the request/pending queue of an AP device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001022 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +01001023static void __ap_flush_queue(struct ap_device *ap_dev)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001024{
1025 struct ap_message *ap_msg, *next;
1026
1027 list_for_each_entry_safe(ap_msg, next, &ap_dev->pendingq, list) {
1028 list_del_init(&ap_msg->list);
1029 ap_dev->pendingq_count--;
Holger Dengler54a8f562012-05-16 14:08:22 +02001030 ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001031 }
1032 list_for_each_entry_safe(ap_msg, next, &ap_dev->requestq, list) {
1033 list_del_init(&ap_msg->list);
1034 ap_dev->requestq_count--;
Holger Dengler54a8f562012-05-16 14:08:22 +02001035 ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001036 }
1037}
1038
1039void ap_flush_queue(struct ap_device *ap_dev)
1040{
1041 spin_lock_bh(&ap_dev->lock);
1042 __ap_flush_queue(ap_dev);
1043 spin_unlock_bh(&ap_dev->lock);
1044}
1045EXPORT_SYMBOL(ap_flush_queue);
1046
1047static int ap_device_remove(struct device *dev)
1048{
1049 struct ap_device *ap_dev = to_ap_dev(dev);
1050 struct ap_driver *ap_drv = ap_dev->drv;
1051
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001052 ap_flush_queue(ap_dev);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001053 del_timer_sync(&ap_dev->timeout);
Christian Maaser43c207e62008-12-25 13:38:42 +01001054 spin_lock_bh(&ap_device_list_lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001055 list_del_init(&ap_dev->list);
Christian Maaser43c207e62008-12-25 13:38:42 +01001056 spin_unlock_bh(&ap_device_list_lock);
Ralph Wuerthnerfaa582c2008-03-05 12:37:13 +01001057 if (ap_drv->remove)
1058 ap_drv->remove(ap_dev);
Ralph Wuerthnere675c0d2007-03-26 20:42:43 +02001059 spin_lock_bh(&ap_dev->lock);
1060 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
1061 spin_unlock_bh(&ap_dev->lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001062 return 0;
1063}
1064
1065int ap_driver_register(struct ap_driver *ap_drv, struct module *owner,
1066 char *name)
1067{
1068 struct device_driver *drv = &ap_drv->driver;
1069
1070 drv->bus = &ap_bus_type;
1071 drv->probe = ap_device_probe;
1072 drv->remove = ap_device_remove;
1073 drv->owner = owner;
1074 drv->name = name;
1075 return driver_register(drv);
1076}
1077EXPORT_SYMBOL(ap_driver_register);
1078
1079void ap_driver_unregister(struct ap_driver *ap_drv)
1080{
1081 driver_unregister(&ap_drv->driver);
1082}
1083EXPORT_SYMBOL(ap_driver_unregister);
1084
Holger Denglerdabecb22012-09-10 21:34:26 +02001085void ap_bus_force_rescan(void)
1086{
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +02001087 if (ap_suspend_flag)
1088 return;
Ingo Tuchscherer56bbe682013-04-12 17:52:08 +02001089 /* processing a asynchronous bus rescan */
Martin Schwidefskyfcd0d1f2015-07-23 10:55:59 +02001090 del_timer(&ap_config_timer);
Ingo Tuchscherer56bbe682013-04-12 17:52:08 +02001091 queue_work(ap_work_queue, &ap_config_work);
1092 flush_work(&ap_config_work);
Holger Denglerdabecb22012-09-10 21:34:26 +02001093}
1094EXPORT_SYMBOL(ap_bus_force_rescan);
1095
Felix Beck1749a812008-04-17 07:46:28 +02001096/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001097 * AP bus attributes.
1098 */
1099static ssize_t ap_domain_show(struct bus_type *bus, char *buf)
1100{
1101 return snprintf(buf, PAGE_SIZE, "%d\n", ap_domain_index);
1102}
1103
1104static BUS_ATTR(ap_domain, 0444, ap_domain_show, NULL);
1105
Ingo Tuchscherer91f3e3ea2013-11-20 10:47:13 +01001106static ssize_t ap_control_domain_mask_show(struct bus_type *bus, char *buf)
1107{
Martin Schwidefsky889875a2015-06-26 16:55:35 +02001108 if (!ap_configuration) /* QCI not supported */
1109 return snprintf(buf, PAGE_SIZE, "not supported\n");
1110 if (!test_facility(76))
1111 /* format 0 - 16 bit domain field */
1112 return snprintf(buf, PAGE_SIZE, "%08x%08x\n",
1113 ap_configuration->adm[0],
1114 ap_configuration->adm[1]);
1115 /* format 1 - 256 bit domain field */
1116 return snprintf(buf, PAGE_SIZE,
1117 "0x%08x%08x%08x%08x%08x%08x%08x%08x\n",
Ingo Tuchscherer91f3e3ea2013-11-20 10:47:13 +01001118 ap_configuration->adm[0], ap_configuration->adm[1],
1119 ap_configuration->adm[2], ap_configuration->adm[3],
1120 ap_configuration->adm[4], ap_configuration->adm[5],
1121 ap_configuration->adm[6], ap_configuration->adm[7]);
Ingo Tuchscherer91f3e3ea2013-11-20 10:47:13 +01001122}
1123
1124static BUS_ATTR(ap_control_domain_mask, 0444,
1125 ap_control_domain_mask_show, NULL);
1126
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001127static ssize_t ap_config_time_show(struct bus_type *bus, char *buf)
1128{
1129 return snprintf(buf, PAGE_SIZE, "%d\n", ap_config_time);
1130}
1131
Felix Beckcb17a632008-12-25 13:38:41 +01001132static ssize_t ap_interrupts_show(struct bus_type *bus, char *buf)
1133{
1134 return snprintf(buf, PAGE_SIZE, "%d\n",
1135 ap_using_interrupts() ? 1 : 0);
1136}
1137
1138static BUS_ATTR(ap_interrupts, 0444, ap_interrupts_show, NULL);
1139
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001140static ssize_t ap_config_time_store(struct bus_type *bus,
1141 const char *buf, size_t count)
1142{
1143 int time;
1144
1145 if (sscanf(buf, "%d\n", &time) != 1 || time < 5 || time > 120)
1146 return -EINVAL;
1147 ap_config_time = time;
Martin Schwidefskyfcd0d1f2015-07-23 10:55:59 +02001148 mod_timer(&ap_config_timer, jiffies + ap_config_time * HZ);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001149 return count;
1150}
1151
1152static BUS_ATTR(config_time, 0644, ap_config_time_show, ap_config_time_store);
1153
1154static ssize_t ap_poll_thread_show(struct bus_type *bus, char *buf)
1155{
1156 return snprintf(buf, PAGE_SIZE, "%d\n", ap_poll_kthread ? 1 : 0);
1157}
1158
1159static ssize_t ap_poll_thread_store(struct bus_type *bus,
1160 const char *buf, size_t count)
1161{
1162 int flag, rc;
1163
1164 if (sscanf(buf, "%d\n", &flag) != 1)
1165 return -EINVAL;
1166 if (flag) {
1167 rc = ap_poll_thread_start();
1168 if (rc)
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +02001169 count = rc;
1170 } else
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001171 ap_poll_thread_stop();
1172 return count;
1173}
1174
1175static BUS_ATTR(poll_thread, 0644, ap_poll_thread_show, ap_poll_thread_store);
1176
Felix Beckfe137232008-07-14 09:59:08 +02001177static ssize_t poll_timeout_show(struct bus_type *bus, char *buf)
1178{
1179 return snprintf(buf, PAGE_SIZE, "%llu\n", poll_timeout);
1180}
1181
1182static ssize_t poll_timeout_store(struct bus_type *bus, const char *buf,
1183 size_t count)
1184{
1185 unsigned long long time;
1186 ktime_t hr_time;
1187
1188 /* 120 seconds = maximum poll interval */
Felix Beckcb17a632008-12-25 13:38:41 +01001189 if (sscanf(buf, "%llu\n", &time) != 1 || time < 1 ||
1190 time > 120000000000ULL)
Felix Beckfe137232008-07-14 09:59:08 +02001191 return -EINVAL;
1192 poll_timeout = time;
1193 hr_time = ktime_set(0, poll_timeout);
1194
Ingo Tuchscherer8cc2af72015-04-28 10:31:44 +02001195 spin_lock_bh(&ap_poll_timer_lock);
1196 hrtimer_cancel(&ap_poll_timer);
1197 hrtimer_set_expires(&ap_poll_timer, hr_time);
1198 hrtimer_start_expires(&ap_poll_timer, HRTIMER_MODE_ABS);
1199 spin_unlock_bh(&ap_poll_timer_lock);
1200
Felix Beckfe137232008-07-14 09:59:08 +02001201 return count;
1202}
1203
1204static BUS_ATTR(poll_timeout, 0644, poll_timeout_show, poll_timeout_store);
1205
Ingo Tuchscherer5bc334b2015-01-23 13:27:04 +01001206static ssize_t ap_max_domain_id_show(struct bus_type *bus, char *buf)
1207{
Martin Schwidefsky889875a2015-06-26 16:55:35 +02001208 int max_domain_id;
Ingo Tuchscherer5bc334b2015-01-23 13:27:04 +01001209
Martin Schwidefsky889875a2015-06-26 16:55:35 +02001210 if (ap_configuration)
1211 max_domain_id = ap_max_domain_id ? : -1;
1212 else
Ingo Tuchscherer5bc334b2015-01-23 13:27:04 +01001213 max_domain_id = 15;
Ingo Tuchscherer5bc334b2015-01-23 13:27:04 +01001214 return snprintf(buf, PAGE_SIZE, "%d\n", max_domain_id);
1215}
1216
1217static BUS_ATTR(ap_max_domain_id, 0444, ap_max_domain_id_show, NULL);
1218
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001219static struct bus_attribute *const ap_bus_attrs[] = {
1220 &bus_attr_ap_domain,
Ingo Tuchscherer91f3e3ea2013-11-20 10:47:13 +01001221 &bus_attr_ap_control_domain_mask,
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001222 &bus_attr_config_time,
1223 &bus_attr_poll_thread,
Felix Beckcb17a632008-12-25 13:38:41 +01001224 &bus_attr_ap_interrupts,
Felix Beckfe137232008-07-14 09:59:08 +02001225 &bus_attr_poll_timeout,
Ingo Tuchscherer5bc334b2015-01-23 13:27:04 +01001226 &bus_attr_ap_max_domain_id,
Felix Beckfe137232008-07-14 09:59:08 +02001227 NULL,
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001228};
1229
Holger Dengler75014552012-08-28 16:41:50 +02001230/**
Felix Beck1749a812008-04-17 07:46:28 +02001231 * ap_select_domain(): Select an AP domain.
1232 *
1233 * Pick one of the 16 AP domains.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001234 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +01001235static int ap_select_domain(void)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001236{
Martin Schwidefsky6acbe212015-06-26 15:40:41 +02001237 int count, max_count, best_domain;
1238 struct ap_queue_status status;
1239 int i, j;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001240
Felix Beck1749a812008-04-17 07:46:28 +02001241 /*
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001242 * We want to use a single domain. Either the one specified with
1243 * the "domain=" parameter or the domain with the maximum number
1244 * of devices.
1245 */
Martin Schwidefsky889875a2015-06-26 16:55:35 +02001246 if (ap_domain_index >= 0)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001247 /* Domain has already been selected. */
1248 return 0;
1249 best_domain = -1;
1250 max_count = 0;
1251 for (i = 0; i < AP_DOMAINS; i++) {
Holger Dengler75014552012-08-28 16:41:50 +02001252 if (!ap_test_config_domain(i))
1253 continue;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001254 count = 0;
1255 for (j = 0; j < AP_DEVICES; j++) {
Holger Dengler75014552012-08-28 16:41:50 +02001256 if (!ap_test_config_card_id(j))
1257 continue;
Martin Schwidefsky6acbe212015-06-26 15:40:41 +02001258 status = ap_test_queue(AP_MKQID(j, i), NULL);
1259 if (status.response_code != AP_RESPONSE_NORMAL)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001260 continue;
1261 count++;
1262 }
1263 if (count > max_count) {
1264 max_count = count;
1265 best_domain = i;
1266 }
1267 }
1268 if (best_domain >= 0){
1269 ap_domain_index = best_domain;
1270 return 0;
1271 }
1272 return -ENODEV;
1273}
1274
1275/**
Felix Beck1749a812008-04-17 07:46:28 +02001276 * ap_probe_device_type(): Find the device type of an AP.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001277 * @ap_dev: pointer to the AP device.
Felix Beck1749a812008-04-17 07:46:28 +02001278 *
1279 * Find the device type if query queue returned a device type of 0.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001280 */
1281static int ap_probe_device_type(struct ap_device *ap_dev)
1282{
1283 static unsigned char msg[] = {
1284 0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
1285 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1286 0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,
1287 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1288 0x01,0x00,0x43,0x43,0x41,0x2d,0x41,0x50,
1289 0x50,0x4c,0x20,0x20,0x20,0x01,0x01,0x01,
1290 0x00,0x00,0x00,0x00,0x50,0x4b,0x00,0x00,
1291 0x00,0x00,0x01,0x1c,0x00,0x00,0x00,0x00,
1292 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1293 0x00,0x00,0x05,0xb8,0x00,0x00,0x00,0x00,
1294 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1295 0x70,0x00,0x41,0x00,0x00,0x00,0x00,0x00,
1296 0x00,0x00,0x54,0x32,0x01,0x00,0xa0,0x00,
1297 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1298 0x00,0x00,0x00,0x00,0xb8,0x05,0x00,0x00,
1299 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1300 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1301 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1302 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1303 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1304 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1305 0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,
1306 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1307 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,
1308 0x49,0x43,0x53,0x46,0x20,0x20,0x20,0x20,
1309 0x50,0x4b,0x0a,0x00,0x50,0x4b,0x43,0x53,
1310 0x2d,0x31,0x2e,0x32,0x37,0x00,0x11,0x22,
1311 0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,
1312 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,
1313 0x99,0x00,0x11,0x22,0x33,0x44,0x55,0x66,
1314 0x77,0x88,0x99,0x00,0x11,0x22,0x33,0x44,
1315 0x55,0x66,0x77,0x88,0x99,0x00,0x11,0x22,
1316 0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,
1317 0x11,0x22,0x33,0x5d,0x00,0x5b,0x00,0x77,
1318 0x88,0x1e,0x00,0x00,0x57,0x00,0x00,0x00,
1319 0x00,0x04,0x00,0x00,0x4f,0x00,0x00,0x00,
1320 0x03,0x02,0x00,0x00,0x40,0x01,0x00,0x01,
1321 0xce,0x02,0x68,0x2d,0x5f,0xa9,0xde,0x0c,
1322 0xf6,0xd2,0x7b,0x58,0x4b,0xf9,0x28,0x68,
1323 0x3d,0xb4,0xf4,0xef,0x78,0xd5,0xbe,0x66,
1324 0x63,0x42,0xef,0xf8,0xfd,0xa4,0xf8,0xb0,
1325 0x8e,0x29,0xc2,0xc9,0x2e,0xd8,0x45,0xb8,
1326 0x53,0x8c,0x6f,0x4e,0x72,0x8f,0x6c,0x04,
1327 0x9c,0x88,0xfc,0x1e,0xc5,0x83,0x55,0x57,
1328 0xf7,0xdd,0xfd,0x4f,0x11,0x36,0x95,0x5d,
1329 };
1330 struct ap_queue_status status;
1331 unsigned long long psmid;
1332 char *reply;
1333 int rc, i;
1334
1335 reply = (void *) get_zeroed_page(GFP_KERNEL);
1336 if (!reply) {
1337 rc = -ENOMEM;
1338 goto out;
1339 }
1340
1341 status = __ap_send(ap_dev->qid, 0x0102030405060708ULL,
Felix Becka6a5d732009-12-07 12:51:55 +01001342 msg, sizeof(msg), 0);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001343 if (status.response_code != AP_RESPONSE_NORMAL) {
1344 rc = -ENODEV;
1345 goto out_free;
1346 }
1347
1348 /* Wait for the test message to complete. */
1349 for (i = 0; i < 6; i++) {
Heiko Carstense4e18992015-08-17 07:59:47 +02001350 msleep(300);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001351 status = __ap_recv(ap_dev->qid, &psmid, reply, 4096);
1352 if (status.response_code == AP_RESPONSE_NORMAL &&
1353 psmid == 0x0102030405060708ULL)
1354 break;
1355 }
1356 if (i < 6) {
1357 /* Got an answer. */
1358 if (reply[0] == 0x00 && reply[1] == 0x86)
1359 ap_dev->device_type = AP_DEVICE_TYPE_PCICC;
1360 else
1361 ap_dev->device_type = AP_DEVICE_TYPE_PCICA;
1362 rc = 0;
1363 } else
1364 rc = -ENODEV;
1365
1366out_free:
1367 free_page((unsigned long) reply);
1368out:
1369 return rc;
1370}
1371
Martin Schwidefskyf4eae942013-06-24 10:30:41 +02001372static void ap_interrupt_handler(struct airq_struct *airq)
Felix Beckcb17a632008-12-25 13:38:41 +01001373{
Heiko Carstens420f42e2013-01-02 15:18:18 +01001374 inc_irq_stat(IRQIO_APB);
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +02001375 if (!ap_suspend_flag)
1376 tasklet_schedule(&ap_tasklet);
Felix Beckcb17a632008-12-25 13:38:41 +01001377}
1378
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001379/**
Felix Beck1749a812008-04-17 07:46:28 +02001380 * __ap_scan_bus(): Scan the AP bus.
1381 * @dev: Pointer to device
1382 * @data: Pointer to data
1383 *
1384 * Scan the AP bus for new devices.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001385 */
1386static int __ap_scan_bus(struct device *dev, void *data)
1387{
1388 return to_ap_dev(dev)->qid == (ap_qid_t)(unsigned long) data;
1389}
1390
1391static void ap_device_release(struct device *dev)
1392{
1393 struct ap_device *ap_dev = to_ap_dev(dev);
1394
1395 kfree(ap_dev);
1396}
1397
Al Viro4927b3f2006-12-06 19:18:20 +00001398static void ap_scan_bus(struct work_struct *unused)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001399{
1400 struct ap_device *ap_dev;
1401 struct device *dev;
1402 ap_qid_t qid;
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001403 int queue_depth = 0, device_type = 0;
Holger Dengler6bed05b2011-07-24 10:48:25 +02001404 unsigned int device_functions;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001405 int rc, i;
1406
Holger Dengler75014552012-08-28 16:41:50 +02001407 ap_query_configuration();
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +02001408 if (ap_select_domain() != 0)
Martin Schwidefskyfcd0d1f2015-07-23 10:55:59 +02001409 goto out;
Martin Schwidefsky889875a2015-06-26 16:55:35 +02001410
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001411 for (i = 0; i < AP_DEVICES; i++) {
1412 qid = AP_MKQID(i, ap_domain_index);
1413 dev = bus_find_device(&ap_bus_type, NULL,
1414 (void *)(unsigned long)qid,
1415 __ap_scan_bus);
Martin Schwidefsky889875a2015-06-26 16:55:35 +02001416 rc = ap_query_queue(qid, &queue_depth, &device_type,
1417 &device_functions);
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001418 if (dev) {
1419 ap_dev = to_ap_dev(dev);
1420 spin_lock_bh(&ap_dev->lock);
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001421 if (rc == -ENODEV || ap_dev->unregistered) {
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001422 spin_unlock_bh(&ap_dev->lock);
Felix Beck5314af62009-09-22 22:58:51 +02001423 if (ap_dev->unregistered)
1424 i--;
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001425 device_unregister(dev);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001426 put_device(dev);
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001427 continue;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001428 }
1429 spin_unlock_bh(&ap_dev->lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001430 put_device(dev);
1431 continue;
1432 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001433 if (rc)
1434 continue;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001435 ap_dev = kzalloc(sizeof(*ap_dev), GFP_KERNEL);
1436 if (!ap_dev)
1437 break;
1438 ap_dev->qid = qid;
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001439 rc = ap_init_queue(ap_dev);
1440 if ((rc != 0) && (rc != -EBUSY)) {
1441 kfree(ap_dev);
1442 continue;
1443 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001444 ap_dev->queue_depth = queue_depth;
Martin Schwidefsky6acbe212015-06-26 15:40:41 +02001445 ap_dev->raw_hwtype = device_type;
1446 ap_dev->device_type = device_type;
1447 ap_dev->functions = device_functions;
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001448 ap_dev->unregistered = 1;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001449 spin_lock_init(&ap_dev->lock);
1450 INIT_LIST_HEAD(&ap_dev->pendingq);
1451 INIT_LIST_HEAD(&ap_dev->requestq);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001452 INIT_LIST_HEAD(&ap_dev->list);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001453 setup_timer(&ap_dev->timeout, ap_request_timeout,
1454 (unsigned long) ap_dev);
Martin Schwidefsky6acbe212015-06-26 15:40:41 +02001455 if (ap_dev->device_type == 0)
Holger Dengler1e2076f2012-08-28 16:48:29 +02001456 /* device type probing for old cards */
Holger Denglercf2d0072011-05-23 10:24:30 +02001457 if (ap_probe_device_type(ap_dev)) {
1458 kfree(ap_dev);
1459 continue;
1460 }
Holger Dengler1e2076f2012-08-28 16:48:29 +02001461
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001462 ap_dev->device.bus = &ap_bus_type;
1463 ap_dev->device.parent = ap_root_device;
Felix Beckedc44fa2009-09-11 10:28:52 +02001464 if (dev_set_name(&ap_dev->device, "card%02x",
1465 AP_QID_DEVICE(ap_dev->qid))) {
1466 kfree(ap_dev);
1467 continue;
1468 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001469 ap_dev->device.release = ap_device_release;
1470 rc = device_register(&ap_dev->device);
1471 if (rc) {
Sebastian Ottc6304932009-09-11 10:28:38 +02001472 put_device(&ap_dev->device);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001473 continue;
1474 }
1475 /* Add device attributes. */
1476 rc = sysfs_create_group(&ap_dev->device.kobj,
1477 &ap_dev_attr_group);
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001478 if (!rc) {
1479 spin_lock_bh(&ap_dev->lock);
1480 ap_dev->unregistered = 0;
1481 spin_unlock_bh(&ap_dev->lock);
1482 }
1483 else
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001484 device_unregister(&ap_dev->device);
1485 }
Martin Schwidefskyfcd0d1f2015-07-23 10:55:59 +02001486out:
1487 mod_timer(&ap_config_timer, jiffies + ap_config_time * HZ);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001488}
1489
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +02001490static void ap_config_timeout(unsigned long ptr)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001491{
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +02001492 if (ap_suspend_flag)
1493 return;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001494 queue_work(ap_work_queue, &ap_config_work);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001495}
1496
1497/**
Felix Beck1749a812008-04-17 07:46:28 +02001498 * ap_poll_read(): Receive pending reply messages from an AP device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001499 * @ap_dev: pointer to the AP device
1500 * @flags: pointer to control flags, bit 2^0 is set if another poll is
1501 * required, bit 2^1 is set if the poll timer needs to get armed
Felix Beck1749a812008-04-17 07:46:28 +02001502 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001503 * Returns 0 if the device is still present, -ENODEV if not.
1504 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +01001505static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001506{
1507 struct ap_queue_status status;
1508 struct ap_message *ap_msg;
1509
1510 if (ap_dev->queue_count <= 0)
1511 return 0;
1512 status = __ap_recv(ap_dev->qid, &ap_dev->reply->psmid,
1513 ap_dev->reply->message, ap_dev->reply->length);
1514 switch (status.response_code) {
1515 case AP_RESPONSE_NORMAL:
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001516 ap_dev->interrupt = status.int_enabled;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001517 atomic_dec(&ap_poll_requests);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001518 ap_decrease_queue_count(ap_dev);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001519 list_for_each_entry(ap_msg, &ap_dev->pendingq, list) {
1520 if (ap_msg->psmid != ap_dev->reply->psmid)
1521 continue;
1522 list_del_init(&ap_msg->list);
1523 ap_dev->pendingq_count--;
Holger Dengler54a8f562012-05-16 14:08:22 +02001524 ap_msg->receive(ap_dev, ap_msg, ap_dev->reply);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001525 break;
1526 }
1527 if (ap_dev->queue_count > 0)
1528 *flags |= 1;
1529 break;
1530 case AP_RESPONSE_NO_PENDING_REPLY:
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001531 ap_dev->interrupt = status.int_enabled;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001532 if (status.queue_empty) {
1533 /* The card shouldn't forget requests but who knows. */
Ralph Wuerthnere675c0d2007-03-26 20:42:43 +02001534 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001535 ap_dev->queue_count = 0;
1536 list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
1537 ap_dev->requestq_count += ap_dev->pendingq_count;
1538 ap_dev->pendingq_count = 0;
1539 } else
1540 *flags |= 2;
1541 break;
1542 default:
1543 return -ENODEV;
1544 }
1545 return 0;
1546}
1547
1548/**
Felix Beck1749a812008-04-17 07:46:28 +02001549 * ap_poll_write(): Send messages from the request queue to an AP device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001550 * @ap_dev: pointer to the AP device
1551 * @flags: pointer to control flags, bit 2^0 is set if another poll is
1552 * required, bit 2^1 is set if the poll timer needs to get armed
Felix Beck1749a812008-04-17 07:46:28 +02001553 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001554 * Returns 0 if the device is still present, -ENODEV if not.
1555 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +01001556static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001557{
1558 struct ap_queue_status status;
1559 struct ap_message *ap_msg;
1560
1561 if (ap_dev->requestq_count <= 0 ||
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001562 (ap_dev->queue_count >= ap_dev->queue_depth) ||
1563 (ap_dev->reset == AP_RESET_IN_PROGRESS))
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001564 return 0;
1565 /* Start the next request on the queue. */
1566 ap_msg = list_entry(ap_dev->requestq.next, struct ap_message, list);
1567 status = __ap_send(ap_dev->qid, ap_msg->psmid,
Felix Becka6a5d732009-12-07 12:51:55 +01001568 ap_msg->message, ap_msg->length, ap_msg->special);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001569 switch (status.response_code) {
1570 case AP_RESPONSE_NORMAL:
1571 atomic_inc(&ap_poll_requests);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001572 ap_increase_queue_count(ap_dev);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001573 list_move_tail(&ap_msg->list, &ap_dev->pendingq);
1574 ap_dev->requestq_count--;
1575 ap_dev->pendingq_count++;
1576 if (ap_dev->queue_count < ap_dev->queue_depth &&
1577 ap_dev->requestq_count > 0)
1578 *flags |= 1;
1579 *flags |= 2;
1580 break;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001581 case AP_RESPONSE_RESET_IN_PROGRESS:
Holger Denglerbc615de2011-11-14 11:19:04 +01001582 __ap_schedule_poll_timer();
1583 case AP_RESPONSE_Q_FULL:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001584 *flags |= 2;
1585 break;
1586 case AP_RESPONSE_MESSAGE_TOO_BIG:
Felix Becka6a5d732009-12-07 12:51:55 +01001587 case AP_RESPONSE_REQ_FAC_NOT_INST:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001588 return -EINVAL;
1589 default:
1590 return -ENODEV;
1591 }
1592 return 0;
1593}
1594
1595/**
Felix Beck1749a812008-04-17 07:46:28 +02001596 * ap_poll_queue(): Poll AP device for pending replies and send new messages.
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001597 * Check if the queue has a pending reset. In case it's done re-enable
1598 * interrupts, otherwise reschedule the poll_timer for another attempt.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001599 * @ap_dev: pointer to the bus device
1600 * @flags: pointer to control flags, bit 2^0 is set if another poll is
1601 * required, bit 2^1 is set if the poll timer needs to get armed
Felix Beck1749a812008-04-17 07:46:28 +02001602 *
1603 * Poll AP device for pending replies and send new messages. If either
1604 * ap_poll_read or ap_poll_write returns -ENODEV unregister the device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001605 * Returns 0.
1606 */
1607static inline int ap_poll_queue(struct ap_device *ap_dev, unsigned long *flags)
1608{
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001609 struct ap_queue_status status;
Martin Schwidefsky6acbe212015-06-26 15:40:41 +02001610 int rc;
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001611
1612 if (ap_dev->reset == AP_RESET_IN_PROGRESS) {
Martin Schwidefsky6acbe212015-06-26 15:40:41 +02001613 status = ap_test_queue(ap_dev->qid, NULL);
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001614 switch (status.response_code) {
1615 case AP_RESPONSE_NORMAL:
1616 ap_dev->reset = AP_RESET_IGNORE;
1617 if (ap_using_interrupts()) {
1618 rc = ap_queue_enable_interruption(
1619 ap_dev, ap_airq.lsi_ptr);
1620 if (!rc)
1621 ap_dev->interrupt = AP_INTR_IN_PROGRESS;
1622 else if (rc == -ENODEV) {
1623 pr_err("Registering adapter interrupts for "
1624 "AP %d failed\n", AP_QID_DEVICE(ap_dev->qid));
1625 return rc;
1626 }
1627 }
1628 /* fall through */
1629 case AP_RESPONSE_BUSY:
1630 case AP_RESPONSE_RESET_IN_PROGRESS:
1631 *flags |= AP_POLL_AFTER_TIMEOUT;
1632 break;
1633 case AP_RESPONSE_Q_NOT_AVAIL:
1634 case AP_RESPONSE_DECONFIGURED:
1635 case AP_RESPONSE_CHECKSTOPPED:
1636 return -ENODEV;
1637 default:
1638 break;
1639 }
1640 }
1641
1642 if ((ap_dev->reset != AP_RESET_IN_PROGRESS) &&
1643 (ap_dev->interrupt == AP_INTR_IN_PROGRESS)) {
Martin Schwidefsky6acbe212015-06-26 15:40:41 +02001644 status = ap_test_queue(ap_dev->qid, NULL);
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001645 if (ap_using_interrupts()) {
1646 if (status.int_enabled == 1)
1647 ap_dev->interrupt = AP_INTR_ENABLED;
1648 else
1649 *flags |= AP_POLL_AFTER_TIMEOUT;
1650 } else
1651 ap_dev->interrupt = AP_INTR_DISABLED;
1652 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001653
1654 rc = ap_poll_read(ap_dev, flags);
1655 if (rc)
1656 return rc;
1657 return ap_poll_write(ap_dev, flags);
1658}
1659
1660/**
Felix Beck1749a812008-04-17 07:46:28 +02001661 * __ap_queue_message(): Queue a message to a device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001662 * @ap_dev: pointer to the AP device
1663 * @ap_msg: the message to be queued
Felix Beck1749a812008-04-17 07:46:28 +02001664 *
1665 * Queue a message to a device. Returns 0 if successful.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001666 */
1667static int __ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
1668{
1669 struct ap_queue_status status;
1670
1671 if (list_empty(&ap_dev->requestq) &&
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001672 (ap_dev->queue_count < ap_dev->queue_depth) &&
1673 (ap_dev->reset != AP_RESET_IN_PROGRESS)) {
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001674 status = __ap_send(ap_dev->qid, ap_msg->psmid,
Felix Becka6a5d732009-12-07 12:51:55 +01001675 ap_msg->message, ap_msg->length,
1676 ap_msg->special);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001677 switch (status.response_code) {
1678 case AP_RESPONSE_NORMAL:
1679 list_add_tail(&ap_msg->list, &ap_dev->pendingq);
1680 atomic_inc(&ap_poll_requests);
1681 ap_dev->pendingq_count++;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001682 ap_increase_queue_count(ap_dev);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001683 ap_dev->total_request_count++;
1684 break;
1685 case AP_RESPONSE_Q_FULL:
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001686 case AP_RESPONSE_RESET_IN_PROGRESS:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001687 list_add_tail(&ap_msg->list, &ap_dev->requestq);
1688 ap_dev->requestq_count++;
1689 ap_dev->total_request_count++;
1690 return -EBUSY;
Felix Becka6a5d732009-12-07 12:51:55 +01001691 case AP_RESPONSE_REQ_FAC_NOT_INST:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001692 case AP_RESPONSE_MESSAGE_TOO_BIG:
Holger Dengler54a8f562012-05-16 14:08:22 +02001693 ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL));
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001694 return -EINVAL;
1695 default: /* Device is gone. */
Holger Dengler54a8f562012-05-16 14:08:22 +02001696 ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001697 return -ENODEV;
1698 }
1699 } else {
1700 list_add_tail(&ap_msg->list, &ap_dev->requestq);
1701 ap_dev->requestq_count++;
1702 ap_dev->total_request_count++;
1703 return -EBUSY;
1704 }
1705 ap_schedule_poll_timer();
1706 return 0;
1707}
1708
1709void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
1710{
1711 unsigned long flags;
1712 int rc;
1713
Holger Dengler54a8f562012-05-16 14:08:22 +02001714 /* For asynchronous message handling a valid receive-callback
1715 * is required. */
1716 BUG_ON(!ap_msg->receive);
1717
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001718 spin_lock_bh(&ap_dev->lock);
1719 if (!ap_dev->unregistered) {
1720 /* Make room on the queue by polling for finished requests. */
1721 rc = ap_poll_queue(ap_dev, &flags);
1722 if (!rc)
1723 rc = __ap_queue_message(ap_dev, ap_msg);
1724 if (!rc)
1725 wake_up(&ap_poll_wait);
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001726 if (rc == -ENODEV)
1727 ap_dev->unregistered = 1;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001728 } else {
Holger Dengler54a8f562012-05-16 14:08:22 +02001729 ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001730 rc = -ENODEV;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001731 }
1732 spin_unlock_bh(&ap_dev->lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001733}
1734EXPORT_SYMBOL(ap_queue_message);
1735
1736/**
Felix Beck1749a812008-04-17 07:46:28 +02001737 * ap_cancel_message(): Cancel a crypto request.
1738 * @ap_dev: The AP device that has the message queued
1739 * @ap_msg: The message that is to be removed
1740 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001741 * Cancel a crypto request. This is done by removing the request
Felix Beck1749a812008-04-17 07:46:28 +02001742 * from the device pending or request queue. Note that the
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001743 * request stays on the AP queue. When it finishes the message
1744 * reply will be discarded because the psmid can't be found.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001745 */
1746void ap_cancel_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
1747{
1748 struct ap_message *tmp;
1749
1750 spin_lock_bh(&ap_dev->lock);
1751 if (!list_empty(&ap_msg->list)) {
1752 list_for_each_entry(tmp, &ap_dev->pendingq, list)
1753 if (tmp->psmid == ap_msg->psmid) {
1754 ap_dev->pendingq_count--;
1755 goto found;
1756 }
1757 ap_dev->requestq_count--;
1758 found:
1759 list_del_init(&ap_msg->list);
1760 }
1761 spin_unlock_bh(&ap_dev->lock);
1762}
1763EXPORT_SYMBOL(ap_cancel_message);
1764
1765/**
Felix Beck1749a812008-04-17 07:46:28 +02001766 * ap_poll_timeout(): AP receive polling for finished AP requests.
Felix Beckfe137232008-07-14 09:59:08 +02001767 * @unused: Unused pointer.
Felix Beck1749a812008-04-17 07:46:28 +02001768 *
Felix Beckfe137232008-07-14 09:59:08 +02001769 * Schedules the AP tasklet using a high resolution timer.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001770 */
Felix Beckfe137232008-07-14 09:59:08 +02001771static enum hrtimer_restart ap_poll_timeout(struct hrtimer *unused)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001772{
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +02001773 if (!ap_suspend_flag)
1774 tasklet_schedule(&ap_tasklet);
Felix Beckfe137232008-07-14 09:59:08 +02001775 return HRTIMER_NORESTART;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001776}
1777
1778/**
Felix Beck1749a812008-04-17 07:46:28 +02001779 * ap_reset(): Reset a not responding AP device.
1780 * @ap_dev: Pointer to the AP device
1781 *
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001782 * Reset a not responding AP device and move all requests from the
1783 * pending queue to the request queue.
1784 */
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001785static void ap_reset(struct ap_device *ap_dev, unsigned long *flags)
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001786{
1787 int rc;
1788
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001789 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
1790 ap_dev->queue_count = 0;
1791 list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
1792 ap_dev->requestq_count += ap_dev->pendingq_count;
1793 ap_dev->pendingq_count = 0;
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001794 rc = ap_init_queue(ap_dev);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001795 if (rc == -ENODEV)
1796 ap_dev->unregistered = 1;
Holger Dengler75464962011-12-01 13:32:23 +01001797 else
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001798 *flags |= AP_POLL_AFTER_TIMEOUT;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001799}
1800
Christian Maaser43c207e62008-12-25 13:38:42 +01001801static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001802{
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001803 if (!ap_dev->unregistered) {
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001804 if (ap_poll_queue(ap_dev, flags))
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001805 ap_dev->unregistered = 1;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001806 if (ap_dev->reset == AP_RESET_DO)
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001807 ap_reset(ap_dev, flags);
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001808 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001809 return 0;
1810}
1811
Felix Beck1749a812008-04-17 07:46:28 +02001812/**
1813 * ap_poll_all(): Poll all AP devices.
1814 * @dummy: Unused variable
1815 *
1816 * Poll all AP devices on the bus in a round robin fashion. Continue
1817 * polling until bit 2^0 of the control flags is not set. If bit 2^1
1818 * of the control flags has been set arm the poll timer.
1819 */
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001820static void ap_poll_all(unsigned long dummy)
1821{
1822 unsigned long flags;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001823 struct ap_device *ap_dev;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001824
Felix Beckcb17a632008-12-25 13:38:41 +01001825 /* Reset the indicator if interrupts are used. Thus new interrupts can
1826 * be received. Doing it in the beginning of the tasklet is therefor
1827 * important that no requests on any AP get lost.
1828 */
1829 if (ap_using_interrupts())
Martin Schwidefskyf4eae942013-06-24 10:30:41 +02001830 xchg(ap_airq.lsi_ptr, 0);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001831 do {
1832 flags = 0;
Christian Maaser43c207e62008-12-25 13:38:42 +01001833 spin_lock(&ap_device_list_lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001834 list_for_each_entry(ap_dev, &ap_device_list, list) {
Felix Beck95f15562009-09-11 10:28:51 +02001835 spin_lock(&ap_dev->lock);
Christian Maaser43c207e62008-12-25 13:38:42 +01001836 __ap_poll_device(ap_dev, &flags);
Felix Beck95f15562009-09-11 10:28:51 +02001837 spin_unlock(&ap_dev->lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001838 }
Christian Maaser43c207e62008-12-25 13:38:42 +01001839 spin_unlock(&ap_device_list_lock);
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001840 } while (flags & AP_POLL_IMMEDIATELY);
1841 if (flags & AP_POLL_AFTER_TIMEOUT)
1842 __ap_schedule_poll_timer();
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001843}
1844
1845/**
Felix Beck1749a812008-04-17 07:46:28 +02001846 * ap_request_timeout(): Handling of request timeouts
1847 * @data: Holds the AP device.
1848 *
1849 * Handles request timeouts.
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001850 */
1851static void ap_request_timeout(unsigned long data)
1852{
1853 struct ap_device *ap_dev = (struct ap_device *) data;
1854
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +02001855 if (ap_suspend_flag)
1856 return;
Felix Beckcb17a632008-12-25 13:38:41 +01001857 if (ap_dev->reset == AP_RESET_ARMED) {
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001858 ap_dev->reset = AP_RESET_DO;
Felix Beckcb17a632008-12-25 13:38:41 +01001859
1860 if (ap_using_interrupts())
1861 tasklet_schedule(&ap_tasklet);
1862 }
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001863}
1864
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001865static void ap_reset_domain(void)
1866{
1867 int i;
1868
Martin Schwidefsky889875a2015-06-26 16:55:35 +02001869 if (ap_domain_index == -1 || !ap_test_config_domain(ap_domain_index))
1870 return;
1871 for (i = 0; i < AP_DEVICES; i++)
1872 ap_reset_queue(AP_MKQID(i, ap_domain_index));
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001873}
1874
1875static void ap_reset_all(void)
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001876{
1877 int i, j;
1878
Ingo Tuchscherer170387a2014-09-08 13:24:13 +02001879 for (i = 0; i < AP_DOMAINS; i++) {
1880 if (!ap_test_config_domain(i))
1881 continue;
1882 for (j = 0; j < AP_DEVICES; j++) {
1883 if (!ap_test_config_card_id(j))
1884 continue;
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001885 ap_reset_queue(AP_MKQID(j, i));
Ingo Tuchscherer170387a2014-09-08 13:24:13 +02001886 }
1887 }
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001888}
1889
1890static struct reset_call ap_reset_call = {
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001891 .fn = ap_reset_all,
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001892};
1893
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001894/**
Felix Beck1749a812008-04-17 07:46:28 +02001895 * ap_module_init(): The module initialization code.
1896 *
1897 * Initializes the module.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001898 */
1899int __init ap_module_init(void)
1900{
Martin Schwidefsky889875a2015-06-26 16:55:35 +02001901 int max_domain_id;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001902 int rc, i;
1903
Martin Schwidefsky889875a2015-06-26 16:55:35 +02001904 if (ap_instructions_available() != 0) {
1905 pr_warn("The hardware system does not support AP instructions\n");
1906 return -ENODEV;
1907 }
1908
1909 /* Get AP configuration data if available */
1910 ap_init_configuration();
1911
1912 if (ap_configuration)
1913 max_domain_id = ap_max_domain_id ? : (AP_DOMAINS - 1);
1914 else
1915 max_domain_id = 15;
1916 if (ap_domain_index < -1 || ap_domain_index > max_domain_id) {
1917 pr_warn("%d is not a valid cryptographic domain\n",
1918 ap_domain_index);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001919 return -EINVAL;
1920 }
Felix Beck5314af62009-09-22 22:58:51 +02001921 /* In resume callback we need to know if the user had set the domain.
1922 * If so, we can not just reset it.
1923 */
1924 if (ap_domain_index >= 0)
1925 user_set_domain = 1;
1926
Felix Beckcb17a632008-12-25 13:38:41 +01001927 if (ap_interrupts_available()) {
Martin Schwidefskyf4eae942013-06-24 10:30:41 +02001928 rc = register_adapter_interrupt(&ap_airq);
1929 ap_airq_flag = (rc == 0);
Felix Beckcb17a632008-12-25 13:38:41 +01001930 }
1931
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001932 register_reset_call(&ap_reset_call);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001933
1934 /* Create /sys/bus/ap. */
1935 rc = bus_register(&ap_bus_type);
1936 if (rc)
1937 goto out;
1938 for (i = 0; ap_bus_attrs[i]; i++) {
1939 rc = bus_create_file(&ap_bus_type, ap_bus_attrs[i]);
1940 if (rc)
1941 goto out_bus;
1942 }
1943
1944 /* Create /sys/devices/ap. */
Mark McLoughlin035da162008-12-15 12:58:29 +00001945 ap_root_device = root_device_register("ap");
Thomas Meyerba8da212013-06-01 11:51:13 +02001946 rc = PTR_RET(ap_root_device);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001947 if (rc)
1948 goto out_bus;
1949
1950 ap_work_queue = create_singlethread_workqueue("kapwork");
1951 if (!ap_work_queue) {
1952 rc = -ENOMEM;
1953 goto out_root;
1954 }
1955
1956 if (ap_select_domain() == 0)
1957 ap_scan_bus(NULL);
1958
Felix Beck1749a812008-04-17 07:46:28 +02001959 /* Setup the AP bus rescan timer. */
Martin Schwidefskyfcd0d1f2015-07-23 10:55:59 +02001960 setup_timer(&ap_config_timer, ap_config_timeout, 0);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001961 add_timer(&ap_config_timer);
1962
Felix Beckfe137232008-07-14 09:59:08 +02001963 /* Setup the high resultion poll timer.
1964 * If we are running under z/VM adjust polling to z/VM polling rate.
1965 */
1966 if (MACHINE_IS_VM)
1967 poll_timeout = 1500000;
Felix Beck93521312009-12-07 12:52:00 +01001968 spin_lock_init(&ap_poll_timer_lock);
Felix Beckfe137232008-07-14 09:59:08 +02001969 hrtimer_init(&ap_poll_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
1970 ap_poll_timer.function = ap_poll_timeout;
1971
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001972 /* Start the low priority AP bus poll thread. */
1973 if (ap_thread_flag) {
1974 rc = ap_poll_thread_start();
1975 if (rc)
1976 goto out_work;
1977 }
1978
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +02001979 rc = register_pm_notifier(&ap_power_notifier);
1980 if (rc)
1981 goto out_pm;
1982
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001983 return 0;
1984
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +02001985out_pm:
1986 ap_poll_thread_stop();
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001987out_work:
1988 del_timer_sync(&ap_config_timer);
Felix Beckfe137232008-07-14 09:59:08 +02001989 hrtimer_cancel(&ap_poll_timer);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001990 destroy_workqueue(ap_work_queue);
1991out_root:
Mark McLoughlin035da162008-12-15 12:58:29 +00001992 root_device_unregister(ap_root_device);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001993out_bus:
1994 while (i--)
1995 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
1996 bus_unregister(&ap_bus_type);
1997out:
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001998 unregister_reset_call(&ap_reset_call);
Martin Schwidefskyf4eae942013-06-24 10:30:41 +02001999 if (ap_using_interrupts())
2000 unregister_adapter_interrupt(&ap_airq);
Martin Schwidefsky889875a2015-06-26 16:55:35 +02002001 kfree(ap_configuration);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002002 return rc;
2003}
2004
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002005/**
Felix Beck1749a812008-04-17 07:46:28 +02002006 * ap_modules_exit(): The module termination code
2007 *
2008 * Terminates the module.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002009 */
2010void ap_module_exit(void)
2011{
2012 int i;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002013
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01002014 ap_reset_domain();
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002015 ap_poll_thread_stop();
2016 del_timer_sync(&ap_config_timer);
Felix Beckfe137232008-07-14 09:59:08 +02002017 hrtimer_cancel(&ap_poll_timer);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002018 destroy_workqueue(ap_work_queue);
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01002019 tasklet_kill(&ap_tasklet);
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +02002020 bus_for_each_dev(&ap_bus_type, NULL, NULL, __ap_devices_unregister);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002021 for (i = 0; ap_bus_attrs[i]; i++)
2022 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
Martin Schwidefsky83e9d5d2015-07-17 13:43:18 +02002023 unregister_pm_notifier(&ap_power_notifier);
Ingo Tuchschererf60b8d42015-04-30 15:36:48 +02002024 root_device_unregister(ap_root_device);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002025 bus_unregister(&ap_bus_type);
Martin Schwidefsky889875a2015-06-26 16:55:35 +02002026 kfree(ap_configuration);
Ralph Wuerthner85eca852006-12-08 15:54:07 +01002027 unregister_reset_call(&ap_reset_call);
Martin Schwidefskyf4eae942013-06-24 10:30:41 +02002028 if (ap_using_interrupts())
2029 unregister_adapter_interrupt(&ap_airq);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002030}
2031
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002032module_init(ap_module_init);
2033module_exit(ap_module_exit);