blob: 51e6aa0e2e5823308c6730987257d33efb446954 [file] [log] [blame]
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001/*
Holger Dengler75014552012-08-28 16:41:50 +02002 * Copyright IBM Corp. 2006, 2012
Martin Schwidefsky1534c382006-09-20 15:58:25 +02003 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
4 * Martin Schwidefsky <schwidefsky@de.ibm.com>
5 * Ralph Wuerthner <rwuerthn@de.ibm.com>
Felix Beckcb17a632008-12-25 13:38:41 +01006 * Felix Beck <felix.beck@de.ibm.com>
Holger Dengler6bed05b2011-07-24 10:48:25 +02007 * Holger Dengler <hd@linux.vnet.ibm.com>
Martin Schwidefsky1534c382006-09-20 15:58:25 +02008 *
9 * Adjunct processor bus.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2, or (at your option)
14 * any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
Martin Schwidefsky136f7a12008-12-25 13:39:46 +010026#define KMSG_COMPONENT "ap"
27#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
28
Holger Dengler62d146f2011-01-05 12:47:38 +010029#include <linux/kernel_stat.h>
Martin Schwidefsky1534c382006-09-20 15:58:25 +020030#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/delay.h>
33#include <linux/err.h>
34#include <linux/interrupt.h>
35#include <linux/workqueue.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090036#include <linux/slab.h>
Martin Schwidefsky1534c382006-09-20 15:58:25 +020037#include <linux/notifier.h>
38#include <linux/kthread.h>
39#include <linux/mutex.h>
Ralph Wuerthner85eca852006-12-08 15:54:07 +010040#include <asm/reset.h>
Felix Beckcb17a632008-12-25 13:38:41 +010041#include <asm/airq.h>
Arun Sharma600634972011-07-26 16:09:06 -070042#include <linux/atomic.h>
Felix Beckcb17a632008-12-25 13:38:41 +010043#include <asm/isc.h>
Felix Beckfe137232008-07-14 09:59:08 +020044#include <linux/hrtimer.h>
45#include <linux/ktime.h>
David Howellsa0616cd2012-03-28 18:30:02 +010046#include <asm/facility.h>
Martin Schwidefsky1534c382006-09-20 15:58:25 +020047
48#include "ap_bus.h"
49
50/* Some prototypes. */
Al Viro4927b3f2006-12-06 19:18:20 +000051static void ap_scan_bus(struct work_struct *);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020052static void ap_poll_all(unsigned long);
Felix Beckfe137232008-07-14 09:59:08 +020053static enum hrtimer_restart ap_poll_timeout(struct hrtimer *);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020054static int ap_poll_thread_start(void);
55static void ap_poll_thread_stop(void);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +020056static void ap_request_timeout(unsigned long);
Felix Beckcb17a632008-12-25 13:38:41 +010057static inline void ap_schedule_poll_timer(void);
Felix Beck772f5472009-06-22 12:08:16 +020058static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags);
59static int ap_device_remove(struct device *dev);
60static int ap_device_probe(struct device *dev);
Martin Schwidefskyf4eae942013-06-24 10:30:41 +020061static void ap_interrupt_handler(struct airq_struct *airq);
Felix Beck772f5472009-06-22 12:08:16 +020062static void ap_reset(struct ap_device *ap_dev);
63static void ap_config_timeout(unsigned long ptr);
Felix Beck5314af62009-09-22 22:58:51 +020064static int ap_select_domain(void);
Holger Dengler75014552012-08-28 16:41:50 +020065static void ap_query_configuration(void);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020066
Felix Beck1749a812008-04-17 07:46:28 +020067/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +020068 * Module description.
69 */
70MODULE_AUTHOR("IBM Corporation");
Holger Dengler75014552012-08-28 16:41:50 +020071MODULE_DESCRIPTION("Adjunct Processor Bus driver, " \
72 "Copyright IBM Corp. 2006, 2012");
Martin Schwidefsky1534c382006-09-20 15:58:25 +020073MODULE_LICENSE("GPL");
Ingo Tuchscherer9da35452013-07-18 16:28:26 +020074MODULE_ALIAS("z90crypt");
Martin Schwidefsky1534c382006-09-20 15:58:25 +020075
Felix Beck1749a812008-04-17 07:46:28 +020076/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +020077 * Module parameter
78 */
79int ap_domain_index = -1; /* Adjunct Processor Domain Index */
Michael Veigelc1a42f42014-04-14 14:28:27 +020080module_param_named(domain, ap_domain_index, int, S_IRUSR|S_IRGRP);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020081MODULE_PARM_DESC(domain, "domain index for ap devices");
82EXPORT_SYMBOL(ap_domain_index);
83
Felix Beckb90b34c2008-02-09 18:24:30 +010084static int ap_thread_flag = 0;
Michael Veigelc1a42f42014-04-14 14:28:27 +020085module_param_named(poll_thread, ap_thread_flag, int, S_IRUSR|S_IRGRP);
Felix Beckb90b34c2008-02-09 18:24:30 +010086MODULE_PARM_DESC(poll_thread, "Turn on/off poll thread, default is 0 (off).");
Martin Schwidefsky1534c382006-09-20 15:58:25 +020087
88static struct device *ap_root_device = NULL;
Holger Dengler75014552012-08-28 16:41:50 +020089static struct ap_config_info *ap_configuration;
Christian Maaser43c207e62008-12-25 13:38:42 +010090static DEFINE_SPINLOCK(ap_device_list_lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +010091static LIST_HEAD(ap_device_list);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020092
Felix Beck1749a812008-04-17 07:46:28 +020093/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +020094 * Workqueue & timer for bus rescan.
95 */
96static struct workqueue_struct *ap_work_queue;
97static struct timer_list ap_config_timer;
98static int ap_config_time = AP_CONFIG_TIME;
Al Viro4927b3f2006-12-06 19:18:20 +000099static DECLARE_WORK(ap_config_work, ap_scan_bus);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200100
Felix Beck1749a812008-04-17 07:46:28 +0200101/*
Felix Beckcb17a632008-12-25 13:38:41 +0100102 * Tasklet & timer for AP request polling and interrupts
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200103 */
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200104static DECLARE_TASKLET(ap_tasklet, ap_poll_all, 0);
105static atomic_t ap_poll_requests = ATOMIC_INIT(0);
106static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait);
107static struct task_struct *ap_poll_kthread = NULL;
108static DEFINE_MUTEX(ap_poll_thread_mutex);
Felix Beck93521312009-12-07 12:52:00 +0100109static DEFINE_SPINLOCK(ap_poll_timer_lock);
Felix Beckfe137232008-07-14 09:59:08 +0200110static struct hrtimer ap_poll_timer;
111/* In LPAR poll with 4kHz frequency. Poll every 250000 nanoseconds.
112 * If z/VM change to 1500000 nanoseconds to adjust to z/VM polling.*/
113static unsigned long long poll_timeout = 250000;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200114
Felix Beck772f5472009-06-22 12:08:16 +0200115/* Suspend flag */
116static int ap_suspend_flag;
Felix Beck5314af62009-09-22 22:58:51 +0200117/* Flag to check if domain was set through module parameter domain=. This is
118 * important when supsend and resume is done in a z/VM environment where the
119 * domain might change. */
120static int user_set_domain = 0;
Felix Beck772f5472009-06-22 12:08:16 +0200121static struct bus_type ap_bus_type;
122
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200123/* Adapter interrupt definitions */
124static int ap_airq_flag;
125
126static struct airq_struct ap_airq = {
127 .handler = ap_interrupt_handler,
128 .isc = AP_ISC,
129};
130
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200131/**
Felix Beckcb17a632008-12-25 13:38:41 +0100132 * ap_using_interrupts() - Returns non-zero if interrupt support is
133 * available.
134 */
135static inline int ap_using_interrupts(void)
136{
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200137 return ap_airq_flag;
Felix Beckcb17a632008-12-25 13:38:41 +0100138}
139
140/**
Felix Beck1749a812008-04-17 07:46:28 +0200141 * ap_intructions_available() - Test if AP instructions are available.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200142 *
Felix Beck1749a812008-04-17 07:46:28 +0200143 * Returns 0 if the AP instructions are installed.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200144 */
145static inline int ap_instructions_available(void)
146{
147 register unsigned long reg0 asm ("0") = AP_MKQID(0,0);
148 register unsigned long reg1 asm ("1") = -ENODEV;
149 register unsigned long reg2 asm ("2") = 0UL;
150
151 asm volatile(
152 " .long 0xb2af0000\n" /* PQAP(TAPQ) */
153 "0: la %1,0\n"
154 "1:\n"
155 EX_TABLE(0b, 1b)
156 : "+d" (reg0), "+d" (reg1), "+d" (reg2) : : "cc" );
157 return reg1;
158}
159
160/**
Felix Beckcb17a632008-12-25 13:38:41 +0100161 * ap_interrupts_available(): Test if AP interrupts are available.
162 *
163 * Returns 1 if AP interrupts are available.
164 */
165static int ap_interrupts_available(void)
166{
Felix Beck53ec24b12011-01-05 12:46:44 +0100167 return test_facility(2) && test_facility(65);
Felix Beckcb17a632008-12-25 13:38:41 +0100168}
169
170/**
Holger Dengler75014552012-08-28 16:41:50 +0200171 * ap_configuration_available(): Test if AP configuration
172 * information is available.
173 *
174 * Returns 1 if AP configuration information is available.
175 */
Heiko Carstensc80773e2012-09-14 11:21:17 +0200176#ifdef CONFIG_64BIT
Holger Dengler75014552012-08-28 16:41:50 +0200177static int ap_configuration_available(void)
178{
179 return test_facility(2) && test_facility(12);
180}
Heiko Carstensc80773e2012-09-14 11:21:17 +0200181#endif
Holger Dengler75014552012-08-28 16:41:50 +0200182
183/**
Felix Beck1749a812008-04-17 07:46:28 +0200184 * ap_test_queue(): Test adjunct processor queue.
185 * @qid: The AP queue number
186 * @queue_depth: Pointer to queue depth value
187 * @device_type: Pointer to device type value
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200188 *
Felix Beck1749a812008-04-17 07:46:28 +0200189 * Returns AP queue status structure.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200190 */
191static inline struct ap_queue_status
192ap_test_queue(ap_qid_t qid, int *queue_depth, int *device_type)
193{
194 register unsigned long reg0 asm ("0") = qid;
195 register struct ap_queue_status reg1 asm ("1");
196 register unsigned long reg2 asm ("2") = 0UL;
197
198 asm volatile(".long 0xb2af0000" /* PQAP(TAPQ) */
199 : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
200 *device_type = (int) (reg2 >> 24);
201 *queue_depth = (int) (reg2 & 0xff);
202 return reg1;
203}
204
205/**
Felix Beck1749a812008-04-17 07:46:28 +0200206 * ap_reset_queue(): Reset adjunct processor queue.
207 * @qid: The AP queue number
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200208 *
Felix Beck1749a812008-04-17 07:46:28 +0200209 * Returns AP queue status structure.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200210 */
211static inline struct ap_queue_status ap_reset_queue(ap_qid_t qid)
212{
213 register unsigned long reg0 asm ("0") = qid | 0x01000000UL;
214 register struct ap_queue_status reg1 asm ("1");
215 register unsigned long reg2 asm ("2") = 0UL;
216
217 asm volatile(
218 ".long 0xb2af0000" /* PQAP(RAPQ) */
219 : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
220 return reg1;
221}
222
Felix Beckcb17a632008-12-25 13:38:41 +0100223#ifdef CONFIG_64BIT
224/**
225 * ap_queue_interruption_control(): Enable interruption for a specific AP.
226 * @qid: The AP queue number
227 * @ind: The notification indicator byte
228 *
229 * Returns AP queue status.
230 */
231static inline struct ap_queue_status
232ap_queue_interruption_control(ap_qid_t qid, void *ind)
233{
234 register unsigned long reg0 asm ("0") = qid | 0x03000000UL;
235 register unsigned long reg1_in asm ("1") = 0x0000800000000000UL | AP_ISC;
236 register struct ap_queue_status reg1_out asm ("1");
237 register void *reg2 asm ("2") = ind;
238 asm volatile(
Holger Denglera7475af2012-05-16 14:10:26 +0200239 ".long 0xb2af0000" /* PQAP(AQIC) */
Felix Beckcb17a632008-12-25 13:38:41 +0100240 : "+d" (reg0), "+d" (reg1_in), "=d" (reg1_out), "+d" (reg2)
241 :
242 : "cc" );
243 return reg1_out;
244}
245#endif
246
Holger Dengler6bed05b2011-07-24 10:48:25 +0200247#ifdef CONFIG_64BIT
248static inline struct ap_queue_status
249__ap_query_functions(ap_qid_t qid, unsigned int *functions)
Felix Beckb1f933d2011-01-05 12:47:44 +0100250{
251 register unsigned long reg0 asm ("0") = 0UL | qid | (1UL << 23);
Holger Dengler6bed05b2011-07-24 10:48:25 +0200252 register struct ap_queue_status reg1 asm ("1") = AP_QUEUE_STATUS_INVALID;
253 register unsigned long reg2 asm ("2");
Felix Beckb1f933d2011-01-05 12:47:44 +0100254
255 asm volatile(
Holger Denglera7475af2012-05-16 14:10:26 +0200256 ".long 0xb2af0000\n" /* PQAP(TAPQ) */
Holger Dengler6bed05b2011-07-24 10:48:25 +0200257 "0:\n"
258 EX_TABLE(0b, 0b)
259 : "+d" (reg0), "+d" (reg1), "=d" (reg2)
Felix Beckb1f933d2011-01-05 12:47:44 +0100260 :
261 : "cc");
262
Holger Dengler6bed05b2011-07-24 10:48:25 +0200263 *functions = (unsigned int)(reg2 >> 32);
Felix Beckb1f933d2011-01-05 12:47:44 +0100264 return reg1;
265}
Holger Dengler6bed05b2011-07-24 10:48:25 +0200266#endif
267
Holger Dengler75014552012-08-28 16:41:50 +0200268#ifdef CONFIG_64BIT
269static inline int __ap_query_configuration(struct ap_config_info *config)
270{
271 register unsigned long reg0 asm ("0") = 0x04000000UL;
272 register unsigned long reg1 asm ("1") = -EINVAL;
273 register unsigned char *reg2 asm ("2") = (unsigned char *)config;
274
275 asm volatile(
276 ".long 0xb2af0000\n" /* PQAP(QCI) */
277 "0: la %1,0\n"
278 "1:\n"
279 EX_TABLE(0b, 1b)
280 : "+d" (reg0), "+d" (reg1), "+d" (reg2)
281 :
282 : "cc");
283
284 return reg1;
285}
286#endif
287
Holger Dengler6bed05b2011-07-24 10:48:25 +0200288/**
289 * ap_query_functions(): Query supported functions.
290 * @qid: The AP queue number
291 * @functions: Pointer to functions field.
292 *
293 * Returns
294 * 0 on success.
295 * -ENODEV if queue not valid.
296 * -EBUSY if device busy.
297 * -EINVAL if query function is not supported
298 */
299static int ap_query_functions(ap_qid_t qid, unsigned int *functions)
300{
301#ifdef CONFIG_64BIT
302 struct ap_queue_status status;
303 int i;
304 status = __ap_query_functions(qid, functions);
305
306 for (i = 0; i < AP_MAX_RESET; i++) {
307 if (ap_queue_status_invalid_test(&status))
308 return -ENODEV;
309
310 switch (status.response_code) {
311 case AP_RESPONSE_NORMAL:
312 return 0;
313 case AP_RESPONSE_RESET_IN_PROGRESS:
314 case AP_RESPONSE_BUSY:
315 break;
316 case AP_RESPONSE_Q_NOT_AVAIL:
317 case AP_RESPONSE_DECONFIGURED:
318 case AP_RESPONSE_CHECKSTOPPED:
319 case AP_RESPONSE_INVALID_ADDRESS:
320 return -ENODEV;
321 case AP_RESPONSE_OTHERWISE_CHANGED:
322 break;
323 default:
324 break;
325 }
326 if (i < AP_MAX_RESET - 1) {
327 udelay(5);
328 status = __ap_query_functions(qid, functions);
329 }
330 }
331 return -EBUSY;
332#else
333 return -EINVAL;
334#endif
335}
Felix Beckb1f933d2011-01-05 12:47:44 +0100336
337/**
Felix Beckcb17a632008-12-25 13:38:41 +0100338 * ap_queue_enable_interruption(): Enable interruption on an AP.
339 * @qid: The AP queue number
340 * @ind: the notification indicator byte
341 *
342 * Enables interruption on AP queue via ap_queue_interruption_control(). Based
343 * on the return value it waits a while and tests the AP queue if interrupts
344 * have been switched on using ap_test_queue().
345 */
346static int ap_queue_enable_interruption(ap_qid_t qid, void *ind)
347{
348#ifdef CONFIG_64BIT
349 struct ap_queue_status status;
350 int t_depth, t_device_type, rc, i;
351
352 rc = -EBUSY;
353 status = ap_queue_interruption_control(qid, ind);
354
355 for (i = 0; i < AP_MAX_RESET; i++) {
356 switch (status.response_code) {
357 case AP_RESPONSE_NORMAL:
358 if (status.int_enabled)
359 return 0;
360 break;
361 case AP_RESPONSE_RESET_IN_PROGRESS:
362 case AP_RESPONSE_BUSY:
Holger Dengler8738e072012-07-02 12:39:59 +0200363 if (i < AP_MAX_RESET - 1) {
364 udelay(5);
365 status = ap_queue_interruption_control(qid,
366 ind);
367 continue;
368 }
Felix Beckcb17a632008-12-25 13:38:41 +0100369 break;
370 case AP_RESPONSE_Q_NOT_AVAIL:
371 case AP_RESPONSE_DECONFIGURED:
372 case AP_RESPONSE_CHECKSTOPPED:
373 case AP_RESPONSE_INVALID_ADDRESS:
374 return -ENODEV;
375 case AP_RESPONSE_OTHERWISE_CHANGED:
376 if (status.int_enabled)
377 return 0;
378 break;
379 default:
380 break;
381 }
382 if (i < AP_MAX_RESET - 1) {
383 udelay(5);
384 status = ap_test_queue(qid, &t_depth, &t_device_type);
385 }
386 }
387 return rc;
388#else
389 return -EINVAL;
390#endif
391}
392
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200393/**
Felix Beck1749a812008-04-17 07:46:28 +0200394 * __ap_send(): Send message to adjunct processor queue.
395 * @qid: The AP queue number
396 * @psmid: The program supplied message identifier
397 * @msg: The message text
398 * @length: The message length
Felix Becka6a5d732009-12-07 12:51:55 +0100399 * @special: Special Bit
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200400 *
Felix Beck1749a812008-04-17 07:46:28 +0200401 * Returns AP queue status structure.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200402 * Condition code 1 on NQAP can't happen because the L bit is 1.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200403 * Condition code 2 on NQAP also means the send is incomplete,
404 * because a segment boundary was reached. The NQAP is repeated.
405 */
406static inline struct ap_queue_status
Felix Becka6a5d732009-12-07 12:51:55 +0100407__ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length,
408 unsigned int special)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200409{
410 typedef struct { char _[length]; } msgblock;
411 register unsigned long reg0 asm ("0") = qid | 0x40000000UL;
412 register struct ap_queue_status reg1 asm ("1");
413 register unsigned long reg2 asm ("2") = (unsigned long) msg;
414 register unsigned long reg3 asm ("3") = (unsigned long) length;
415 register unsigned long reg4 asm ("4") = (unsigned int) (psmid >> 32);
Heiko Carstens7d6c3b42013-09-07 11:07:22 +0200416 register unsigned long reg5 asm ("5") = psmid & 0xffffffff;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200417
Felix Becka6a5d732009-12-07 12:51:55 +0100418 if (special == 1)
419 reg0 |= 0x400000UL;
420
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200421 asm volatile (
Holger Denglera7475af2012-05-16 14:10:26 +0200422 "0: .long 0xb2ad0042\n" /* NQAP */
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200423 " brc 2,0b"
424 : "+d" (reg0), "=d" (reg1), "+d" (reg2), "+d" (reg3)
425 : "d" (reg4), "d" (reg5), "m" (*(msgblock *) msg)
426 : "cc" );
427 return reg1;
428}
429
430int ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length)
431{
432 struct ap_queue_status status;
433
Felix Becka6a5d732009-12-07 12:51:55 +0100434 status = __ap_send(qid, psmid, msg, length, 0);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200435 switch (status.response_code) {
436 case AP_RESPONSE_NORMAL:
437 return 0;
438 case AP_RESPONSE_Q_FULL:
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200439 case AP_RESPONSE_RESET_IN_PROGRESS:
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200440 return -EBUSY;
Felix Becka6a5d732009-12-07 12:51:55 +0100441 case AP_RESPONSE_REQ_FAC_NOT_INST:
442 return -EINVAL;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200443 default: /* Device is gone. */
444 return -ENODEV;
445 }
446}
447EXPORT_SYMBOL(ap_send);
448
Felix Beck1749a812008-04-17 07:46:28 +0200449/**
450 * __ap_recv(): Receive message from adjunct processor queue.
451 * @qid: The AP queue number
452 * @psmid: Pointer to program supplied message identifier
453 * @msg: The message text
454 * @length: The message length
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200455 *
Felix Beck1749a812008-04-17 07:46:28 +0200456 * Returns AP queue status structure.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200457 * Condition code 1 on DQAP means the receive has taken place
458 * but only partially. The response is incomplete, hence the
459 * DQAP is repeated.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200460 * Condition code 2 on DQAP also means the receive is incomplete,
461 * this time because a segment boundary was reached. Again, the
462 * DQAP is repeated.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200463 * Note that gpr2 is used by the DQAP instruction to keep track of
464 * any 'residual' length, in case the instruction gets interrupted.
465 * Hence it gets zeroed before the instruction.
466 */
467static inline struct ap_queue_status
468__ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length)
469{
470 typedef struct { char _[length]; } msgblock;
471 register unsigned long reg0 asm("0") = qid | 0x80000000UL;
472 register struct ap_queue_status reg1 asm ("1");
473 register unsigned long reg2 asm("2") = 0UL;
474 register unsigned long reg4 asm("4") = (unsigned long) msg;
475 register unsigned long reg5 asm("5") = (unsigned long) length;
476 register unsigned long reg6 asm("6") = 0UL;
477 register unsigned long reg7 asm("7") = 0UL;
478
479
480 asm volatile(
Holger Denglera7475af2012-05-16 14:10:26 +0200481 "0: .long 0xb2ae0064\n" /* DQAP */
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200482 " brc 6,0b\n"
483 : "+d" (reg0), "=d" (reg1), "+d" (reg2),
484 "+d" (reg4), "+d" (reg5), "+d" (reg6), "+d" (reg7),
485 "=m" (*(msgblock *) msg) : : "cc" );
486 *psmid = (((unsigned long long) reg6) << 32) + reg7;
487 return reg1;
488}
489
490int ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length)
491{
492 struct ap_queue_status status;
493
494 status = __ap_recv(qid, psmid, msg, length);
495 switch (status.response_code) {
496 case AP_RESPONSE_NORMAL:
497 return 0;
498 case AP_RESPONSE_NO_PENDING_REPLY:
499 if (status.queue_empty)
500 return -ENOENT;
501 return -EBUSY;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200502 case AP_RESPONSE_RESET_IN_PROGRESS:
503 return -EBUSY;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200504 default:
505 return -ENODEV;
506 }
507}
508EXPORT_SYMBOL(ap_recv);
509
510/**
Felix Beck1749a812008-04-17 07:46:28 +0200511 * ap_query_queue(): Check if an AP queue is available.
512 * @qid: The AP queue number
513 * @queue_depth: Pointer to queue depth value
514 * @device_type: Pointer to device type value
515 *
516 * The test is repeated for AP_MAX_RESET times.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200517 */
518static int ap_query_queue(ap_qid_t qid, int *queue_depth, int *device_type)
519{
520 struct ap_queue_status status;
521 int t_depth, t_device_type, rc, i;
522
523 rc = -EBUSY;
524 for (i = 0; i < AP_MAX_RESET; i++) {
525 status = ap_test_queue(qid, &t_depth, &t_device_type);
526 switch (status.response_code) {
527 case AP_RESPONSE_NORMAL:
528 *queue_depth = t_depth + 1;
529 *device_type = t_device_type;
530 rc = 0;
531 break;
532 case AP_RESPONSE_Q_NOT_AVAIL:
533 rc = -ENODEV;
534 break;
535 case AP_RESPONSE_RESET_IN_PROGRESS:
536 break;
537 case AP_RESPONSE_DECONFIGURED:
538 rc = -ENODEV;
539 break;
540 case AP_RESPONSE_CHECKSTOPPED:
541 rc = -ENODEV;
542 break;
Felix Beckcb17a632008-12-25 13:38:41 +0100543 case AP_RESPONSE_INVALID_ADDRESS:
544 rc = -ENODEV;
545 break;
546 case AP_RESPONSE_OTHERWISE_CHANGED:
547 break;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200548 case AP_RESPONSE_BUSY:
549 break;
550 default:
551 BUG();
552 }
553 if (rc != -EBUSY)
554 break;
555 if (i < AP_MAX_RESET - 1)
556 udelay(5);
557 }
558 return rc;
559}
560
561/**
Felix Beck1749a812008-04-17 07:46:28 +0200562 * ap_init_queue(): Reset an AP queue.
563 * @qid: The AP queue number
564 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200565 * Reset an AP queue and wait for it to become available again.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200566 */
567static int ap_init_queue(ap_qid_t qid)
568{
569 struct ap_queue_status status;
570 int rc, dummy, i;
571
572 rc = -ENODEV;
573 status = ap_reset_queue(qid);
574 for (i = 0; i < AP_MAX_RESET; i++) {
575 switch (status.response_code) {
576 case AP_RESPONSE_NORMAL:
577 if (status.queue_empty)
578 rc = 0;
579 break;
580 case AP_RESPONSE_Q_NOT_AVAIL:
581 case AP_RESPONSE_DECONFIGURED:
582 case AP_RESPONSE_CHECKSTOPPED:
583 i = AP_MAX_RESET; /* return with -ENODEV */
584 break;
585 case AP_RESPONSE_RESET_IN_PROGRESS:
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200586 rc = -EBUSY;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200587 case AP_RESPONSE_BUSY:
588 default:
589 break;
590 }
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200591 if (rc != -ENODEV && rc != -EBUSY)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200592 break;
593 if (i < AP_MAX_RESET - 1) {
Ingo Tuchscherer91f3e3ea2013-11-20 10:47:13 +0100594 /* Time we are waiting until we give up (0.7sec * 90).
595 * Since the actual request (in progress) will not
596 * interrupted immediately for the reset command,
597 * we have to be patient. In worst case we have to
598 * wait 60sec + reset time (some msec).
599 */
600 schedule_timeout(AP_RESET_TIMEOUT);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200601 status = ap_test_queue(qid, &dummy, &dummy);
602 }
603 }
Felix Beckcb17a632008-12-25 13:38:41 +0100604 if (rc == 0 && ap_using_interrupts()) {
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200605 rc = ap_queue_enable_interruption(qid, ap_airq.lsi_ptr);
Felix Beckcb17a632008-12-25 13:38:41 +0100606 /* If interruption mode is supported by the machine,
607 * but an AP can not be enabled for interruption then
608 * the AP will be discarded. */
609 if (rc)
610 pr_err("Registering adapter interrupts for "
611 "AP %d failed\n", AP_QID_DEVICE(qid));
612 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200613 return rc;
614}
615
616/**
Felix Beck1749a812008-04-17 07:46:28 +0200617 * ap_increase_queue_count(): Arm request timeout.
618 * @ap_dev: Pointer to an AP device.
619 *
620 * Arm request timeout if an AP device was idle and a new request is submitted.
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200621 */
622static void ap_increase_queue_count(struct ap_device *ap_dev)
623{
624 int timeout = ap_dev->drv->request_timeout;
625
626 ap_dev->queue_count++;
627 if (ap_dev->queue_count == 1) {
628 mod_timer(&ap_dev->timeout, jiffies + timeout);
629 ap_dev->reset = AP_RESET_ARMED;
630 }
631}
632
633/**
Felix Beck1749a812008-04-17 07:46:28 +0200634 * ap_decrease_queue_count(): Decrease queue count.
635 * @ap_dev: Pointer to an AP device.
636 *
637 * If AP device is still alive, re-schedule request timeout if there are still
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200638 * pending requests.
639 */
640static void ap_decrease_queue_count(struct ap_device *ap_dev)
641{
642 int timeout = ap_dev->drv->request_timeout;
643
644 ap_dev->queue_count--;
645 if (ap_dev->queue_count > 0)
646 mod_timer(&ap_dev->timeout, jiffies + timeout);
647 else
Felix Beck1749a812008-04-17 07:46:28 +0200648 /*
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200649 * The timeout timer should to be disabled now - since
650 * del_timer_sync() is very expensive, we just tell via the
651 * reset flag to ignore the pending timeout timer.
652 */
653 ap_dev->reset = AP_RESET_IGNORE;
654}
655
Felix Beck1749a812008-04-17 07:46:28 +0200656/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200657 * AP device related attributes.
658 */
659static ssize_t ap_hwtype_show(struct device *dev,
660 struct device_attribute *attr, char *buf)
661{
662 struct ap_device *ap_dev = to_ap_dev(dev);
663 return snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->device_type);
664}
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200665
Christian Maaser43c207e62008-12-25 13:38:42 +0100666static DEVICE_ATTR(hwtype, 0444, ap_hwtype_show, NULL);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200667static ssize_t ap_depth_show(struct device *dev, struct device_attribute *attr,
668 char *buf)
669{
670 struct ap_device *ap_dev = to_ap_dev(dev);
671 return snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->queue_depth);
672}
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200673
Christian Maaser43c207e62008-12-25 13:38:42 +0100674static DEVICE_ATTR(depth, 0444, ap_depth_show, NULL);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200675static ssize_t ap_request_count_show(struct device *dev,
676 struct device_attribute *attr,
677 char *buf)
678{
679 struct ap_device *ap_dev = to_ap_dev(dev);
680 int rc;
681
682 spin_lock_bh(&ap_dev->lock);
683 rc = snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->total_request_count);
684 spin_unlock_bh(&ap_dev->lock);
685 return rc;
686}
687
688static DEVICE_ATTR(request_count, 0444, ap_request_count_show, NULL);
689
Holger Denglerb26bd942012-08-28 16:43:48 +0200690static ssize_t ap_requestq_count_show(struct device *dev,
691 struct device_attribute *attr, char *buf)
692{
693 struct ap_device *ap_dev = to_ap_dev(dev);
694 int rc;
695
696 spin_lock_bh(&ap_dev->lock);
697 rc = snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->requestq_count);
698 spin_unlock_bh(&ap_dev->lock);
699 return rc;
700}
701
702static DEVICE_ATTR(requestq_count, 0444, ap_requestq_count_show, NULL);
703
704static ssize_t ap_pendingq_count_show(struct device *dev,
705 struct device_attribute *attr, char *buf)
706{
707 struct ap_device *ap_dev = to_ap_dev(dev);
708 int rc;
709
710 spin_lock_bh(&ap_dev->lock);
711 rc = snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->pendingq_count);
712 spin_unlock_bh(&ap_dev->lock);
713 return rc;
714}
715
716static DEVICE_ATTR(pendingq_count, 0444, ap_pendingq_count_show, NULL);
717
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200718static ssize_t ap_modalias_show(struct device *dev,
719 struct device_attribute *attr, char *buf)
720{
721 return sprintf(buf, "ap:t%02X", to_ap_dev(dev)->device_type);
722}
723
724static DEVICE_ATTR(modalias, 0444, ap_modalias_show, NULL);
725
Holger Denglerb26bd942012-08-28 16:43:48 +0200726static ssize_t ap_functions_show(struct device *dev,
727 struct device_attribute *attr, char *buf)
728{
729 struct ap_device *ap_dev = to_ap_dev(dev);
730 return snprintf(buf, PAGE_SIZE, "0x%08X\n", ap_dev->functions);
731}
732
733static DEVICE_ATTR(ap_functions, 0444, ap_functions_show, NULL);
734
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200735static struct attribute *ap_dev_attrs[] = {
736 &dev_attr_hwtype.attr,
737 &dev_attr_depth.attr,
738 &dev_attr_request_count.attr,
Holger Denglerb26bd942012-08-28 16:43:48 +0200739 &dev_attr_requestq_count.attr,
740 &dev_attr_pendingq_count.attr,
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200741 &dev_attr_modalias.attr,
Holger Denglerb26bd942012-08-28 16:43:48 +0200742 &dev_attr_ap_functions.attr,
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200743 NULL
744};
745static struct attribute_group ap_dev_attr_group = {
746 .attrs = ap_dev_attrs
747};
748
749/**
Felix Beck1749a812008-04-17 07:46:28 +0200750 * ap_bus_match()
751 * @dev: Pointer to device
752 * @drv: Pointer to device_driver
753 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200754 * AP bus driver registration/unregistration.
755 */
756static int ap_bus_match(struct device *dev, struct device_driver *drv)
757{
758 struct ap_device *ap_dev = to_ap_dev(dev);
759 struct ap_driver *ap_drv = to_ap_drv(drv);
760 struct ap_device_id *id;
761
Felix Beck1749a812008-04-17 07:46:28 +0200762 /*
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200763 * Compare device type of the device with the list of
764 * supported types of the device_driver.
765 */
766 for (id = ap_drv->ids; id->match_flags; id++) {
767 if ((id->match_flags & AP_DEVICE_ID_MATCH_DEVICE_TYPE) &&
768 (id->dev_type != ap_dev->device_type))
769 continue;
770 return 1;
771 }
772 return 0;
773}
774
775/**
Felix Beck1749a812008-04-17 07:46:28 +0200776 * ap_uevent(): Uevent function for AP devices.
777 * @dev: Pointer to device
778 * @env: Pointer to kobj_uevent_env
779 *
780 * It sets up a single environment variable DEV_TYPE which contains the
781 * hardware device type.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200782 */
Kay Sievers7eff2e72007-08-14 15:15:12 +0200783static int ap_uevent (struct device *dev, struct kobj_uevent_env *env)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200784{
785 struct ap_device *ap_dev = to_ap_dev(dev);
Kay Sievers7eff2e72007-08-14 15:15:12 +0200786 int retval = 0;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200787
788 if (!ap_dev)
789 return -ENODEV;
790
791 /* Set up DEV_TYPE environment variable. */
Kay Sievers7eff2e72007-08-14 15:15:12 +0200792 retval = add_uevent_var(env, "DEV_TYPE=%04X", ap_dev->device_type);
Eric Rannaudbf624562007-03-30 22:23:12 -0700793 if (retval)
794 return retval;
795
Cornelia Huck66a4263b2006-12-04 15:40:10 +0100796 /* Add MODALIAS= */
Kay Sievers7eff2e72007-08-14 15:15:12 +0200797 retval = add_uevent_var(env, "MODALIAS=ap:t%02X", ap_dev->device_type);
Eric Rannaudbf624562007-03-30 22:23:12 -0700798
Eric Rannaudbf624562007-03-30 22:23:12 -0700799 return retval;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200800}
801
Felix Beck772f5472009-06-22 12:08:16 +0200802static int ap_bus_suspend(struct device *dev, pm_message_t state)
803{
804 struct ap_device *ap_dev = to_ap_dev(dev);
805 unsigned long flags;
806
807 if (!ap_suspend_flag) {
808 ap_suspend_flag = 1;
809
810 /* Disable scanning for devices, thus we do not want to scan
811 * for them after removing.
812 */
813 del_timer_sync(&ap_config_timer);
814 if (ap_work_queue != NULL) {
815 destroy_workqueue(ap_work_queue);
816 ap_work_queue = NULL;
817 }
Felix Beck5314af62009-09-22 22:58:51 +0200818
Felix Beck772f5472009-06-22 12:08:16 +0200819 tasklet_disable(&ap_tasklet);
820 }
821 /* Poll on the device until all requests are finished. */
822 do {
823 flags = 0;
Felix Beck95f15562009-09-11 10:28:51 +0200824 spin_lock_bh(&ap_dev->lock);
Felix Beck772f5472009-06-22 12:08:16 +0200825 __ap_poll_device(ap_dev, &flags);
Felix Beck95f15562009-09-11 10:28:51 +0200826 spin_unlock_bh(&ap_dev->lock);
Felix Beck772f5472009-06-22 12:08:16 +0200827 } while ((flags & 1) || (flags & 2));
828
Felix Beck5314af62009-09-22 22:58:51 +0200829 spin_lock_bh(&ap_dev->lock);
830 ap_dev->unregistered = 1;
831 spin_unlock_bh(&ap_dev->lock);
832
Felix Beck772f5472009-06-22 12:08:16 +0200833 return 0;
834}
835
836static int ap_bus_resume(struct device *dev)
837{
Felix Beck772f5472009-06-22 12:08:16 +0200838 struct ap_device *ap_dev = to_ap_dev(dev);
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200839 int rc;
Felix Beck772f5472009-06-22 12:08:16 +0200840
841 if (ap_suspend_flag) {
842 ap_suspend_flag = 0;
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200843 if (ap_interrupts_available()) {
844 if (!ap_using_interrupts()) {
845 rc = register_adapter_interrupt(&ap_airq);
846 ap_airq_flag = (rc == 0);
847 }
848 } else {
849 if (ap_using_interrupts()) {
850 unregister_adapter_interrupt(&ap_airq);
851 ap_airq_flag = 0;
852 }
853 }
Holger Dengler75014552012-08-28 16:41:50 +0200854 ap_query_configuration();
Felix Beck5314af62009-09-22 22:58:51 +0200855 if (!user_set_domain) {
856 ap_domain_index = -1;
857 ap_select_domain();
858 }
Felix Beck772f5472009-06-22 12:08:16 +0200859 init_timer(&ap_config_timer);
860 ap_config_timer.function = ap_config_timeout;
861 ap_config_timer.data = 0;
862 ap_config_timer.expires = jiffies + ap_config_time * HZ;
863 add_timer(&ap_config_timer);
864 ap_work_queue = create_singlethread_workqueue("kapwork");
865 if (!ap_work_queue)
866 return -ENOMEM;
867 tasklet_enable(&ap_tasklet);
868 if (!ap_using_interrupts())
869 ap_schedule_poll_timer();
870 else
871 tasklet_schedule(&ap_tasklet);
872 if (ap_thread_flag)
873 rc = ap_poll_thread_start();
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200874 else
875 rc = 0;
876 } else
877 rc = 0;
Felix Beck5314af62009-09-22 22:58:51 +0200878 if (AP_QID_QUEUE(ap_dev->qid) != ap_domain_index) {
879 spin_lock_bh(&ap_dev->lock);
880 ap_dev->qid = AP_MKQID(AP_QID_DEVICE(ap_dev->qid),
881 ap_domain_index);
882 spin_unlock_bh(&ap_dev->lock);
883 }
884 queue_work(ap_work_queue, &ap_config_work);
Felix Beck772f5472009-06-22 12:08:16 +0200885
886 return rc;
887}
888
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200889static struct bus_type ap_bus_type = {
890 .name = "ap",
891 .match = &ap_bus_match,
892 .uevent = &ap_uevent,
Felix Beck772f5472009-06-22 12:08:16 +0200893 .suspend = ap_bus_suspend,
894 .resume = ap_bus_resume
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200895};
896
897static int ap_device_probe(struct device *dev)
898{
899 struct ap_device *ap_dev = to_ap_dev(dev);
900 struct ap_driver *ap_drv = to_ap_drv(dev->driver);
901 int rc;
902
903 ap_dev->drv = ap_drv;
Ingo Tuchscherer666e68e2014-07-14 19:11:48 +0200904
905 spin_lock_bh(&ap_device_list_lock);
906 list_add(&ap_dev->list, &ap_device_list);
907 spin_unlock_bh(&ap_device_list_lock);
908
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200909 rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV;
Ingo Tuchscherer666e68e2014-07-14 19:11:48 +0200910 if (rc) {
Christian Maaser43c207e62008-12-25 13:38:42 +0100911 spin_lock_bh(&ap_device_list_lock);
Ingo Tuchscherer666e68e2014-07-14 19:11:48 +0200912 list_del_init(&ap_dev->list);
Christian Maaser43c207e62008-12-25 13:38:42 +0100913 spin_unlock_bh(&ap_device_list_lock);
Ralph Wuerthnerfaa582c2008-03-05 12:37:13 +0100914 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200915 return rc;
916}
917
918/**
Felix Beck1749a812008-04-17 07:46:28 +0200919 * __ap_flush_queue(): Flush requests.
920 * @ap_dev: Pointer to the AP device
921 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200922 * Flush all requests from the request/pending queue of an AP device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200923 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +0100924static void __ap_flush_queue(struct ap_device *ap_dev)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200925{
926 struct ap_message *ap_msg, *next;
927
928 list_for_each_entry_safe(ap_msg, next, &ap_dev->pendingq, list) {
929 list_del_init(&ap_msg->list);
930 ap_dev->pendingq_count--;
Holger Dengler54a8f562012-05-16 14:08:22 +0200931 ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200932 }
933 list_for_each_entry_safe(ap_msg, next, &ap_dev->requestq, list) {
934 list_del_init(&ap_msg->list);
935 ap_dev->requestq_count--;
Holger Dengler54a8f562012-05-16 14:08:22 +0200936 ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200937 }
938}
939
940void ap_flush_queue(struct ap_device *ap_dev)
941{
942 spin_lock_bh(&ap_dev->lock);
943 __ap_flush_queue(ap_dev);
944 spin_unlock_bh(&ap_dev->lock);
945}
946EXPORT_SYMBOL(ap_flush_queue);
947
948static int ap_device_remove(struct device *dev)
949{
950 struct ap_device *ap_dev = to_ap_dev(dev);
951 struct ap_driver *ap_drv = ap_dev->drv;
952
Ralph Wuerthner4e562962006-10-04 20:02:05 +0200953 ap_flush_queue(ap_dev);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200954 del_timer_sync(&ap_dev->timeout);
Christian Maaser43c207e62008-12-25 13:38:42 +0100955 spin_lock_bh(&ap_device_list_lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +0100956 list_del_init(&ap_dev->list);
Christian Maaser43c207e62008-12-25 13:38:42 +0100957 spin_unlock_bh(&ap_device_list_lock);
Ralph Wuerthnerfaa582c2008-03-05 12:37:13 +0100958 if (ap_drv->remove)
959 ap_drv->remove(ap_dev);
Ralph Wuerthnere675c0d2007-03-26 20:42:43 +0200960 spin_lock_bh(&ap_dev->lock);
961 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
962 spin_unlock_bh(&ap_dev->lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200963 return 0;
964}
965
966int ap_driver_register(struct ap_driver *ap_drv, struct module *owner,
967 char *name)
968{
969 struct device_driver *drv = &ap_drv->driver;
970
971 drv->bus = &ap_bus_type;
972 drv->probe = ap_device_probe;
973 drv->remove = ap_device_remove;
974 drv->owner = owner;
975 drv->name = name;
976 return driver_register(drv);
977}
978EXPORT_SYMBOL(ap_driver_register);
979
980void ap_driver_unregister(struct ap_driver *ap_drv)
981{
982 driver_unregister(&ap_drv->driver);
983}
984EXPORT_SYMBOL(ap_driver_unregister);
985
Holger Denglerdabecb22012-09-10 21:34:26 +0200986void ap_bus_force_rescan(void)
987{
Ingo Tuchscherer56bbe682013-04-12 17:52:08 +0200988 /* reconfigure the AP bus rescan timer. */
989 mod_timer(&ap_config_timer, jiffies + ap_config_time * HZ);
990 /* processing a asynchronous bus rescan */
991 queue_work(ap_work_queue, &ap_config_work);
992 flush_work(&ap_config_work);
Holger Denglerdabecb22012-09-10 21:34:26 +0200993}
994EXPORT_SYMBOL(ap_bus_force_rescan);
995
Felix Beck1749a812008-04-17 07:46:28 +0200996/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200997 * AP bus attributes.
998 */
999static ssize_t ap_domain_show(struct bus_type *bus, char *buf)
1000{
1001 return snprintf(buf, PAGE_SIZE, "%d\n", ap_domain_index);
1002}
1003
1004static BUS_ATTR(ap_domain, 0444, ap_domain_show, NULL);
1005
Ingo Tuchscherer91f3e3ea2013-11-20 10:47:13 +01001006static ssize_t ap_control_domain_mask_show(struct bus_type *bus, char *buf)
1007{
1008 if (ap_configuration != NULL) { /* QCI not supported */
1009 if (test_facility(76)) { /* format 1 - 256 bit domain field */
1010 return snprintf(buf, PAGE_SIZE,
1011 "0x%08x%08x%08x%08x%08x%08x%08x%08x\n",
1012 ap_configuration->adm[0], ap_configuration->adm[1],
1013 ap_configuration->adm[2], ap_configuration->adm[3],
1014 ap_configuration->adm[4], ap_configuration->adm[5],
1015 ap_configuration->adm[6], ap_configuration->adm[7]);
1016 } else { /* format 0 - 16 bit domain field */
1017 return snprintf(buf, PAGE_SIZE, "%08x%08x\n",
1018 ap_configuration->adm[0], ap_configuration->adm[1]);
1019 }
1020 } else {
1021 return snprintf(buf, PAGE_SIZE, "not supported\n");
1022 }
1023}
1024
1025static BUS_ATTR(ap_control_domain_mask, 0444,
1026 ap_control_domain_mask_show, NULL);
1027
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001028static ssize_t ap_config_time_show(struct bus_type *bus, char *buf)
1029{
1030 return snprintf(buf, PAGE_SIZE, "%d\n", ap_config_time);
1031}
1032
Felix Beckcb17a632008-12-25 13:38:41 +01001033static ssize_t ap_interrupts_show(struct bus_type *bus, char *buf)
1034{
1035 return snprintf(buf, PAGE_SIZE, "%d\n",
1036 ap_using_interrupts() ? 1 : 0);
1037}
1038
1039static BUS_ATTR(ap_interrupts, 0444, ap_interrupts_show, NULL);
1040
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001041static ssize_t ap_config_time_store(struct bus_type *bus,
1042 const char *buf, size_t count)
1043{
1044 int time;
1045
1046 if (sscanf(buf, "%d\n", &time) != 1 || time < 5 || time > 120)
1047 return -EINVAL;
1048 ap_config_time = time;
1049 if (!timer_pending(&ap_config_timer) ||
1050 !mod_timer(&ap_config_timer, jiffies + ap_config_time * HZ)) {
1051 ap_config_timer.expires = jiffies + ap_config_time * HZ;
1052 add_timer(&ap_config_timer);
1053 }
1054 return count;
1055}
1056
1057static BUS_ATTR(config_time, 0644, ap_config_time_show, ap_config_time_store);
1058
1059static ssize_t ap_poll_thread_show(struct bus_type *bus, char *buf)
1060{
1061 return snprintf(buf, PAGE_SIZE, "%d\n", ap_poll_kthread ? 1 : 0);
1062}
1063
1064static ssize_t ap_poll_thread_store(struct bus_type *bus,
1065 const char *buf, size_t count)
1066{
1067 int flag, rc;
1068
1069 if (sscanf(buf, "%d\n", &flag) != 1)
1070 return -EINVAL;
1071 if (flag) {
1072 rc = ap_poll_thread_start();
1073 if (rc)
1074 return rc;
1075 }
1076 else
1077 ap_poll_thread_stop();
1078 return count;
1079}
1080
1081static BUS_ATTR(poll_thread, 0644, ap_poll_thread_show, ap_poll_thread_store);
1082
Felix Beckfe137232008-07-14 09:59:08 +02001083static ssize_t poll_timeout_show(struct bus_type *bus, char *buf)
1084{
1085 return snprintf(buf, PAGE_SIZE, "%llu\n", poll_timeout);
1086}
1087
1088static ssize_t poll_timeout_store(struct bus_type *bus, const char *buf,
1089 size_t count)
1090{
1091 unsigned long long time;
1092 ktime_t hr_time;
1093
1094 /* 120 seconds = maximum poll interval */
Felix Beckcb17a632008-12-25 13:38:41 +01001095 if (sscanf(buf, "%llu\n", &time) != 1 || time < 1 ||
1096 time > 120000000000ULL)
Felix Beckfe137232008-07-14 09:59:08 +02001097 return -EINVAL;
1098 poll_timeout = time;
1099 hr_time = ktime_set(0, poll_timeout);
1100
1101 if (!hrtimer_is_queued(&ap_poll_timer) ||
Arjan van de Ven6c644ea2008-09-01 15:20:30 -07001102 !hrtimer_forward(&ap_poll_timer, hrtimer_get_expires(&ap_poll_timer), hr_time)) {
1103 hrtimer_set_expires(&ap_poll_timer, hr_time);
1104 hrtimer_start_expires(&ap_poll_timer, HRTIMER_MODE_ABS);
Felix Beckfe137232008-07-14 09:59:08 +02001105 }
1106 return count;
1107}
1108
1109static BUS_ATTR(poll_timeout, 0644, poll_timeout_show, poll_timeout_store);
1110
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001111static struct bus_attribute *const ap_bus_attrs[] = {
1112 &bus_attr_ap_domain,
Ingo Tuchscherer91f3e3ea2013-11-20 10:47:13 +01001113 &bus_attr_ap_control_domain_mask,
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001114 &bus_attr_config_time,
1115 &bus_attr_poll_thread,
Felix Beckcb17a632008-12-25 13:38:41 +01001116 &bus_attr_ap_interrupts,
Felix Beckfe137232008-07-14 09:59:08 +02001117 &bus_attr_poll_timeout,
1118 NULL,
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001119};
1120
Holger Dengler75014552012-08-28 16:41:50 +02001121static inline int ap_test_config(unsigned int *field, unsigned int nr)
1122{
1123 if (nr > 0xFFu)
1124 return 0;
1125 return ap_test_bit((field + (nr >> 5)), (nr & 0x1f));
1126}
1127
1128/*
1129 * ap_test_config_card_id(): Test, whether an AP card ID is configured.
1130 * @id AP card ID
1131 *
1132 * Returns 0 if the card is not configured
1133 * 1 if the card is configured or
1134 * if the configuration information is not available
1135 */
1136static inline int ap_test_config_card_id(unsigned int id)
1137{
1138 if (!ap_configuration)
1139 return 1;
1140 return ap_test_config(ap_configuration->apm, id);
1141}
1142
1143/*
1144 * ap_test_config_domain(): Test, whether an AP usage domain is configured.
1145 * @domain AP usage domain ID
1146 *
1147 * Returns 0 if the usage domain is not configured
1148 * 1 if the usage domain is configured or
1149 * if the configuration information is not available
1150 */
1151static inline int ap_test_config_domain(unsigned int domain)
1152{
1153 if (!ap_configuration)
1154 return 1;
1155 return ap_test_config(ap_configuration->aqm, domain);
1156}
1157
1158/**
1159 * ap_query_configuration(): Query AP configuration information.
1160 *
1161 * Query information of installed cards and configured domains from AP.
1162 */
1163static void ap_query_configuration(void)
1164{
1165#ifdef CONFIG_64BIT
1166 if (ap_configuration_available()) {
1167 if (!ap_configuration)
1168 ap_configuration =
1169 kzalloc(sizeof(struct ap_config_info),
1170 GFP_KERNEL);
1171 if (ap_configuration)
1172 __ap_query_configuration(ap_configuration);
1173 } else
1174 ap_configuration = NULL;
1175#else
1176 ap_configuration = NULL;
1177#endif
1178}
1179
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001180/**
Felix Beck1749a812008-04-17 07:46:28 +02001181 * ap_select_domain(): Select an AP domain.
1182 *
1183 * Pick one of the 16 AP domains.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001184 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +01001185static int ap_select_domain(void)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001186{
1187 int queue_depth, device_type, count, max_count, best_domain;
Holger Dengler75014552012-08-28 16:41:50 +02001188 ap_qid_t qid;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001189 int rc, i, j;
1190
Ingo Tuchscherer170387a2014-09-08 13:24:13 +02001191 /* IF APXA isn't installed, only 16 domains could be defined */
1192 if (!ap_configuration->ap_extended && (ap_domain_index > 15))
1193 return -EINVAL;
1194
Felix Beck1749a812008-04-17 07:46:28 +02001195 /*
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001196 * We want to use a single domain. Either the one specified with
1197 * the "domain=" parameter or the domain with the maximum number
1198 * of devices.
1199 */
1200 if (ap_domain_index >= 0 && ap_domain_index < AP_DOMAINS)
1201 /* Domain has already been selected. */
1202 return 0;
1203 best_domain = -1;
1204 max_count = 0;
1205 for (i = 0; i < AP_DOMAINS; i++) {
Holger Dengler75014552012-08-28 16:41:50 +02001206 if (!ap_test_config_domain(i))
1207 continue;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001208 count = 0;
1209 for (j = 0; j < AP_DEVICES; j++) {
Holger Dengler75014552012-08-28 16:41:50 +02001210 if (!ap_test_config_card_id(j))
1211 continue;
1212 qid = AP_MKQID(j, i);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001213 rc = ap_query_queue(qid, &queue_depth, &device_type);
1214 if (rc)
1215 continue;
1216 count++;
1217 }
1218 if (count > max_count) {
1219 max_count = count;
1220 best_domain = i;
1221 }
1222 }
1223 if (best_domain >= 0){
1224 ap_domain_index = best_domain;
1225 return 0;
1226 }
1227 return -ENODEV;
1228}
1229
1230/**
Felix Beck1749a812008-04-17 07:46:28 +02001231 * ap_probe_device_type(): Find the device type of an AP.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001232 * @ap_dev: pointer to the AP device.
Felix Beck1749a812008-04-17 07:46:28 +02001233 *
1234 * Find the device type if query queue returned a device type of 0.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001235 */
1236static int ap_probe_device_type(struct ap_device *ap_dev)
1237{
1238 static unsigned char msg[] = {
1239 0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
1240 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1241 0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,
1242 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1243 0x01,0x00,0x43,0x43,0x41,0x2d,0x41,0x50,
1244 0x50,0x4c,0x20,0x20,0x20,0x01,0x01,0x01,
1245 0x00,0x00,0x00,0x00,0x50,0x4b,0x00,0x00,
1246 0x00,0x00,0x01,0x1c,0x00,0x00,0x00,0x00,
1247 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1248 0x00,0x00,0x05,0xb8,0x00,0x00,0x00,0x00,
1249 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1250 0x70,0x00,0x41,0x00,0x00,0x00,0x00,0x00,
1251 0x00,0x00,0x54,0x32,0x01,0x00,0xa0,0x00,
1252 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1253 0x00,0x00,0x00,0x00,0xb8,0x05,0x00,0x00,
1254 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1255 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1256 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1257 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1258 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1259 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1260 0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,
1261 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1262 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,
1263 0x49,0x43,0x53,0x46,0x20,0x20,0x20,0x20,
1264 0x50,0x4b,0x0a,0x00,0x50,0x4b,0x43,0x53,
1265 0x2d,0x31,0x2e,0x32,0x37,0x00,0x11,0x22,
1266 0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,
1267 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,
1268 0x99,0x00,0x11,0x22,0x33,0x44,0x55,0x66,
1269 0x77,0x88,0x99,0x00,0x11,0x22,0x33,0x44,
1270 0x55,0x66,0x77,0x88,0x99,0x00,0x11,0x22,
1271 0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,
1272 0x11,0x22,0x33,0x5d,0x00,0x5b,0x00,0x77,
1273 0x88,0x1e,0x00,0x00,0x57,0x00,0x00,0x00,
1274 0x00,0x04,0x00,0x00,0x4f,0x00,0x00,0x00,
1275 0x03,0x02,0x00,0x00,0x40,0x01,0x00,0x01,
1276 0xce,0x02,0x68,0x2d,0x5f,0xa9,0xde,0x0c,
1277 0xf6,0xd2,0x7b,0x58,0x4b,0xf9,0x28,0x68,
1278 0x3d,0xb4,0xf4,0xef,0x78,0xd5,0xbe,0x66,
1279 0x63,0x42,0xef,0xf8,0xfd,0xa4,0xf8,0xb0,
1280 0x8e,0x29,0xc2,0xc9,0x2e,0xd8,0x45,0xb8,
1281 0x53,0x8c,0x6f,0x4e,0x72,0x8f,0x6c,0x04,
1282 0x9c,0x88,0xfc,0x1e,0xc5,0x83,0x55,0x57,
1283 0xf7,0xdd,0xfd,0x4f,0x11,0x36,0x95,0x5d,
1284 };
1285 struct ap_queue_status status;
1286 unsigned long long psmid;
1287 char *reply;
1288 int rc, i;
1289
1290 reply = (void *) get_zeroed_page(GFP_KERNEL);
1291 if (!reply) {
1292 rc = -ENOMEM;
1293 goto out;
1294 }
1295
1296 status = __ap_send(ap_dev->qid, 0x0102030405060708ULL,
Felix Becka6a5d732009-12-07 12:51:55 +01001297 msg, sizeof(msg), 0);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001298 if (status.response_code != AP_RESPONSE_NORMAL) {
1299 rc = -ENODEV;
1300 goto out_free;
1301 }
1302
1303 /* Wait for the test message to complete. */
1304 for (i = 0; i < 6; i++) {
1305 mdelay(300);
1306 status = __ap_recv(ap_dev->qid, &psmid, reply, 4096);
1307 if (status.response_code == AP_RESPONSE_NORMAL &&
1308 psmid == 0x0102030405060708ULL)
1309 break;
1310 }
1311 if (i < 6) {
1312 /* Got an answer. */
1313 if (reply[0] == 0x00 && reply[1] == 0x86)
1314 ap_dev->device_type = AP_DEVICE_TYPE_PCICC;
1315 else
1316 ap_dev->device_type = AP_DEVICE_TYPE_PCICA;
1317 rc = 0;
1318 } else
1319 rc = -ENODEV;
1320
1321out_free:
1322 free_page((unsigned long) reply);
1323out:
1324 return rc;
1325}
1326
Martin Schwidefskyf4eae942013-06-24 10:30:41 +02001327static void ap_interrupt_handler(struct airq_struct *airq)
Felix Beckcb17a632008-12-25 13:38:41 +01001328{
Heiko Carstens420f42e2013-01-02 15:18:18 +01001329 inc_irq_stat(IRQIO_APB);
Felix Beckcb17a632008-12-25 13:38:41 +01001330 tasklet_schedule(&ap_tasklet);
1331}
1332
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001333/**
Felix Beck1749a812008-04-17 07:46:28 +02001334 * __ap_scan_bus(): Scan the AP bus.
1335 * @dev: Pointer to device
1336 * @data: Pointer to data
1337 *
1338 * Scan the AP bus for new devices.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001339 */
1340static int __ap_scan_bus(struct device *dev, void *data)
1341{
1342 return to_ap_dev(dev)->qid == (ap_qid_t)(unsigned long) data;
1343}
1344
1345static void ap_device_release(struct device *dev)
1346{
1347 struct ap_device *ap_dev = to_ap_dev(dev);
1348
1349 kfree(ap_dev);
1350}
1351
Al Viro4927b3f2006-12-06 19:18:20 +00001352static void ap_scan_bus(struct work_struct *unused)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001353{
1354 struct ap_device *ap_dev;
1355 struct device *dev;
1356 ap_qid_t qid;
1357 int queue_depth, device_type;
Holger Dengler6bed05b2011-07-24 10:48:25 +02001358 unsigned int device_functions;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001359 int rc, i;
1360
Holger Dengler75014552012-08-28 16:41:50 +02001361 ap_query_configuration();
Ingo Tuchscherer56bbe682013-04-12 17:52:08 +02001362 if (ap_select_domain() != 0) {
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001363 return;
Ingo Tuchscherer56bbe682013-04-12 17:52:08 +02001364 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001365 for (i = 0; i < AP_DEVICES; i++) {
1366 qid = AP_MKQID(i, ap_domain_index);
1367 dev = bus_find_device(&ap_bus_type, NULL,
1368 (void *)(unsigned long)qid,
1369 __ap_scan_bus);
Holger Dengler75014552012-08-28 16:41:50 +02001370 if (ap_test_config_card_id(i))
1371 rc = ap_query_queue(qid, &queue_depth, &device_type);
1372 else
1373 rc = -ENODEV;
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001374 if (dev) {
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001375 if (rc == -EBUSY) {
1376 set_current_state(TASK_UNINTERRUPTIBLE);
1377 schedule_timeout(AP_RESET_TIMEOUT);
1378 rc = ap_query_queue(qid, &queue_depth,
1379 &device_type);
1380 }
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001381 ap_dev = to_ap_dev(dev);
1382 spin_lock_bh(&ap_dev->lock);
1383 if (rc || ap_dev->unregistered) {
1384 spin_unlock_bh(&ap_dev->lock);
Felix Beck5314af62009-09-22 22:58:51 +02001385 if (ap_dev->unregistered)
1386 i--;
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001387 device_unregister(dev);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001388 put_device(dev);
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001389 continue;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001390 }
1391 spin_unlock_bh(&ap_dev->lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001392 put_device(dev);
1393 continue;
1394 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001395 if (rc)
1396 continue;
1397 rc = ap_init_queue(qid);
1398 if (rc)
1399 continue;
1400 ap_dev = kzalloc(sizeof(*ap_dev), GFP_KERNEL);
1401 if (!ap_dev)
1402 break;
1403 ap_dev->qid = qid;
1404 ap_dev->queue_depth = queue_depth;
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001405 ap_dev->unregistered = 1;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001406 spin_lock_init(&ap_dev->lock);
1407 INIT_LIST_HEAD(&ap_dev->pendingq);
1408 INIT_LIST_HEAD(&ap_dev->requestq);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001409 INIT_LIST_HEAD(&ap_dev->list);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001410 setup_timer(&ap_dev->timeout, ap_request_timeout,
1411 (unsigned long) ap_dev);
Holger Dengler6bed05b2011-07-24 10:48:25 +02001412 switch (device_type) {
1413 case 0:
Holger Dengler1e2076f2012-08-28 16:48:29 +02001414 /* device type probing for old cards */
Holger Denglercf2d0072011-05-23 10:24:30 +02001415 if (ap_probe_device_type(ap_dev)) {
1416 kfree(ap_dev);
1417 continue;
1418 }
Holger Dengler6bed05b2011-07-24 10:48:25 +02001419 break;
Holger Dengler6bed05b2011-07-24 10:48:25 +02001420 default:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001421 ap_dev->device_type = device_type;
Holger Dengler6bed05b2011-07-24 10:48:25 +02001422 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001423
Holger Dengler1e2076f2012-08-28 16:48:29 +02001424 rc = ap_query_functions(qid, &device_functions);
1425 if (!rc)
1426 ap_dev->functions = device_functions;
1427 else
1428 ap_dev->functions = 0u;
1429
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001430 ap_dev->device.bus = &ap_bus_type;
1431 ap_dev->device.parent = ap_root_device;
Felix Beckedc44fa2009-09-11 10:28:52 +02001432 if (dev_set_name(&ap_dev->device, "card%02x",
1433 AP_QID_DEVICE(ap_dev->qid))) {
1434 kfree(ap_dev);
1435 continue;
1436 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001437 ap_dev->device.release = ap_device_release;
1438 rc = device_register(&ap_dev->device);
1439 if (rc) {
Sebastian Ottc6304932009-09-11 10:28:38 +02001440 put_device(&ap_dev->device);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001441 continue;
1442 }
1443 /* Add device attributes. */
1444 rc = sysfs_create_group(&ap_dev->device.kobj,
1445 &ap_dev_attr_group);
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001446 if (!rc) {
1447 spin_lock_bh(&ap_dev->lock);
1448 ap_dev->unregistered = 0;
1449 spin_unlock_bh(&ap_dev->lock);
1450 }
1451 else
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001452 device_unregister(&ap_dev->device);
1453 }
1454}
1455
1456static void
1457ap_config_timeout(unsigned long ptr)
1458{
1459 queue_work(ap_work_queue, &ap_config_work);
1460 ap_config_timer.expires = jiffies + ap_config_time * HZ;
1461 add_timer(&ap_config_timer);
1462}
1463
1464/**
Holger Denglerbc615de2011-11-14 11:19:04 +01001465 * __ap_schedule_poll_timer(): Schedule poll timer.
Felix Beck1749a812008-04-17 07:46:28 +02001466 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001467 * Set up the timer to run the poll tasklet
1468 */
Holger Denglerbc615de2011-11-14 11:19:04 +01001469static inline void __ap_schedule_poll_timer(void)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001470{
Felix Beck8d406c62009-07-24 12:39:53 +02001471 ktime_t hr_time;
Felix Beck93521312009-12-07 12:52:00 +01001472
1473 spin_lock_bh(&ap_poll_timer_lock);
Holger Denglerbc615de2011-11-14 11:19:04 +01001474 if (hrtimer_is_queued(&ap_poll_timer) || ap_suspend_flag)
Felix Beck93521312009-12-07 12:52:00 +01001475 goto out;
Felix Beck8d406c62009-07-24 12:39:53 +02001476 if (ktime_to_ns(hrtimer_expires_remaining(&ap_poll_timer)) <= 0) {
1477 hr_time = ktime_set(0, poll_timeout);
1478 hrtimer_forward_now(&ap_poll_timer, hr_time);
1479 hrtimer_restart(&ap_poll_timer);
1480 }
Felix Beck93521312009-12-07 12:52:00 +01001481out:
1482 spin_unlock_bh(&ap_poll_timer_lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001483}
1484
1485/**
Holger Denglerbc615de2011-11-14 11:19:04 +01001486 * ap_schedule_poll_timer(): Schedule poll timer.
1487 *
1488 * Set up the timer to run the poll tasklet
1489 */
1490static inline void ap_schedule_poll_timer(void)
1491{
1492 if (ap_using_interrupts())
1493 return;
1494 __ap_schedule_poll_timer();
1495}
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:
1516 atomic_dec(&ap_poll_requests);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001517 ap_decrease_queue_count(ap_dev);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001518 list_for_each_entry(ap_msg, &ap_dev->pendingq, list) {
1519 if (ap_msg->psmid != ap_dev->reply->psmid)
1520 continue;
1521 list_del_init(&ap_msg->list);
1522 ap_dev->pendingq_count--;
Holger Dengler54a8f562012-05-16 14:08:22 +02001523 ap_msg->receive(ap_dev, ap_msg, ap_dev->reply);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001524 break;
1525 }
1526 if (ap_dev->queue_count > 0)
1527 *flags |= 1;
1528 break;
1529 case AP_RESPONSE_NO_PENDING_REPLY:
1530 if (status.queue_empty) {
1531 /* The card shouldn't forget requests but who knows. */
Ralph Wuerthnere675c0d2007-03-26 20:42:43 +02001532 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001533 ap_dev->queue_count = 0;
1534 list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
1535 ap_dev->requestq_count += ap_dev->pendingq_count;
1536 ap_dev->pendingq_count = 0;
1537 } else
1538 *flags |= 2;
1539 break;
1540 default:
1541 return -ENODEV;
1542 }
1543 return 0;
1544}
1545
1546/**
Felix Beck1749a812008-04-17 07:46:28 +02001547 * ap_poll_write(): Send messages from the request queue to an AP device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001548 * @ap_dev: pointer to the AP device
1549 * @flags: pointer to control flags, bit 2^0 is set if another poll is
1550 * required, bit 2^1 is set if the poll timer needs to get armed
Felix Beck1749a812008-04-17 07:46:28 +02001551 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001552 * Returns 0 if the device is still present, -ENODEV if not.
1553 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +01001554static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001555{
1556 struct ap_queue_status status;
1557 struct ap_message *ap_msg;
1558
1559 if (ap_dev->requestq_count <= 0 ||
1560 ap_dev->queue_count >= ap_dev->queue_depth)
1561 return 0;
1562 /* Start the next request on the queue. */
1563 ap_msg = list_entry(ap_dev->requestq.next, struct ap_message, list);
1564 status = __ap_send(ap_dev->qid, ap_msg->psmid,
Felix Becka6a5d732009-12-07 12:51:55 +01001565 ap_msg->message, ap_msg->length, ap_msg->special);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001566 switch (status.response_code) {
1567 case AP_RESPONSE_NORMAL:
1568 atomic_inc(&ap_poll_requests);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001569 ap_increase_queue_count(ap_dev);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001570 list_move_tail(&ap_msg->list, &ap_dev->pendingq);
1571 ap_dev->requestq_count--;
1572 ap_dev->pendingq_count++;
1573 if (ap_dev->queue_count < ap_dev->queue_depth &&
1574 ap_dev->requestq_count > 0)
1575 *flags |= 1;
1576 *flags |= 2;
1577 break;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001578 case AP_RESPONSE_RESET_IN_PROGRESS:
Holger Denglerbc615de2011-11-14 11:19:04 +01001579 __ap_schedule_poll_timer();
1580 case AP_RESPONSE_Q_FULL:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001581 *flags |= 2;
1582 break;
1583 case AP_RESPONSE_MESSAGE_TOO_BIG:
Felix Becka6a5d732009-12-07 12:51:55 +01001584 case AP_RESPONSE_REQ_FAC_NOT_INST:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001585 return -EINVAL;
1586 default:
1587 return -ENODEV;
1588 }
1589 return 0;
1590}
1591
1592/**
Felix Beck1749a812008-04-17 07:46:28 +02001593 * ap_poll_queue(): Poll AP device for pending replies and send new messages.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001594 * @ap_dev: pointer to the bus device
1595 * @flags: pointer to control flags, bit 2^0 is set if another poll is
1596 * required, bit 2^1 is set if the poll timer needs to get armed
Felix Beck1749a812008-04-17 07:46:28 +02001597 *
1598 * Poll AP device for pending replies and send new messages. If either
1599 * ap_poll_read or ap_poll_write returns -ENODEV unregister the device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001600 * Returns 0.
1601 */
1602static inline int ap_poll_queue(struct ap_device *ap_dev, unsigned long *flags)
1603{
1604 int rc;
1605
1606 rc = ap_poll_read(ap_dev, flags);
1607 if (rc)
1608 return rc;
1609 return ap_poll_write(ap_dev, flags);
1610}
1611
1612/**
Felix Beck1749a812008-04-17 07:46:28 +02001613 * __ap_queue_message(): Queue a message to a device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001614 * @ap_dev: pointer to the AP device
1615 * @ap_msg: the message to be queued
Felix Beck1749a812008-04-17 07:46:28 +02001616 *
1617 * Queue a message to a device. Returns 0 if successful.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001618 */
1619static int __ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
1620{
1621 struct ap_queue_status status;
1622
1623 if (list_empty(&ap_dev->requestq) &&
1624 ap_dev->queue_count < ap_dev->queue_depth) {
1625 status = __ap_send(ap_dev->qid, ap_msg->psmid,
Felix Becka6a5d732009-12-07 12:51:55 +01001626 ap_msg->message, ap_msg->length,
1627 ap_msg->special);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001628 switch (status.response_code) {
1629 case AP_RESPONSE_NORMAL:
1630 list_add_tail(&ap_msg->list, &ap_dev->pendingq);
1631 atomic_inc(&ap_poll_requests);
1632 ap_dev->pendingq_count++;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001633 ap_increase_queue_count(ap_dev);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001634 ap_dev->total_request_count++;
1635 break;
1636 case AP_RESPONSE_Q_FULL:
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001637 case AP_RESPONSE_RESET_IN_PROGRESS:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001638 list_add_tail(&ap_msg->list, &ap_dev->requestq);
1639 ap_dev->requestq_count++;
1640 ap_dev->total_request_count++;
1641 return -EBUSY;
Felix Becka6a5d732009-12-07 12:51:55 +01001642 case AP_RESPONSE_REQ_FAC_NOT_INST:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001643 case AP_RESPONSE_MESSAGE_TOO_BIG:
Holger Dengler54a8f562012-05-16 14:08:22 +02001644 ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL));
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001645 return -EINVAL;
1646 default: /* Device is gone. */
Holger Dengler54a8f562012-05-16 14:08:22 +02001647 ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001648 return -ENODEV;
1649 }
1650 } else {
1651 list_add_tail(&ap_msg->list, &ap_dev->requestq);
1652 ap_dev->requestq_count++;
1653 ap_dev->total_request_count++;
1654 return -EBUSY;
1655 }
1656 ap_schedule_poll_timer();
1657 return 0;
1658}
1659
1660void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
1661{
1662 unsigned long flags;
1663 int rc;
1664
Holger Dengler54a8f562012-05-16 14:08:22 +02001665 /* For asynchronous message handling a valid receive-callback
1666 * is required. */
1667 BUG_ON(!ap_msg->receive);
1668
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001669 spin_lock_bh(&ap_dev->lock);
1670 if (!ap_dev->unregistered) {
1671 /* Make room on the queue by polling for finished requests. */
1672 rc = ap_poll_queue(ap_dev, &flags);
1673 if (!rc)
1674 rc = __ap_queue_message(ap_dev, ap_msg);
1675 if (!rc)
1676 wake_up(&ap_poll_wait);
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001677 if (rc == -ENODEV)
1678 ap_dev->unregistered = 1;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001679 } else {
Holger Dengler54a8f562012-05-16 14:08:22 +02001680 ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001681 rc = -ENODEV;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001682 }
1683 spin_unlock_bh(&ap_dev->lock);
1684 if (rc == -ENODEV)
1685 device_unregister(&ap_dev->device);
1686}
1687EXPORT_SYMBOL(ap_queue_message);
1688
1689/**
Felix Beck1749a812008-04-17 07:46:28 +02001690 * ap_cancel_message(): Cancel a crypto request.
1691 * @ap_dev: The AP device that has the message queued
1692 * @ap_msg: The message that is to be removed
1693 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001694 * Cancel a crypto request. This is done by removing the request
Felix Beck1749a812008-04-17 07:46:28 +02001695 * from the device pending or request queue. Note that the
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001696 * request stays on the AP queue. When it finishes the message
1697 * reply will be discarded because the psmid can't be found.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001698 */
1699void ap_cancel_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
1700{
1701 struct ap_message *tmp;
1702
1703 spin_lock_bh(&ap_dev->lock);
1704 if (!list_empty(&ap_msg->list)) {
1705 list_for_each_entry(tmp, &ap_dev->pendingq, list)
1706 if (tmp->psmid == ap_msg->psmid) {
1707 ap_dev->pendingq_count--;
1708 goto found;
1709 }
1710 ap_dev->requestq_count--;
1711 found:
1712 list_del_init(&ap_msg->list);
1713 }
1714 spin_unlock_bh(&ap_dev->lock);
1715}
1716EXPORT_SYMBOL(ap_cancel_message);
1717
1718/**
Felix Beck1749a812008-04-17 07:46:28 +02001719 * ap_poll_timeout(): AP receive polling for finished AP requests.
Felix Beckfe137232008-07-14 09:59:08 +02001720 * @unused: Unused pointer.
Felix Beck1749a812008-04-17 07:46:28 +02001721 *
Felix Beckfe137232008-07-14 09:59:08 +02001722 * Schedules the AP tasklet using a high resolution timer.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001723 */
Felix Beckfe137232008-07-14 09:59:08 +02001724static enum hrtimer_restart ap_poll_timeout(struct hrtimer *unused)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001725{
1726 tasklet_schedule(&ap_tasklet);
Felix Beckfe137232008-07-14 09:59:08 +02001727 return HRTIMER_NORESTART;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001728}
1729
1730/**
Felix Beck1749a812008-04-17 07:46:28 +02001731 * ap_reset(): Reset a not responding AP device.
1732 * @ap_dev: Pointer to the AP device
1733 *
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001734 * Reset a not responding AP device and move all requests from the
1735 * pending queue to the request queue.
1736 */
1737static void ap_reset(struct ap_device *ap_dev)
1738{
1739 int rc;
1740
1741 ap_dev->reset = AP_RESET_IGNORE;
1742 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
1743 ap_dev->queue_count = 0;
1744 list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
1745 ap_dev->requestq_count += ap_dev->pendingq_count;
1746 ap_dev->pendingq_count = 0;
1747 rc = ap_init_queue(ap_dev->qid);
1748 if (rc == -ENODEV)
1749 ap_dev->unregistered = 1;
Holger Dengler75464962011-12-01 13:32:23 +01001750 else
1751 __ap_schedule_poll_timer();
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001752}
1753
Christian Maaser43c207e62008-12-25 13:38:42 +01001754static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001755{
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001756 if (!ap_dev->unregistered) {
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001757 if (ap_poll_queue(ap_dev, flags))
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001758 ap_dev->unregistered = 1;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001759 if (ap_dev->reset == AP_RESET_DO)
1760 ap_reset(ap_dev);
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001761 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001762 return 0;
1763}
1764
Felix Beck1749a812008-04-17 07:46:28 +02001765/**
1766 * ap_poll_all(): Poll all AP devices.
1767 * @dummy: Unused variable
1768 *
1769 * Poll all AP devices on the bus in a round robin fashion. Continue
1770 * polling until bit 2^0 of the control flags is not set. If bit 2^1
1771 * of the control flags has been set arm the poll timer.
1772 */
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001773static void ap_poll_all(unsigned long dummy)
1774{
1775 unsigned long flags;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001776 struct ap_device *ap_dev;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001777
Felix Beckcb17a632008-12-25 13:38:41 +01001778 /* Reset the indicator if interrupts are used. Thus new interrupts can
1779 * be received. Doing it in the beginning of the tasklet is therefor
1780 * important that no requests on any AP get lost.
1781 */
1782 if (ap_using_interrupts())
Martin Schwidefskyf4eae942013-06-24 10:30:41 +02001783 xchg(ap_airq.lsi_ptr, 0);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001784 do {
1785 flags = 0;
Christian Maaser43c207e62008-12-25 13:38:42 +01001786 spin_lock(&ap_device_list_lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001787 list_for_each_entry(ap_dev, &ap_device_list, list) {
Felix Beck95f15562009-09-11 10:28:51 +02001788 spin_lock(&ap_dev->lock);
Christian Maaser43c207e62008-12-25 13:38:42 +01001789 __ap_poll_device(ap_dev, &flags);
Felix Beck95f15562009-09-11 10:28:51 +02001790 spin_unlock(&ap_dev->lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001791 }
Christian Maaser43c207e62008-12-25 13:38:42 +01001792 spin_unlock(&ap_device_list_lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001793 } while (flags & 1);
1794 if (flags & 2)
1795 ap_schedule_poll_timer();
1796}
1797
1798/**
Felix Beck1749a812008-04-17 07:46:28 +02001799 * ap_poll_thread(): Thread that polls for finished requests.
1800 * @data: Unused pointer
1801 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001802 * AP bus poll thread. The purpose of this thread is to poll for
1803 * finished requests in a loop if there is a "free" cpu - that is
1804 * a cpu that doesn't have anything better to do. The polling stops
1805 * as soon as there is another task or if all messages have been
1806 * delivered.
1807 */
1808static int ap_poll_thread(void *data)
1809{
1810 DECLARE_WAITQUEUE(wait, current);
1811 unsigned long flags;
1812 int requests;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001813 struct ap_device *ap_dev;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001814
Dongsheng Yang8698a742014-03-11 18:09:12 +08001815 set_user_nice(current, MAX_NICE);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001816 while (1) {
Felix Beck772f5472009-06-22 12:08:16 +02001817 if (ap_suspend_flag)
1818 return 0;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001819 if (need_resched()) {
1820 schedule();
1821 continue;
1822 }
1823 add_wait_queue(&ap_poll_wait, &wait);
1824 set_current_state(TASK_INTERRUPTIBLE);
1825 if (kthread_should_stop())
1826 break;
1827 requests = atomic_read(&ap_poll_requests);
1828 if (requests <= 0)
1829 schedule();
1830 set_current_state(TASK_RUNNING);
1831 remove_wait_queue(&ap_poll_wait, &wait);
1832
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001833 flags = 0;
Christian Maaser43c207e62008-12-25 13:38:42 +01001834 spin_lock_bh(&ap_device_list_lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001835 list_for_each_entry(ap_dev, &ap_device_list, list) {
Felix Beck95f15562009-09-11 10:28:51 +02001836 spin_lock(&ap_dev->lock);
Christian Maaser43c207e62008-12-25 13:38:42 +01001837 __ap_poll_device(ap_dev, &flags);
Felix Beck95f15562009-09-11 10:28:51 +02001838 spin_unlock(&ap_dev->lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001839 }
Christian Maaser43c207e62008-12-25 13:38:42 +01001840 spin_unlock_bh(&ap_device_list_lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001841 }
1842 set_current_state(TASK_RUNNING);
1843 remove_wait_queue(&ap_poll_wait, &wait);
1844 return 0;
1845}
1846
1847static int ap_poll_thread_start(void)
1848{
1849 int rc;
1850
Felix Beck772f5472009-06-22 12:08:16 +02001851 if (ap_using_interrupts() || ap_suspend_flag)
Felix Beckcb17a632008-12-25 13:38:41 +01001852 return 0;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001853 mutex_lock(&ap_poll_thread_mutex);
1854 if (!ap_poll_kthread) {
1855 ap_poll_kthread = kthread_run(ap_poll_thread, NULL, "appoll");
Thomas Meyerba8da212013-06-01 11:51:13 +02001856 rc = PTR_RET(ap_poll_kthread);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001857 if (rc)
1858 ap_poll_kthread = NULL;
1859 }
1860 else
1861 rc = 0;
1862 mutex_unlock(&ap_poll_thread_mutex);
1863 return rc;
1864}
1865
1866static void ap_poll_thread_stop(void)
1867{
1868 mutex_lock(&ap_poll_thread_mutex);
1869 if (ap_poll_kthread) {
1870 kthread_stop(ap_poll_kthread);
1871 ap_poll_kthread = NULL;
1872 }
1873 mutex_unlock(&ap_poll_thread_mutex);
1874}
1875
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001876/**
Felix Beck1749a812008-04-17 07:46:28 +02001877 * ap_request_timeout(): Handling of request timeouts
1878 * @data: Holds the AP device.
1879 *
1880 * Handles request timeouts.
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001881 */
1882static void ap_request_timeout(unsigned long data)
1883{
1884 struct ap_device *ap_dev = (struct ap_device *) data;
1885
Felix Beckcb17a632008-12-25 13:38:41 +01001886 if (ap_dev->reset == AP_RESET_ARMED) {
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001887 ap_dev->reset = AP_RESET_DO;
Felix Beckcb17a632008-12-25 13:38:41 +01001888
1889 if (ap_using_interrupts())
1890 tasklet_schedule(&ap_tasklet);
1891 }
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001892}
1893
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001894static void ap_reset_domain(void)
1895{
1896 int i;
1897
Ralph Wuerthner39aa7cf2007-10-12 16:11:29 +02001898 if (ap_domain_index != -1)
1899 for (i = 0; i < AP_DEVICES; i++)
1900 ap_reset_queue(AP_MKQID(i, ap_domain_index));
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001901}
1902
1903static void ap_reset_all(void)
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001904{
1905 int i, j;
1906
Ingo Tuchscherer170387a2014-09-08 13:24:13 +02001907 for (i = 0; i < AP_DOMAINS; i++) {
1908 if (!ap_test_config_domain(i))
1909 continue;
1910 for (j = 0; j < AP_DEVICES; j++) {
1911 if (!ap_test_config_card_id(j))
1912 continue;
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001913 ap_reset_queue(AP_MKQID(j, i));
Ingo Tuchscherer170387a2014-09-08 13:24:13 +02001914 }
1915 }
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001916}
1917
1918static struct reset_call ap_reset_call = {
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001919 .fn = ap_reset_all,
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001920};
1921
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001922/**
Felix Beck1749a812008-04-17 07:46:28 +02001923 * ap_module_init(): The module initialization code.
1924 *
1925 * Initializes the module.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001926 */
1927int __init ap_module_init(void)
1928{
1929 int rc, i;
1930
1931 if (ap_domain_index < -1 || ap_domain_index >= AP_DOMAINS) {
Martin Schwidefsky136f7a12008-12-25 13:39:46 +01001932 pr_warning("%d is not a valid cryptographic domain\n",
1933 ap_domain_index);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001934 return -EINVAL;
1935 }
Felix Beck5314af62009-09-22 22:58:51 +02001936 /* In resume callback we need to know if the user had set the domain.
1937 * If so, we can not just reset it.
1938 */
1939 if (ap_domain_index >= 0)
1940 user_set_domain = 1;
1941
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001942 if (ap_instructions_available() != 0) {
Martin Schwidefsky136f7a12008-12-25 13:39:46 +01001943 pr_warning("The hardware system does not support "
1944 "AP instructions\n");
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001945 return -ENODEV;
1946 }
Felix Beckcb17a632008-12-25 13:38:41 +01001947 if (ap_interrupts_available()) {
Martin Schwidefskyf4eae942013-06-24 10:30:41 +02001948 rc = register_adapter_interrupt(&ap_airq);
1949 ap_airq_flag = (rc == 0);
Felix Beckcb17a632008-12-25 13:38:41 +01001950 }
1951
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001952 register_reset_call(&ap_reset_call);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001953
1954 /* Create /sys/bus/ap. */
1955 rc = bus_register(&ap_bus_type);
1956 if (rc)
1957 goto out;
1958 for (i = 0; ap_bus_attrs[i]; i++) {
1959 rc = bus_create_file(&ap_bus_type, ap_bus_attrs[i]);
1960 if (rc)
1961 goto out_bus;
1962 }
1963
1964 /* Create /sys/devices/ap. */
Mark McLoughlin035da162008-12-15 12:58:29 +00001965 ap_root_device = root_device_register("ap");
Thomas Meyerba8da212013-06-01 11:51:13 +02001966 rc = PTR_RET(ap_root_device);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001967 if (rc)
1968 goto out_bus;
1969
1970 ap_work_queue = create_singlethread_workqueue("kapwork");
1971 if (!ap_work_queue) {
1972 rc = -ENOMEM;
1973 goto out_root;
1974 }
1975
Holger Dengler75014552012-08-28 16:41:50 +02001976 ap_query_configuration();
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001977 if (ap_select_domain() == 0)
1978 ap_scan_bus(NULL);
1979
Felix Beck1749a812008-04-17 07:46:28 +02001980 /* Setup the AP bus rescan timer. */
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001981 init_timer(&ap_config_timer);
1982 ap_config_timer.function = ap_config_timeout;
1983 ap_config_timer.data = 0;
1984 ap_config_timer.expires = jiffies + ap_config_time * HZ;
1985 add_timer(&ap_config_timer);
1986
Felix Beckfe137232008-07-14 09:59:08 +02001987 /* Setup the high resultion poll timer.
1988 * If we are running under z/VM adjust polling to z/VM polling rate.
1989 */
1990 if (MACHINE_IS_VM)
1991 poll_timeout = 1500000;
Felix Beck93521312009-12-07 12:52:00 +01001992 spin_lock_init(&ap_poll_timer_lock);
Felix Beckfe137232008-07-14 09:59:08 +02001993 hrtimer_init(&ap_poll_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
1994 ap_poll_timer.function = ap_poll_timeout;
1995
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001996 /* Start the low priority AP bus poll thread. */
1997 if (ap_thread_flag) {
1998 rc = ap_poll_thread_start();
1999 if (rc)
2000 goto out_work;
2001 }
2002
2003 return 0;
2004
2005out_work:
2006 del_timer_sync(&ap_config_timer);
Felix Beckfe137232008-07-14 09:59:08 +02002007 hrtimer_cancel(&ap_poll_timer);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002008 destroy_workqueue(ap_work_queue);
2009out_root:
Mark McLoughlin035da162008-12-15 12:58:29 +00002010 root_device_unregister(ap_root_device);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002011out_bus:
2012 while (i--)
2013 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
2014 bus_unregister(&ap_bus_type);
2015out:
Ralph Wuerthner85eca852006-12-08 15:54:07 +01002016 unregister_reset_call(&ap_reset_call);
Martin Schwidefskyf4eae942013-06-24 10:30:41 +02002017 if (ap_using_interrupts())
2018 unregister_adapter_interrupt(&ap_airq);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002019 return rc;
2020}
2021
2022static int __ap_match_all(struct device *dev, void *data)
2023{
2024 return 1;
2025}
2026
2027/**
Felix Beck1749a812008-04-17 07:46:28 +02002028 * ap_modules_exit(): The module termination code
2029 *
2030 * Terminates the module.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002031 */
2032void ap_module_exit(void)
2033{
2034 int i;
2035 struct device *dev;
2036
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01002037 ap_reset_domain();
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002038 ap_poll_thread_stop();
2039 del_timer_sync(&ap_config_timer);
Felix Beckfe137232008-07-14 09:59:08 +02002040 hrtimer_cancel(&ap_poll_timer);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002041 destroy_workqueue(ap_work_queue);
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01002042 tasklet_kill(&ap_tasklet);
Mark McLoughlin035da162008-12-15 12:58:29 +00002043 root_device_unregister(ap_root_device);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002044 while ((dev = bus_find_device(&ap_bus_type, NULL, NULL,
2045 __ap_match_all)))
2046 {
2047 device_unregister(dev);
2048 put_device(dev);
2049 }
2050 for (i = 0; ap_bus_attrs[i]; i++)
2051 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
2052 bus_unregister(&ap_bus_type);
Ralph Wuerthner85eca852006-12-08 15:54:07 +01002053 unregister_reset_call(&ap_reset_call);
Martin Schwidefskyf4eae942013-06-24 10:30:41 +02002054 if (ap_using_interrupts())
2055 unregister_adapter_interrupt(&ap_airq);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002056}
2057
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002058module_init(ap_module_init);
2059module_exit(ap_module_exit);