blob: 559a9dcdb15d274d4bad423bdbef6f01da769639 [file] [log] [blame]
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001/*
Holger Dengler75014552012-08-28 16:41:50 +02002 * Copyright IBM Corp. 2006, 2012
Martin Schwidefsky1534c382006-09-20 15:58:25 +02003 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
4 * Martin Schwidefsky <schwidefsky@de.ibm.com>
5 * Ralph Wuerthner <rwuerthn@de.ibm.com>
Felix Beckcb17a632008-12-25 13:38:41 +01006 * Felix Beck <felix.beck@de.ibm.com>
Holger Dengler6bed05b2011-07-24 10:48:25 +02007 * Holger Dengler <hd@linux.vnet.ibm.com>
Martin Schwidefsky1534c382006-09-20 15:58:25 +02008 *
9 * Adjunct processor bus.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2, or (at your option)
14 * any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
Martin Schwidefsky136f7a12008-12-25 13:39:46 +010026#define KMSG_COMPONENT "ap"
27#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
28
Holger Dengler62d146f2011-01-05 12:47:38 +010029#include <linux/kernel_stat.h>
Martin Schwidefsky1534c382006-09-20 15:58:25 +020030#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/delay.h>
33#include <linux/err.h>
34#include <linux/interrupt.h>
35#include <linux/workqueue.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090036#include <linux/slab.h>
Martin Schwidefsky1534c382006-09-20 15:58:25 +020037#include <linux/notifier.h>
38#include <linux/kthread.h>
39#include <linux/mutex.h>
Ralph Wuerthner85eca852006-12-08 15:54:07 +010040#include <asm/reset.h>
Felix Beckcb17a632008-12-25 13:38:41 +010041#include <asm/airq.h>
Arun Sharma600634972011-07-26 16:09:06 -070042#include <linux/atomic.h>
Felix Beckcb17a632008-12-25 13:38:41 +010043#include <asm/isc.h>
Felix Beckfe137232008-07-14 09:59:08 +020044#include <linux/hrtimer.h>
45#include <linux/ktime.h>
David Howellsa0616cd2012-03-28 18:30:02 +010046#include <asm/facility.h>
Kees Cook5d26a102014-11-20 17:05:53 -080047#include <linux/crypto.h>
Martin Schwidefsky1534c382006-09-20 15:58:25 +020048
49#include "ap_bus.h"
50
51/* Some prototypes. */
Al Viro4927b3f2006-12-06 19:18:20 +000052static void ap_scan_bus(struct work_struct *);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020053static void ap_poll_all(unsigned long);
Felix Beckfe137232008-07-14 09:59:08 +020054static enum hrtimer_restart ap_poll_timeout(struct hrtimer *);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020055static int ap_poll_thread_start(void);
56static void ap_poll_thread_stop(void);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +020057static void ap_request_timeout(unsigned long);
Felix Beckcb17a632008-12-25 13:38:41 +010058static inline void ap_schedule_poll_timer(void);
Felix Beck772f5472009-06-22 12:08:16 +020059static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags);
60static int ap_device_remove(struct device *dev);
61static int ap_device_probe(struct device *dev);
Martin Schwidefskyf4eae942013-06-24 10:30:41 +020062static void ap_interrupt_handler(struct airq_struct *airq);
Ingo Tuchschererc50a1602015-06-17 16:19:15 +020063static void ap_reset(struct ap_device *ap_dev, unsigned long *flags);
Felix Beck772f5472009-06-22 12:08:16 +020064static void ap_config_timeout(unsigned long ptr);
Felix Beck5314af62009-09-22 22:58:51 +020065static int ap_select_domain(void);
Holger Dengler75014552012-08-28 16:41:50 +020066static void ap_query_configuration(void);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020067
Felix Beck1749a812008-04-17 07:46:28 +020068/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +020069 * Module description.
70 */
71MODULE_AUTHOR("IBM Corporation");
Holger Dengler75014552012-08-28 16:41:50 +020072MODULE_DESCRIPTION("Adjunct Processor Bus driver, " \
73 "Copyright IBM Corp. 2006, 2012");
Martin Schwidefsky1534c382006-09-20 15:58:25 +020074MODULE_LICENSE("GPL");
Kees Cook5d26a102014-11-20 17:05:53 -080075MODULE_ALIAS_CRYPTO("z90crypt");
Martin Schwidefsky1534c382006-09-20 15:58:25 +020076
Felix Beck1749a812008-04-17 07:46:28 +020077/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +020078 * Module parameter
79 */
80int ap_domain_index = -1; /* Adjunct Processor Domain Index */
Michael Veigelc1a42f42014-04-14 14:28:27 +020081module_param_named(domain, ap_domain_index, int, S_IRUSR|S_IRGRP);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020082MODULE_PARM_DESC(domain, "domain index for ap devices");
83EXPORT_SYMBOL(ap_domain_index);
84
Felix Beckb90b34c2008-02-09 18:24:30 +010085static int ap_thread_flag = 0;
Michael Veigelc1a42f42014-04-14 14:28:27 +020086module_param_named(poll_thread, ap_thread_flag, int, S_IRUSR|S_IRGRP);
Felix Beckb90b34c2008-02-09 18:24:30 +010087MODULE_PARM_DESC(poll_thread, "Turn on/off poll thread, default is 0 (off).");
Martin Schwidefsky1534c382006-09-20 15:58:25 +020088
89static struct device *ap_root_device = NULL;
Holger Dengler75014552012-08-28 16:41:50 +020090static struct ap_config_info *ap_configuration;
Christian Maaser43c207e62008-12-25 13:38:42 +010091static DEFINE_SPINLOCK(ap_device_list_lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +010092static LIST_HEAD(ap_device_list);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020093
Felix Beck1749a812008-04-17 07:46:28 +020094/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +020095 * Workqueue & timer for bus rescan.
96 */
97static struct workqueue_struct *ap_work_queue;
98static struct timer_list ap_config_timer;
99static int ap_config_time = AP_CONFIG_TIME;
Al Viro4927b3f2006-12-06 19:18:20 +0000100static DECLARE_WORK(ap_config_work, ap_scan_bus);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200101
Felix Beck1749a812008-04-17 07:46:28 +0200102/*
Felix Beckcb17a632008-12-25 13:38:41 +0100103 * Tasklet & timer for AP request polling and interrupts
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200104 */
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200105static DECLARE_TASKLET(ap_tasklet, ap_poll_all, 0);
106static atomic_t ap_poll_requests = ATOMIC_INIT(0);
107static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait);
108static struct task_struct *ap_poll_kthread = NULL;
109static DEFINE_MUTEX(ap_poll_thread_mutex);
Felix Beck93521312009-12-07 12:52:00 +0100110static DEFINE_SPINLOCK(ap_poll_timer_lock);
Felix Beckfe137232008-07-14 09:59:08 +0200111static struct hrtimer ap_poll_timer;
112/* In LPAR poll with 4kHz frequency. Poll every 250000 nanoseconds.
113 * If z/VM change to 1500000 nanoseconds to adjust to z/VM polling.*/
114static unsigned long long poll_timeout = 250000;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200115
Felix Beck772f5472009-06-22 12:08:16 +0200116/* Suspend flag */
117static int ap_suspend_flag;
Felix Beck5314af62009-09-22 22:58:51 +0200118/* Flag to check if domain was set through module parameter domain=. This is
119 * important when supsend and resume is done in a z/VM environment where the
120 * domain might change. */
121static int user_set_domain = 0;
Felix Beck772f5472009-06-22 12:08:16 +0200122static struct bus_type ap_bus_type;
123
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200124/* Adapter interrupt definitions */
125static int ap_airq_flag;
126
127static struct airq_struct ap_airq = {
128 .handler = ap_interrupt_handler,
129 .isc = AP_ISC,
130};
131
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200132/**
Felix Beckcb17a632008-12-25 13:38:41 +0100133 * ap_using_interrupts() - Returns non-zero if interrupt support is
134 * available.
135 */
136static inline int ap_using_interrupts(void)
137{
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200138 return ap_airq_flag;
Felix Beckcb17a632008-12-25 13:38:41 +0100139}
140
141/**
Felix Beck1749a812008-04-17 07:46:28 +0200142 * ap_intructions_available() - Test if AP instructions are available.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200143 *
Felix Beck1749a812008-04-17 07:46:28 +0200144 * Returns 0 if the AP instructions are installed.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200145 */
146static inline int ap_instructions_available(void)
147{
148 register unsigned long reg0 asm ("0") = AP_MKQID(0,0);
149 register unsigned long reg1 asm ("1") = -ENODEV;
150 register unsigned long reg2 asm ("2") = 0UL;
151
152 asm volatile(
153 " .long 0xb2af0000\n" /* PQAP(TAPQ) */
154 "0: la %1,0\n"
155 "1:\n"
156 EX_TABLE(0b, 1b)
157 : "+d" (reg0), "+d" (reg1), "+d" (reg2) : : "cc" );
158 return reg1;
159}
160
161/**
Felix Beckcb17a632008-12-25 13:38:41 +0100162 * ap_interrupts_available(): Test if AP interrupts are available.
163 *
164 * Returns 1 if AP interrupts are available.
165 */
166static int ap_interrupts_available(void)
167{
Heiko Carstens86cd7412015-02-14 11:23:21 +0100168 return test_facility(65);
Felix Beckcb17a632008-12-25 13:38:41 +0100169}
170
171/**
Holger Dengler75014552012-08-28 16:41:50 +0200172 * ap_configuration_available(): Test if AP configuration
173 * information is available.
174 *
175 * Returns 1 if AP configuration information is available.
176 */
177static int ap_configuration_available(void)
178{
Heiko Carstens86cd7412015-02-14 11:23:21 +0100179 return test_facility(12);
Holger Dengler75014552012-08-28 16:41:50 +0200180}
181
182/**
Felix Beck1749a812008-04-17 07:46:28 +0200183 * ap_test_queue(): Test adjunct processor queue.
184 * @qid: The AP queue number
185 * @queue_depth: Pointer to queue depth value
186 * @device_type: Pointer to device type value
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200187 *
Felix Beck1749a812008-04-17 07:46:28 +0200188 * Returns AP queue status structure.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200189 */
190static inline struct ap_queue_status
191ap_test_queue(ap_qid_t qid, int *queue_depth, int *device_type)
192{
193 register unsigned long reg0 asm ("0") = qid;
194 register struct ap_queue_status reg1 asm ("1");
195 register unsigned long reg2 asm ("2") = 0UL;
196
197 asm volatile(".long 0xb2af0000" /* PQAP(TAPQ) */
198 : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
199 *device_type = (int) (reg2 >> 24);
200 *queue_depth = (int) (reg2 & 0xff);
201 return reg1;
202}
203
204/**
Ingo Tuchscherer5bc334b2015-01-23 13:27:04 +0100205 * ap_query_facilities(): PQAP(TAPQ) query facilities.
206 * @qid: The AP queue number
207 *
208 * Returns content of general register 2 after the PQAP(TAPQ)
209 * instruction was called.
210 */
211static inline unsigned long ap_query_facilities(ap_qid_t qid)
212{
213 register unsigned long reg0 asm ("0") = qid | 0x00800000UL;
214 register unsigned long reg1 asm ("1");
215 register unsigned long reg2 asm ("2") = 0UL;
216
217 asm volatile(".long 0xb2af0000" /* PQAP(TAPQ) */
218 : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
219 return reg2;
220}
221
222/**
Felix Beck1749a812008-04-17 07:46:28 +0200223 * ap_reset_queue(): Reset adjunct processor queue.
224 * @qid: The AP queue number
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200225 *
Felix Beck1749a812008-04-17 07:46:28 +0200226 * Returns AP queue status structure.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200227 */
228static inline struct ap_queue_status ap_reset_queue(ap_qid_t qid)
229{
230 register unsigned long reg0 asm ("0") = qid | 0x01000000UL;
231 register struct ap_queue_status reg1 asm ("1");
232 register unsigned long reg2 asm ("2") = 0UL;
233
234 asm volatile(
235 ".long 0xb2af0000" /* PQAP(RAPQ) */
236 : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
237 return reg1;
238}
239
Felix Beckcb17a632008-12-25 13:38:41 +0100240/**
241 * ap_queue_interruption_control(): Enable interruption for a specific AP.
242 * @qid: The AP queue number
243 * @ind: The notification indicator byte
244 *
245 * Returns AP queue status.
246 */
247static inline struct ap_queue_status
248ap_queue_interruption_control(ap_qid_t qid, void *ind)
249{
250 register unsigned long reg0 asm ("0") = qid | 0x03000000UL;
251 register unsigned long reg1_in asm ("1") = 0x0000800000000000UL | AP_ISC;
252 register struct ap_queue_status reg1_out asm ("1");
253 register void *reg2 asm ("2") = ind;
254 asm volatile(
Holger Denglera7475af2012-05-16 14:10:26 +0200255 ".long 0xb2af0000" /* PQAP(AQIC) */
Felix Beckcb17a632008-12-25 13:38:41 +0100256 : "+d" (reg0), "+d" (reg1_in), "=d" (reg1_out), "+d" (reg2)
257 :
258 : "cc" );
259 return reg1_out;
260}
Felix Beckcb17a632008-12-25 13:38:41 +0100261
Holger Dengler6bed05b2011-07-24 10:48:25 +0200262static inline struct ap_queue_status
263__ap_query_functions(ap_qid_t qid, unsigned int *functions)
Felix Beckb1f933d2011-01-05 12:47:44 +0100264{
265 register unsigned long reg0 asm ("0") = 0UL | qid | (1UL << 23);
Holger Dengler6bed05b2011-07-24 10:48:25 +0200266 register struct ap_queue_status reg1 asm ("1") = AP_QUEUE_STATUS_INVALID;
267 register unsigned long reg2 asm ("2");
Felix Beckb1f933d2011-01-05 12:47:44 +0100268
269 asm volatile(
Holger Denglera7475af2012-05-16 14:10:26 +0200270 ".long 0xb2af0000\n" /* PQAP(TAPQ) */
Holger Dengler6bed05b2011-07-24 10:48:25 +0200271 "0:\n"
272 EX_TABLE(0b, 0b)
273 : "+d" (reg0), "+d" (reg1), "=d" (reg2)
Felix Beckb1f933d2011-01-05 12:47:44 +0100274 :
275 : "cc");
276
Holger Dengler6bed05b2011-07-24 10:48:25 +0200277 *functions = (unsigned int)(reg2 >> 32);
Felix Beckb1f933d2011-01-05 12:47:44 +0100278 return reg1;
279}
Holger Dengler6bed05b2011-07-24 10:48:25 +0200280
Holger Dengler75014552012-08-28 16:41:50 +0200281static inline int __ap_query_configuration(struct ap_config_info *config)
282{
283 register unsigned long reg0 asm ("0") = 0x04000000UL;
284 register unsigned long reg1 asm ("1") = -EINVAL;
285 register unsigned char *reg2 asm ("2") = (unsigned char *)config;
286
287 asm volatile(
288 ".long 0xb2af0000\n" /* PQAP(QCI) */
289 "0: la %1,0\n"
290 "1:\n"
291 EX_TABLE(0b, 1b)
292 : "+d" (reg0), "+d" (reg1), "+d" (reg2)
293 :
294 : "cc");
295
296 return reg1;
297}
Holger Dengler75014552012-08-28 16:41:50 +0200298
Holger Dengler6bed05b2011-07-24 10:48:25 +0200299/**
300 * ap_query_functions(): Query supported functions.
301 * @qid: The AP queue number
302 * @functions: Pointer to functions field.
303 *
304 * Returns
305 * 0 on success.
306 * -ENODEV if queue not valid.
307 * -EBUSY if device busy.
308 * -EINVAL if query function is not supported
309 */
310static int ap_query_functions(ap_qid_t qid, unsigned int *functions)
311{
Holger Dengler6bed05b2011-07-24 10:48:25 +0200312 struct ap_queue_status status;
Ingo Tuchschererc50a1602015-06-17 16:19:15 +0200313
Holger Dengler6bed05b2011-07-24 10:48:25 +0200314 status = __ap_query_functions(qid, functions);
315
Ingo Tuchschererc50a1602015-06-17 16:19:15 +0200316 if (ap_queue_status_invalid_test(&status))
317 return -ENODEV;
Holger Dengler6bed05b2011-07-24 10:48:25 +0200318
Ingo Tuchschererc50a1602015-06-17 16:19:15 +0200319 switch (status.response_code) {
320 case AP_RESPONSE_NORMAL:
321 return 0;
322 case AP_RESPONSE_Q_NOT_AVAIL:
323 case AP_RESPONSE_DECONFIGURED:
324 case AP_RESPONSE_CHECKSTOPPED:
325 case AP_RESPONSE_INVALID_ADDRESS:
326 return -ENODEV;
327 case AP_RESPONSE_RESET_IN_PROGRESS:
328 case AP_RESPONSE_BUSY:
329 case AP_RESPONSE_OTHERWISE_CHANGED:
330 default:
331 return -EBUSY;
Holger Dengler6bed05b2011-07-24 10:48:25 +0200332 }
Holger Dengler6bed05b2011-07-24 10:48:25 +0200333}
Felix Beckb1f933d2011-01-05 12:47:44 +0100334
335/**
Felix Beckcb17a632008-12-25 13:38:41 +0100336 * ap_queue_enable_interruption(): Enable interruption on an AP.
337 * @qid: The AP queue number
338 * @ind: the notification indicator byte
339 *
340 * Enables interruption on AP queue via ap_queue_interruption_control(). Based
341 * on the return value it waits a while and tests the AP queue if interrupts
342 * have been switched on using ap_test_queue().
343 */
Ingo Tuchschererc50a1602015-06-17 16:19:15 +0200344static int ap_queue_enable_interruption(struct ap_device *ap_dev, void *ind)
Felix Beckcb17a632008-12-25 13:38:41 +0100345{
Felix Beckcb17a632008-12-25 13:38:41 +0100346 struct ap_queue_status status;
Felix Beckcb17a632008-12-25 13:38:41 +0100347
Ingo Tuchschererc50a1602015-06-17 16:19:15 +0200348 status = ap_queue_interruption_control(ap_dev->qid, ind);
349 switch (status.response_code) {
350 case AP_RESPONSE_NORMAL:
351 case AP_RESPONSE_OTHERWISE_CHANGED:
352 return 0;
353 case AP_RESPONSE_Q_NOT_AVAIL:
354 case AP_RESPONSE_DECONFIGURED:
355 case AP_RESPONSE_CHECKSTOPPED:
356 case AP_RESPONSE_INVALID_ADDRESS:
357 return -ENODEV;
358 case AP_RESPONSE_RESET_IN_PROGRESS:
359 case AP_RESPONSE_BUSY:
360 default:
361 return -EBUSY;
Felix Beckcb17a632008-12-25 13:38:41 +0100362 }
Felix Beckcb17a632008-12-25 13:38:41 +0100363}
364
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200365/**
Felix Beck1749a812008-04-17 07:46:28 +0200366 * __ap_send(): Send message to adjunct processor queue.
367 * @qid: The AP queue number
368 * @psmid: The program supplied message identifier
369 * @msg: The message text
370 * @length: The message length
Felix Becka6a5d732009-12-07 12:51:55 +0100371 * @special: Special Bit
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200372 *
Felix Beck1749a812008-04-17 07:46:28 +0200373 * Returns AP queue status structure.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200374 * Condition code 1 on NQAP can't happen because the L bit is 1.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200375 * Condition code 2 on NQAP also means the send is incomplete,
376 * because a segment boundary was reached. The NQAP is repeated.
377 */
378static inline struct ap_queue_status
Felix Becka6a5d732009-12-07 12:51:55 +0100379__ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length,
380 unsigned int special)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200381{
382 typedef struct { char _[length]; } msgblock;
383 register unsigned long reg0 asm ("0") = qid | 0x40000000UL;
384 register struct ap_queue_status reg1 asm ("1");
385 register unsigned long reg2 asm ("2") = (unsigned long) msg;
386 register unsigned long reg3 asm ("3") = (unsigned long) length;
387 register unsigned long reg4 asm ("4") = (unsigned int) (psmid >> 32);
Heiko Carstens7d6c3b42013-09-07 11:07:22 +0200388 register unsigned long reg5 asm ("5") = psmid & 0xffffffff;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200389
Felix Becka6a5d732009-12-07 12:51:55 +0100390 if (special == 1)
391 reg0 |= 0x400000UL;
392
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200393 asm volatile (
Holger Denglera7475af2012-05-16 14:10:26 +0200394 "0: .long 0xb2ad0042\n" /* NQAP */
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200395 " brc 2,0b"
396 : "+d" (reg0), "=d" (reg1), "+d" (reg2), "+d" (reg3)
397 : "d" (reg4), "d" (reg5), "m" (*(msgblock *) msg)
398 : "cc" );
399 return reg1;
400}
401
402int ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length)
403{
404 struct ap_queue_status status;
405
Felix Becka6a5d732009-12-07 12:51:55 +0100406 status = __ap_send(qid, psmid, msg, length, 0);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200407 switch (status.response_code) {
408 case AP_RESPONSE_NORMAL:
409 return 0;
410 case AP_RESPONSE_Q_FULL:
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200411 case AP_RESPONSE_RESET_IN_PROGRESS:
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200412 return -EBUSY;
Felix Becka6a5d732009-12-07 12:51:55 +0100413 case AP_RESPONSE_REQ_FAC_NOT_INST:
414 return -EINVAL;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200415 default: /* Device is gone. */
416 return -ENODEV;
417 }
418}
419EXPORT_SYMBOL(ap_send);
420
Felix Beck1749a812008-04-17 07:46:28 +0200421/**
422 * __ap_recv(): Receive message from adjunct processor queue.
423 * @qid: The AP queue number
424 * @psmid: Pointer to program supplied message identifier
425 * @msg: The message text
426 * @length: The message length
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200427 *
Felix Beck1749a812008-04-17 07:46:28 +0200428 * Returns AP queue status structure.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200429 * Condition code 1 on DQAP means the receive has taken place
430 * but only partially. The response is incomplete, hence the
431 * DQAP is repeated.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200432 * Condition code 2 on DQAP also means the receive is incomplete,
433 * this time because a segment boundary was reached. Again, the
434 * DQAP is repeated.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200435 * Note that gpr2 is used by the DQAP instruction to keep track of
436 * any 'residual' length, in case the instruction gets interrupted.
437 * Hence it gets zeroed before the instruction.
438 */
439static inline struct ap_queue_status
440__ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length)
441{
442 typedef struct { char _[length]; } msgblock;
443 register unsigned long reg0 asm("0") = qid | 0x80000000UL;
444 register struct ap_queue_status reg1 asm ("1");
445 register unsigned long reg2 asm("2") = 0UL;
446 register unsigned long reg4 asm("4") = (unsigned long) msg;
447 register unsigned long reg5 asm("5") = (unsigned long) length;
448 register unsigned long reg6 asm("6") = 0UL;
449 register unsigned long reg7 asm("7") = 0UL;
450
451
452 asm volatile(
Holger Denglera7475af2012-05-16 14:10:26 +0200453 "0: .long 0xb2ae0064\n" /* DQAP */
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200454 " brc 6,0b\n"
455 : "+d" (reg0), "=d" (reg1), "+d" (reg2),
456 "+d" (reg4), "+d" (reg5), "+d" (reg6), "+d" (reg7),
457 "=m" (*(msgblock *) msg) : : "cc" );
458 *psmid = (((unsigned long long) reg6) << 32) + reg7;
459 return reg1;
460}
461
462int ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length)
463{
464 struct ap_queue_status status;
465
466 status = __ap_recv(qid, psmid, msg, length);
467 switch (status.response_code) {
468 case AP_RESPONSE_NORMAL:
469 return 0;
470 case AP_RESPONSE_NO_PENDING_REPLY:
471 if (status.queue_empty)
472 return -ENOENT;
473 return -EBUSY;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200474 case AP_RESPONSE_RESET_IN_PROGRESS:
475 return -EBUSY;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200476 default:
477 return -ENODEV;
478 }
479}
480EXPORT_SYMBOL(ap_recv);
481
482/**
Ingo Tuchschererc50a1602015-06-17 16:19:15 +0200483 * __ap_schedule_poll_timer(): Schedule poll timer.
484 *
485 * Set up the timer to run the poll tasklet
486 */
487static inline void __ap_schedule_poll_timer(void)
488{
489 ktime_t hr_time;
490
491 spin_lock_bh(&ap_poll_timer_lock);
492 if (!hrtimer_is_queued(&ap_poll_timer) && !ap_suspend_flag) {
493 hr_time = ktime_set(0, poll_timeout);
494 hrtimer_forward_now(&ap_poll_timer, hr_time);
495 hrtimer_restart(&ap_poll_timer);
496 }
497 spin_unlock_bh(&ap_poll_timer_lock);
498}
499
500/**
501 * ap_schedule_poll_timer(): Schedule poll timer.
502 *
503 * Set up the timer to run the poll tasklet
504 */
505static inline void ap_schedule_poll_timer(void)
506{
507 if (ap_using_interrupts())
508 return;
509 __ap_schedule_poll_timer();
510}
511
512
513/**
Felix Beck1749a812008-04-17 07:46:28 +0200514 * ap_query_queue(): Check if an AP queue is available.
515 * @qid: The AP queue number
516 * @queue_depth: Pointer to queue depth value
517 * @device_type: Pointer to device type value
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200518 */
519static int ap_query_queue(ap_qid_t qid, int *queue_depth, int *device_type)
520{
521 struct ap_queue_status status;
Ingo Tuchschererc50a1602015-06-17 16:19:15 +0200522 int t_depth, t_device_type;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200523
Ingo Tuchschererc50a1602015-06-17 16:19:15 +0200524 status = ap_test_queue(qid, &t_depth, &t_device_type);
525 switch (status.response_code) {
526 case AP_RESPONSE_NORMAL:
527 *queue_depth = t_depth + 1;
528 *device_type = t_device_type;
529 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
Felix Beck1749a812008-04-17 07:46:28 +0200613/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200614 * AP device related attributes.
615 */
616static ssize_t ap_hwtype_show(struct device *dev,
617 struct device_attribute *attr, char *buf)
618{
619 struct ap_device *ap_dev = to_ap_dev(dev);
620 return snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->device_type);
621}
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200622
Christian Maaser43c207e62008-12-25 13:38:42 +0100623static DEVICE_ATTR(hwtype, 0444, ap_hwtype_show, NULL);
Ingo Tuchscherer42f4dd612014-10-02 14:48:46 +0200624
625static ssize_t ap_raw_hwtype_show(struct device *dev,
626 struct device_attribute *attr, char *buf)
627{
628 struct ap_device *ap_dev = to_ap_dev(dev);
629
630 return snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->raw_hwtype);
631}
632
633static DEVICE_ATTR(raw_hwtype, 0444, ap_raw_hwtype_show, NULL);
634
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200635static ssize_t ap_depth_show(struct device *dev, struct device_attribute *attr,
636 char *buf)
637{
638 struct ap_device *ap_dev = to_ap_dev(dev);
639 return snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->queue_depth);
640}
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200641
Christian Maaser43c207e62008-12-25 13:38:42 +0100642static DEVICE_ATTR(depth, 0444, ap_depth_show, NULL);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200643static ssize_t ap_request_count_show(struct device *dev,
644 struct device_attribute *attr,
645 char *buf)
646{
647 struct ap_device *ap_dev = to_ap_dev(dev);
648 int rc;
649
650 spin_lock_bh(&ap_dev->lock);
651 rc = snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->total_request_count);
652 spin_unlock_bh(&ap_dev->lock);
653 return rc;
654}
655
656static DEVICE_ATTR(request_count, 0444, ap_request_count_show, NULL);
657
Holger Denglerb26bd942012-08-28 16:43:48 +0200658static ssize_t ap_requestq_count_show(struct device *dev,
659 struct device_attribute *attr, char *buf)
660{
661 struct ap_device *ap_dev = to_ap_dev(dev);
662 int rc;
663
664 spin_lock_bh(&ap_dev->lock);
665 rc = snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->requestq_count);
666 spin_unlock_bh(&ap_dev->lock);
667 return rc;
668}
669
670static DEVICE_ATTR(requestq_count, 0444, ap_requestq_count_show, NULL);
671
672static ssize_t ap_pendingq_count_show(struct device *dev,
673 struct device_attribute *attr, char *buf)
674{
675 struct ap_device *ap_dev = to_ap_dev(dev);
676 int rc;
677
678 spin_lock_bh(&ap_dev->lock);
679 rc = snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->pendingq_count);
680 spin_unlock_bh(&ap_dev->lock);
681 return rc;
682}
683
684static DEVICE_ATTR(pendingq_count, 0444, ap_pendingq_count_show, NULL);
685
Ingo Tuchschererc50a1602015-06-17 16:19:15 +0200686static ssize_t ap_reset_show(struct device *dev,
687 struct device_attribute *attr, char *buf)
688{
689 struct ap_device *ap_dev = to_ap_dev(dev);
690 int rc = 0;
691
692 spin_lock_bh(&ap_dev->lock);
693 switch (ap_dev->reset) {
694 case AP_RESET_IGNORE:
695 rc = snprintf(buf, PAGE_SIZE, "No Reset Timer set.\n");
696 break;
697 case AP_RESET_ARMED:
698 rc = snprintf(buf, PAGE_SIZE, "Reset Timer armed.\n");
699 break;
700 case AP_RESET_DO:
701 rc = snprintf(buf, PAGE_SIZE, "Reset Timer expired.\n");
702 break;
703 case AP_RESET_IN_PROGRESS:
704 rc = snprintf(buf, PAGE_SIZE, "Reset in progress.\n");
705 break;
706 default:
707 break;
708 }
709 spin_unlock_bh(&ap_dev->lock);
710 return rc;
711}
712
713static DEVICE_ATTR(reset, 0444, ap_reset_show, NULL);
714
715static ssize_t ap_interrupt_show(struct device *dev,
716 struct device_attribute *attr, char *buf)
717{
718 struct ap_device *ap_dev = to_ap_dev(dev);
719 int rc = 0;
720
721 spin_lock_bh(&ap_dev->lock);
722 switch (ap_dev->interrupt) {
723 case AP_INTR_DISABLED:
724 rc = snprintf(buf, PAGE_SIZE, "Interrupts disabled.\n");
725 break;
726 case AP_INTR_ENABLED:
727 rc = snprintf(buf, PAGE_SIZE, "Interrupts enabled.\n");
728 break;
729 case AP_INTR_IN_PROGRESS:
730 rc = snprintf(buf, PAGE_SIZE, "Enable Interrupt pending.\n");
731 break;
732 }
733 spin_unlock_bh(&ap_dev->lock);
734 return rc;
735}
736
737static DEVICE_ATTR(interrupt, 0444, ap_interrupt_show, NULL);
738
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200739static ssize_t ap_modalias_show(struct device *dev,
740 struct device_attribute *attr, char *buf)
741{
Ingo Tuchschererc50a1602015-06-17 16:19:15 +0200742 return sprintf(buf, "ap:t%02X\n", to_ap_dev(dev)->device_type);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200743}
744
745static DEVICE_ATTR(modalias, 0444, ap_modalias_show, NULL);
746
Holger Denglerb26bd942012-08-28 16:43:48 +0200747static ssize_t ap_functions_show(struct device *dev,
748 struct device_attribute *attr, char *buf)
749{
750 struct ap_device *ap_dev = to_ap_dev(dev);
751 return snprintf(buf, PAGE_SIZE, "0x%08X\n", ap_dev->functions);
752}
753
754static DEVICE_ATTR(ap_functions, 0444, ap_functions_show, NULL);
755
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200756static struct attribute *ap_dev_attrs[] = {
757 &dev_attr_hwtype.attr,
Ingo Tuchscherer42f4dd612014-10-02 14:48:46 +0200758 &dev_attr_raw_hwtype.attr,
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200759 &dev_attr_depth.attr,
760 &dev_attr_request_count.attr,
Holger Denglerb26bd942012-08-28 16:43:48 +0200761 &dev_attr_requestq_count.attr,
762 &dev_attr_pendingq_count.attr,
Ingo Tuchschererc50a1602015-06-17 16:19:15 +0200763 &dev_attr_reset.attr,
764 &dev_attr_interrupt.attr,
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200765 &dev_attr_modalias.attr,
Holger Denglerb26bd942012-08-28 16:43:48 +0200766 &dev_attr_ap_functions.attr,
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200767 NULL
768};
769static struct attribute_group ap_dev_attr_group = {
770 .attrs = ap_dev_attrs
771};
772
773/**
Felix Beck1749a812008-04-17 07:46:28 +0200774 * ap_bus_match()
775 * @dev: Pointer to device
776 * @drv: Pointer to device_driver
777 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200778 * AP bus driver registration/unregistration.
779 */
780static int ap_bus_match(struct device *dev, struct device_driver *drv)
781{
782 struct ap_device *ap_dev = to_ap_dev(dev);
783 struct ap_driver *ap_drv = to_ap_drv(drv);
784 struct ap_device_id *id;
785
Felix Beck1749a812008-04-17 07:46:28 +0200786 /*
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200787 * Compare device type of the device with the list of
788 * supported types of the device_driver.
789 */
790 for (id = ap_drv->ids; id->match_flags; id++) {
791 if ((id->match_flags & AP_DEVICE_ID_MATCH_DEVICE_TYPE) &&
792 (id->dev_type != ap_dev->device_type))
793 continue;
794 return 1;
795 }
796 return 0;
797}
798
799/**
Felix Beck1749a812008-04-17 07:46:28 +0200800 * ap_uevent(): Uevent function for AP devices.
801 * @dev: Pointer to device
802 * @env: Pointer to kobj_uevent_env
803 *
804 * It sets up a single environment variable DEV_TYPE which contains the
805 * hardware device type.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200806 */
Kay Sievers7eff2e72007-08-14 15:15:12 +0200807static int ap_uevent (struct device *dev, struct kobj_uevent_env *env)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200808{
809 struct ap_device *ap_dev = to_ap_dev(dev);
Kay Sievers7eff2e72007-08-14 15:15:12 +0200810 int retval = 0;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200811
812 if (!ap_dev)
813 return -ENODEV;
814
815 /* Set up DEV_TYPE environment variable. */
Kay Sievers7eff2e72007-08-14 15:15:12 +0200816 retval = add_uevent_var(env, "DEV_TYPE=%04X", ap_dev->device_type);
Eric Rannaudbf624562007-03-30 22:23:12 -0700817 if (retval)
818 return retval;
819
Cornelia Huck66a4263b2006-12-04 15:40:10 +0100820 /* Add MODALIAS= */
Kay Sievers7eff2e72007-08-14 15:15:12 +0200821 retval = add_uevent_var(env, "MODALIAS=ap:t%02X", ap_dev->device_type);
Eric Rannaudbf624562007-03-30 22:23:12 -0700822
Eric Rannaudbf624562007-03-30 22:23:12 -0700823 return retval;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200824}
825
Felix Beck772f5472009-06-22 12:08:16 +0200826static int ap_bus_suspend(struct device *dev, pm_message_t state)
827{
828 struct ap_device *ap_dev = to_ap_dev(dev);
829 unsigned long flags;
830
831 if (!ap_suspend_flag) {
832 ap_suspend_flag = 1;
833
834 /* Disable scanning for devices, thus we do not want to scan
835 * for them after removing.
836 */
837 del_timer_sync(&ap_config_timer);
838 if (ap_work_queue != NULL) {
839 destroy_workqueue(ap_work_queue);
840 ap_work_queue = NULL;
841 }
Felix Beck5314af62009-09-22 22:58:51 +0200842
Felix Beck772f5472009-06-22 12:08:16 +0200843 tasklet_disable(&ap_tasklet);
844 }
845 /* Poll on the device until all requests are finished. */
846 do {
847 flags = 0;
Felix Beck95f15562009-09-11 10:28:51 +0200848 spin_lock_bh(&ap_dev->lock);
Felix Beck772f5472009-06-22 12:08:16 +0200849 __ap_poll_device(ap_dev, &flags);
Felix Beck95f15562009-09-11 10:28:51 +0200850 spin_unlock_bh(&ap_dev->lock);
Felix Beck772f5472009-06-22 12:08:16 +0200851 } while ((flags & 1) || (flags & 2));
852
Felix Beck5314af62009-09-22 22:58:51 +0200853 spin_lock_bh(&ap_dev->lock);
854 ap_dev->unregistered = 1;
855 spin_unlock_bh(&ap_dev->lock);
856
Felix Beck772f5472009-06-22 12:08:16 +0200857 return 0;
858}
859
860static int ap_bus_resume(struct device *dev)
861{
Felix Beck772f5472009-06-22 12:08:16 +0200862 struct ap_device *ap_dev = to_ap_dev(dev);
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200863 int rc;
Felix Beck772f5472009-06-22 12:08:16 +0200864
865 if (ap_suspend_flag) {
866 ap_suspend_flag = 0;
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200867 if (ap_interrupts_available()) {
868 if (!ap_using_interrupts()) {
869 rc = register_adapter_interrupt(&ap_airq);
870 ap_airq_flag = (rc == 0);
871 }
872 } else {
873 if (ap_using_interrupts()) {
874 unregister_adapter_interrupt(&ap_airq);
875 ap_airq_flag = 0;
876 }
877 }
Holger Dengler75014552012-08-28 16:41:50 +0200878 ap_query_configuration();
Felix Beck5314af62009-09-22 22:58:51 +0200879 if (!user_set_domain) {
880 ap_domain_index = -1;
881 ap_select_domain();
882 }
Felix Beck772f5472009-06-22 12:08:16 +0200883 init_timer(&ap_config_timer);
884 ap_config_timer.function = ap_config_timeout;
885 ap_config_timer.data = 0;
886 ap_config_timer.expires = jiffies + ap_config_time * HZ;
887 add_timer(&ap_config_timer);
888 ap_work_queue = create_singlethread_workqueue("kapwork");
889 if (!ap_work_queue)
890 return -ENOMEM;
891 tasklet_enable(&ap_tasklet);
892 if (!ap_using_interrupts())
893 ap_schedule_poll_timer();
894 else
895 tasklet_schedule(&ap_tasklet);
896 if (ap_thread_flag)
897 rc = ap_poll_thread_start();
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200898 else
899 rc = 0;
900 } else
901 rc = 0;
Felix Beck5314af62009-09-22 22:58:51 +0200902 if (AP_QID_QUEUE(ap_dev->qid) != ap_domain_index) {
903 spin_lock_bh(&ap_dev->lock);
904 ap_dev->qid = AP_MKQID(AP_QID_DEVICE(ap_dev->qid),
905 ap_domain_index);
906 spin_unlock_bh(&ap_dev->lock);
907 }
908 queue_work(ap_work_queue, &ap_config_work);
Felix Beck772f5472009-06-22 12:08:16 +0200909
910 return rc;
911}
912
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200913static struct bus_type ap_bus_type = {
914 .name = "ap",
915 .match = &ap_bus_match,
916 .uevent = &ap_uevent,
Felix Beck772f5472009-06-22 12:08:16 +0200917 .suspend = ap_bus_suspend,
918 .resume = ap_bus_resume
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200919};
920
921static int ap_device_probe(struct device *dev)
922{
923 struct ap_device *ap_dev = to_ap_dev(dev);
924 struct ap_driver *ap_drv = to_ap_drv(dev->driver);
925 int rc;
926
927 ap_dev->drv = ap_drv;
Ingo Tuchscherer666e68e2014-07-14 19:11:48 +0200928
929 spin_lock_bh(&ap_device_list_lock);
930 list_add(&ap_dev->list, &ap_device_list);
931 spin_unlock_bh(&ap_device_list_lock);
932
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200933 rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV;
Ingo Tuchscherer666e68e2014-07-14 19:11:48 +0200934 if (rc) {
Christian Maaser43c207e62008-12-25 13:38:42 +0100935 spin_lock_bh(&ap_device_list_lock);
Ingo Tuchscherer666e68e2014-07-14 19:11:48 +0200936 list_del_init(&ap_dev->list);
Christian Maaser43c207e62008-12-25 13:38:42 +0100937 spin_unlock_bh(&ap_device_list_lock);
Ingo Tuchschererc50a1602015-06-17 16:19:15 +0200938 } else {
939 if (ap_dev->reset == AP_RESET_IN_PROGRESS ||
940 ap_dev->interrupt == AP_INTR_IN_PROGRESS)
941 __ap_schedule_poll_timer();
Ralph Wuerthnerfaa582c2008-03-05 12:37:13 +0100942 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200943 return rc;
944}
945
946/**
Felix Beck1749a812008-04-17 07:46:28 +0200947 * __ap_flush_queue(): Flush requests.
948 * @ap_dev: Pointer to the AP device
949 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200950 * Flush all requests from the request/pending queue of an AP device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200951 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +0100952static void __ap_flush_queue(struct ap_device *ap_dev)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200953{
954 struct ap_message *ap_msg, *next;
955
956 list_for_each_entry_safe(ap_msg, next, &ap_dev->pendingq, list) {
957 list_del_init(&ap_msg->list);
958 ap_dev->pendingq_count--;
Holger Dengler54a8f562012-05-16 14:08:22 +0200959 ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200960 }
961 list_for_each_entry_safe(ap_msg, next, &ap_dev->requestq, list) {
962 list_del_init(&ap_msg->list);
963 ap_dev->requestq_count--;
Holger Dengler54a8f562012-05-16 14:08:22 +0200964 ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200965 }
966}
967
968void ap_flush_queue(struct ap_device *ap_dev)
969{
970 spin_lock_bh(&ap_dev->lock);
971 __ap_flush_queue(ap_dev);
972 spin_unlock_bh(&ap_dev->lock);
973}
974EXPORT_SYMBOL(ap_flush_queue);
975
976static int ap_device_remove(struct device *dev)
977{
978 struct ap_device *ap_dev = to_ap_dev(dev);
979 struct ap_driver *ap_drv = ap_dev->drv;
980
Ralph Wuerthner4e562962006-10-04 20:02:05 +0200981 ap_flush_queue(ap_dev);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200982 del_timer_sync(&ap_dev->timeout);
Christian Maaser43c207e62008-12-25 13:38:42 +0100983 spin_lock_bh(&ap_device_list_lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +0100984 list_del_init(&ap_dev->list);
Christian Maaser43c207e62008-12-25 13:38:42 +0100985 spin_unlock_bh(&ap_device_list_lock);
Ralph Wuerthnerfaa582c2008-03-05 12:37:13 +0100986 if (ap_drv->remove)
987 ap_drv->remove(ap_dev);
Ralph Wuerthnere675c0d2007-03-26 20:42:43 +0200988 spin_lock_bh(&ap_dev->lock);
989 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
990 spin_unlock_bh(&ap_dev->lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200991 return 0;
992}
993
994int ap_driver_register(struct ap_driver *ap_drv, struct module *owner,
995 char *name)
996{
997 struct device_driver *drv = &ap_drv->driver;
998
999 drv->bus = &ap_bus_type;
1000 drv->probe = ap_device_probe;
1001 drv->remove = ap_device_remove;
1002 drv->owner = owner;
1003 drv->name = name;
1004 return driver_register(drv);
1005}
1006EXPORT_SYMBOL(ap_driver_register);
1007
1008void ap_driver_unregister(struct ap_driver *ap_drv)
1009{
1010 driver_unregister(&ap_drv->driver);
1011}
1012EXPORT_SYMBOL(ap_driver_unregister);
1013
Holger Denglerdabecb22012-09-10 21:34:26 +02001014void ap_bus_force_rescan(void)
1015{
Ingo Tuchscherer56bbe682013-04-12 17:52:08 +02001016 /* reconfigure the AP bus rescan timer. */
1017 mod_timer(&ap_config_timer, jiffies + ap_config_time * HZ);
1018 /* processing a asynchronous bus rescan */
1019 queue_work(ap_work_queue, &ap_config_work);
1020 flush_work(&ap_config_work);
Holger Denglerdabecb22012-09-10 21:34:26 +02001021}
1022EXPORT_SYMBOL(ap_bus_force_rescan);
1023
Felix Beck1749a812008-04-17 07:46:28 +02001024/*
Ingo Tuchscherer5bc334b2015-01-23 13:27:04 +01001025 * ap_test_config(): helper function to extract the nrth bit
1026 * within the unsigned int array field.
1027 */
1028static inline int ap_test_config(unsigned int *field, unsigned int nr)
1029{
1030 if (nr > 0xFFu)
1031 return 0;
1032 return ap_test_bit((field + (nr >> 5)), (nr & 0x1f));
1033}
1034
1035/*
1036 * ap_test_config_card_id(): Test, whether an AP card ID is configured.
1037 * @id AP card ID
1038 *
1039 * Returns 0 if the card is not configured
1040 * 1 if the card is configured or
1041 * if the configuration information is not available
1042 */
1043static inline int ap_test_config_card_id(unsigned int id)
1044{
1045 if (!ap_configuration)
1046 return 1;
1047 return ap_test_config(ap_configuration->apm, id);
1048}
1049
1050/*
1051 * ap_test_config_domain(): Test, whether an AP usage domain is configured.
1052 * @domain AP usage domain ID
1053 *
1054 * Returns 0 if the usage domain is not configured
1055 * 1 if the usage domain is configured or
1056 * if the configuration information is not available
1057 */
1058static inline int ap_test_config_domain(unsigned int domain)
1059{
Ingo Tuchschererea96f782015-02-02 17:50:17 +01001060 if (!ap_configuration) /* QCI not supported */
1061 if (domain < 16)
1062 return 1; /* then domains 0...15 are configured */
1063 else
1064 return 0;
1065 else
1066 return ap_test_config(ap_configuration->aqm, domain);
Ingo Tuchscherer5bc334b2015-01-23 13:27:04 +01001067}
1068
1069/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001070 * AP bus attributes.
1071 */
1072static ssize_t ap_domain_show(struct bus_type *bus, char *buf)
1073{
1074 return snprintf(buf, PAGE_SIZE, "%d\n", ap_domain_index);
1075}
1076
1077static BUS_ATTR(ap_domain, 0444, ap_domain_show, NULL);
1078
Ingo Tuchscherer91f3e3ea2013-11-20 10:47:13 +01001079static ssize_t ap_control_domain_mask_show(struct bus_type *bus, char *buf)
1080{
1081 if (ap_configuration != NULL) { /* QCI not supported */
1082 if (test_facility(76)) { /* format 1 - 256 bit domain field */
1083 return snprintf(buf, PAGE_SIZE,
1084 "0x%08x%08x%08x%08x%08x%08x%08x%08x\n",
1085 ap_configuration->adm[0], ap_configuration->adm[1],
1086 ap_configuration->adm[2], ap_configuration->adm[3],
1087 ap_configuration->adm[4], ap_configuration->adm[5],
1088 ap_configuration->adm[6], ap_configuration->adm[7]);
1089 } else { /* format 0 - 16 bit domain field */
1090 return snprintf(buf, PAGE_SIZE, "%08x%08x\n",
1091 ap_configuration->adm[0], ap_configuration->adm[1]);
1092 }
1093 } else {
1094 return snprintf(buf, PAGE_SIZE, "not supported\n");
1095 }
1096}
1097
1098static BUS_ATTR(ap_control_domain_mask, 0444,
1099 ap_control_domain_mask_show, NULL);
1100
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001101static ssize_t ap_config_time_show(struct bus_type *bus, char *buf)
1102{
1103 return snprintf(buf, PAGE_SIZE, "%d\n", ap_config_time);
1104}
1105
Felix Beckcb17a632008-12-25 13:38:41 +01001106static ssize_t ap_interrupts_show(struct bus_type *bus, char *buf)
1107{
1108 return snprintf(buf, PAGE_SIZE, "%d\n",
1109 ap_using_interrupts() ? 1 : 0);
1110}
1111
1112static BUS_ATTR(ap_interrupts, 0444, ap_interrupts_show, NULL);
1113
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001114static ssize_t ap_config_time_store(struct bus_type *bus,
1115 const char *buf, size_t count)
1116{
1117 int time;
1118
1119 if (sscanf(buf, "%d\n", &time) != 1 || time < 5 || time > 120)
1120 return -EINVAL;
1121 ap_config_time = time;
1122 if (!timer_pending(&ap_config_timer) ||
1123 !mod_timer(&ap_config_timer, jiffies + ap_config_time * HZ)) {
1124 ap_config_timer.expires = jiffies + ap_config_time * HZ;
1125 add_timer(&ap_config_timer);
1126 }
1127 return count;
1128}
1129
1130static BUS_ATTR(config_time, 0644, ap_config_time_show, ap_config_time_store);
1131
1132static ssize_t ap_poll_thread_show(struct bus_type *bus, char *buf)
1133{
1134 return snprintf(buf, PAGE_SIZE, "%d\n", ap_poll_kthread ? 1 : 0);
1135}
1136
1137static ssize_t ap_poll_thread_store(struct bus_type *bus,
1138 const char *buf, size_t count)
1139{
1140 int flag, rc;
1141
1142 if (sscanf(buf, "%d\n", &flag) != 1)
1143 return -EINVAL;
1144 if (flag) {
1145 rc = ap_poll_thread_start();
1146 if (rc)
1147 return rc;
1148 }
1149 else
1150 ap_poll_thread_stop();
1151 return count;
1152}
1153
1154static BUS_ATTR(poll_thread, 0644, ap_poll_thread_show, ap_poll_thread_store);
1155
Felix Beckfe137232008-07-14 09:59:08 +02001156static ssize_t poll_timeout_show(struct bus_type *bus, char *buf)
1157{
1158 return snprintf(buf, PAGE_SIZE, "%llu\n", poll_timeout);
1159}
1160
1161static ssize_t poll_timeout_store(struct bus_type *bus, const char *buf,
1162 size_t count)
1163{
1164 unsigned long long time;
1165 ktime_t hr_time;
1166
1167 /* 120 seconds = maximum poll interval */
Felix Beckcb17a632008-12-25 13:38:41 +01001168 if (sscanf(buf, "%llu\n", &time) != 1 || time < 1 ||
1169 time > 120000000000ULL)
Felix Beckfe137232008-07-14 09:59:08 +02001170 return -EINVAL;
1171 poll_timeout = time;
1172 hr_time = ktime_set(0, poll_timeout);
1173
Ingo Tuchscherer8cc2af72015-04-28 10:31:44 +02001174 spin_lock_bh(&ap_poll_timer_lock);
1175 hrtimer_cancel(&ap_poll_timer);
1176 hrtimer_set_expires(&ap_poll_timer, hr_time);
1177 hrtimer_start_expires(&ap_poll_timer, HRTIMER_MODE_ABS);
1178 spin_unlock_bh(&ap_poll_timer_lock);
1179
Felix Beckfe137232008-07-14 09:59:08 +02001180 return count;
1181}
1182
1183static BUS_ATTR(poll_timeout, 0644, poll_timeout_show, poll_timeout_store);
1184
Ingo Tuchscherer5bc334b2015-01-23 13:27:04 +01001185static ssize_t ap_max_domain_id_show(struct bus_type *bus, char *buf)
1186{
1187 ap_qid_t qid;
1188 int i, nd, max_domain_id = -1;
1189 unsigned long fbits;
1190
1191 if (ap_configuration) {
1192 if (ap_domain_index >= 0 && ap_domain_index < AP_DOMAINS) {
1193 for (i = 0; i < AP_DEVICES; i++) {
1194 if (!ap_test_config_card_id(i))
1195 continue;
1196 qid = AP_MKQID(i, ap_domain_index);
1197 fbits = ap_query_facilities(qid);
1198 if (fbits & (1UL << 57)) {
1199 /* the N bit is 0, Nd field is filled */
1200 nd = (int)((fbits & 0x00FF0000UL)>>16);
1201 if (nd > 0)
1202 max_domain_id = nd;
1203 else
1204 max_domain_id = 15;
1205 } else {
1206 /* N bit is 1, max 16 domains */
1207 max_domain_id = 15;
1208 }
1209 break;
1210 }
1211 }
1212 } else {
1213 /* no APXA support, older machines with max 16 domains */
1214 max_domain_id = 15;
1215 }
1216 return snprintf(buf, PAGE_SIZE, "%d\n", max_domain_id);
1217}
1218
1219static BUS_ATTR(ap_max_domain_id, 0444, ap_max_domain_id_show, NULL);
1220
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001221static struct bus_attribute *const ap_bus_attrs[] = {
1222 &bus_attr_ap_domain,
Ingo Tuchscherer91f3e3ea2013-11-20 10:47:13 +01001223 &bus_attr_ap_control_domain_mask,
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001224 &bus_attr_config_time,
1225 &bus_attr_poll_thread,
Felix Beckcb17a632008-12-25 13:38:41 +01001226 &bus_attr_ap_interrupts,
Felix Beckfe137232008-07-14 09:59:08 +02001227 &bus_attr_poll_timeout,
Ingo Tuchscherer5bc334b2015-01-23 13:27:04 +01001228 &bus_attr_ap_max_domain_id,
Felix Beckfe137232008-07-14 09:59:08 +02001229 NULL,
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001230};
1231
Holger Dengler75014552012-08-28 16:41:50 +02001232/**
1233 * ap_query_configuration(): Query AP configuration information.
1234 *
1235 * Query information of installed cards and configured domains from AP.
1236 */
1237static void ap_query_configuration(void)
1238{
Holger Dengler75014552012-08-28 16:41:50 +02001239 if (ap_configuration_available()) {
1240 if (!ap_configuration)
1241 ap_configuration =
1242 kzalloc(sizeof(struct ap_config_info),
1243 GFP_KERNEL);
1244 if (ap_configuration)
1245 __ap_query_configuration(ap_configuration);
1246 } else
1247 ap_configuration = NULL;
Holger Dengler75014552012-08-28 16:41:50 +02001248}
1249
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001250/**
Felix Beck1749a812008-04-17 07:46:28 +02001251 * ap_select_domain(): Select an AP domain.
1252 *
1253 * Pick one of the 16 AP domains.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001254 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +01001255static int ap_select_domain(void)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001256{
1257 int queue_depth, device_type, count, max_count, best_domain;
Holger Dengler75014552012-08-28 16:41:50 +02001258 ap_qid_t qid;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001259 int rc, i, j;
1260
Ingo Tuchscherer170387a2014-09-08 13:24:13 +02001261 /* IF APXA isn't installed, only 16 domains could be defined */
1262 if (!ap_configuration->ap_extended && (ap_domain_index > 15))
1263 return -EINVAL;
1264
Felix Beck1749a812008-04-17 07:46:28 +02001265 /*
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001266 * We want to use a single domain. Either the one specified with
1267 * the "domain=" parameter or the domain with the maximum number
1268 * of devices.
1269 */
1270 if (ap_domain_index >= 0 && ap_domain_index < AP_DOMAINS)
1271 /* Domain has already been selected. */
1272 return 0;
1273 best_domain = -1;
1274 max_count = 0;
1275 for (i = 0; i < AP_DOMAINS; i++) {
Holger Dengler75014552012-08-28 16:41:50 +02001276 if (!ap_test_config_domain(i))
1277 continue;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001278 count = 0;
1279 for (j = 0; j < AP_DEVICES; j++) {
Holger Dengler75014552012-08-28 16:41:50 +02001280 if (!ap_test_config_card_id(j))
1281 continue;
1282 qid = AP_MKQID(j, i);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001283 rc = ap_query_queue(qid, &queue_depth, &device_type);
1284 if (rc)
1285 continue;
1286 count++;
1287 }
1288 if (count > max_count) {
1289 max_count = count;
1290 best_domain = i;
1291 }
1292 }
1293 if (best_domain >= 0){
1294 ap_domain_index = best_domain;
1295 return 0;
1296 }
1297 return -ENODEV;
1298}
1299
1300/**
Felix Beck1749a812008-04-17 07:46:28 +02001301 * ap_probe_device_type(): Find the device type of an AP.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001302 * @ap_dev: pointer to the AP device.
Felix Beck1749a812008-04-17 07:46:28 +02001303 *
1304 * Find the device type if query queue returned a device type of 0.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001305 */
1306static int ap_probe_device_type(struct ap_device *ap_dev)
1307{
1308 static unsigned char msg[] = {
1309 0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
1310 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1311 0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,
1312 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1313 0x01,0x00,0x43,0x43,0x41,0x2d,0x41,0x50,
1314 0x50,0x4c,0x20,0x20,0x20,0x01,0x01,0x01,
1315 0x00,0x00,0x00,0x00,0x50,0x4b,0x00,0x00,
1316 0x00,0x00,0x01,0x1c,0x00,0x00,0x00,0x00,
1317 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1318 0x00,0x00,0x05,0xb8,0x00,0x00,0x00,0x00,
1319 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1320 0x70,0x00,0x41,0x00,0x00,0x00,0x00,0x00,
1321 0x00,0x00,0x54,0x32,0x01,0x00,0xa0,0x00,
1322 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1323 0x00,0x00,0x00,0x00,0xb8,0x05,0x00,0x00,
1324 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1325 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1326 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1327 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1328 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1329 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1330 0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,
1331 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1332 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,
1333 0x49,0x43,0x53,0x46,0x20,0x20,0x20,0x20,
1334 0x50,0x4b,0x0a,0x00,0x50,0x4b,0x43,0x53,
1335 0x2d,0x31,0x2e,0x32,0x37,0x00,0x11,0x22,
1336 0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,
1337 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,
1338 0x99,0x00,0x11,0x22,0x33,0x44,0x55,0x66,
1339 0x77,0x88,0x99,0x00,0x11,0x22,0x33,0x44,
1340 0x55,0x66,0x77,0x88,0x99,0x00,0x11,0x22,
1341 0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,
1342 0x11,0x22,0x33,0x5d,0x00,0x5b,0x00,0x77,
1343 0x88,0x1e,0x00,0x00,0x57,0x00,0x00,0x00,
1344 0x00,0x04,0x00,0x00,0x4f,0x00,0x00,0x00,
1345 0x03,0x02,0x00,0x00,0x40,0x01,0x00,0x01,
1346 0xce,0x02,0x68,0x2d,0x5f,0xa9,0xde,0x0c,
1347 0xf6,0xd2,0x7b,0x58,0x4b,0xf9,0x28,0x68,
1348 0x3d,0xb4,0xf4,0xef,0x78,0xd5,0xbe,0x66,
1349 0x63,0x42,0xef,0xf8,0xfd,0xa4,0xf8,0xb0,
1350 0x8e,0x29,0xc2,0xc9,0x2e,0xd8,0x45,0xb8,
1351 0x53,0x8c,0x6f,0x4e,0x72,0x8f,0x6c,0x04,
1352 0x9c,0x88,0xfc,0x1e,0xc5,0x83,0x55,0x57,
1353 0xf7,0xdd,0xfd,0x4f,0x11,0x36,0x95,0x5d,
1354 };
1355 struct ap_queue_status status;
1356 unsigned long long psmid;
1357 char *reply;
1358 int rc, i;
1359
1360 reply = (void *) get_zeroed_page(GFP_KERNEL);
1361 if (!reply) {
1362 rc = -ENOMEM;
1363 goto out;
1364 }
1365
1366 status = __ap_send(ap_dev->qid, 0x0102030405060708ULL,
Felix Becka6a5d732009-12-07 12:51:55 +01001367 msg, sizeof(msg), 0);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001368 if (status.response_code != AP_RESPONSE_NORMAL) {
1369 rc = -ENODEV;
1370 goto out_free;
1371 }
1372
1373 /* Wait for the test message to complete. */
1374 for (i = 0; i < 6; i++) {
1375 mdelay(300);
1376 status = __ap_recv(ap_dev->qid, &psmid, reply, 4096);
1377 if (status.response_code == AP_RESPONSE_NORMAL &&
1378 psmid == 0x0102030405060708ULL)
1379 break;
1380 }
1381 if (i < 6) {
1382 /* Got an answer. */
1383 if (reply[0] == 0x00 && reply[1] == 0x86)
1384 ap_dev->device_type = AP_DEVICE_TYPE_PCICC;
1385 else
1386 ap_dev->device_type = AP_DEVICE_TYPE_PCICA;
1387 rc = 0;
1388 } else
1389 rc = -ENODEV;
1390
1391out_free:
1392 free_page((unsigned long) reply);
1393out:
1394 return rc;
1395}
1396
Martin Schwidefskyf4eae942013-06-24 10:30:41 +02001397static void ap_interrupt_handler(struct airq_struct *airq)
Felix Beckcb17a632008-12-25 13:38:41 +01001398{
Heiko Carstens420f42e2013-01-02 15:18:18 +01001399 inc_irq_stat(IRQIO_APB);
Felix Beckcb17a632008-12-25 13:38:41 +01001400 tasklet_schedule(&ap_tasklet);
1401}
1402
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001403/**
Felix Beck1749a812008-04-17 07:46:28 +02001404 * __ap_scan_bus(): Scan the AP bus.
1405 * @dev: Pointer to device
1406 * @data: Pointer to data
1407 *
1408 * Scan the AP bus for new devices.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001409 */
1410static int __ap_scan_bus(struct device *dev, void *data)
1411{
1412 return to_ap_dev(dev)->qid == (ap_qid_t)(unsigned long) data;
1413}
1414
1415static void ap_device_release(struct device *dev)
1416{
1417 struct ap_device *ap_dev = to_ap_dev(dev);
1418
1419 kfree(ap_dev);
1420}
1421
Al Viro4927b3f2006-12-06 19:18:20 +00001422static void ap_scan_bus(struct work_struct *unused)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001423{
1424 struct ap_device *ap_dev;
1425 struct device *dev;
1426 ap_qid_t qid;
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001427 int queue_depth = 0, device_type = 0;
Holger Dengler6bed05b2011-07-24 10:48:25 +02001428 unsigned int device_functions;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001429 int rc, i;
1430
Holger Dengler75014552012-08-28 16:41:50 +02001431 ap_query_configuration();
Ingo Tuchscherer56bbe682013-04-12 17:52:08 +02001432 if (ap_select_domain() != 0) {
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001433 return;
Ingo Tuchscherer56bbe682013-04-12 17:52:08 +02001434 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001435 for (i = 0; i < AP_DEVICES; i++) {
1436 qid = AP_MKQID(i, ap_domain_index);
1437 dev = bus_find_device(&ap_bus_type, NULL,
1438 (void *)(unsigned long)qid,
1439 __ap_scan_bus);
Holger Dengler75014552012-08-28 16:41:50 +02001440 if (ap_test_config_card_id(i))
1441 rc = ap_query_queue(qid, &queue_depth, &device_type);
1442 else
1443 rc = -ENODEV;
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001444 if (dev) {
1445 ap_dev = to_ap_dev(dev);
1446 spin_lock_bh(&ap_dev->lock);
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001447 if (rc == -ENODEV || ap_dev->unregistered) {
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001448 spin_unlock_bh(&ap_dev->lock);
Felix Beck5314af62009-09-22 22:58:51 +02001449 if (ap_dev->unregistered)
1450 i--;
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001451 device_unregister(dev);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001452 put_device(dev);
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001453 continue;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001454 }
1455 spin_unlock_bh(&ap_dev->lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001456 put_device(dev);
1457 continue;
1458 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001459 if (rc)
1460 continue;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001461 ap_dev = kzalloc(sizeof(*ap_dev), GFP_KERNEL);
1462 if (!ap_dev)
1463 break;
1464 ap_dev->qid = qid;
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001465 rc = ap_init_queue(ap_dev);
1466 if ((rc != 0) && (rc != -EBUSY)) {
1467 kfree(ap_dev);
1468 continue;
1469 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001470 ap_dev->queue_depth = queue_depth;
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001471 ap_dev->unregistered = 1;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001472 spin_lock_init(&ap_dev->lock);
1473 INIT_LIST_HEAD(&ap_dev->pendingq);
1474 INIT_LIST_HEAD(&ap_dev->requestq);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001475 INIT_LIST_HEAD(&ap_dev->list);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001476 setup_timer(&ap_dev->timeout, ap_request_timeout,
1477 (unsigned long) ap_dev);
Holger Dengler6bed05b2011-07-24 10:48:25 +02001478 switch (device_type) {
1479 case 0:
Holger Dengler1e2076f2012-08-28 16:48:29 +02001480 /* device type probing for old cards */
Holger Denglercf2d0072011-05-23 10:24:30 +02001481 if (ap_probe_device_type(ap_dev)) {
1482 kfree(ap_dev);
1483 continue;
1484 }
Holger Dengler6bed05b2011-07-24 10:48:25 +02001485 break;
Holger Dengler6bed05b2011-07-24 10:48:25 +02001486 default:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001487 ap_dev->device_type = device_type;
Holger Dengler6bed05b2011-07-24 10:48:25 +02001488 }
Ingo Tuchscherer42f4dd612014-10-02 14:48:46 +02001489 ap_dev->raw_hwtype = device_type;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001490
Holger Dengler1e2076f2012-08-28 16:48:29 +02001491 rc = ap_query_functions(qid, &device_functions);
1492 if (!rc)
1493 ap_dev->functions = device_functions;
1494 else
1495 ap_dev->functions = 0u;
1496
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001497 ap_dev->device.bus = &ap_bus_type;
1498 ap_dev->device.parent = ap_root_device;
Felix Beckedc44fa2009-09-11 10:28:52 +02001499 if (dev_set_name(&ap_dev->device, "card%02x",
1500 AP_QID_DEVICE(ap_dev->qid))) {
1501 kfree(ap_dev);
1502 continue;
1503 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001504 ap_dev->device.release = ap_device_release;
1505 rc = device_register(&ap_dev->device);
1506 if (rc) {
Sebastian Ottc6304932009-09-11 10:28:38 +02001507 put_device(&ap_dev->device);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001508 continue;
1509 }
1510 /* Add device attributes. */
1511 rc = sysfs_create_group(&ap_dev->device.kobj,
1512 &ap_dev_attr_group);
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001513 if (!rc) {
1514 spin_lock_bh(&ap_dev->lock);
1515 ap_dev->unregistered = 0;
1516 spin_unlock_bh(&ap_dev->lock);
1517 }
1518 else
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001519 device_unregister(&ap_dev->device);
1520 }
1521}
1522
1523static void
1524ap_config_timeout(unsigned long ptr)
1525{
1526 queue_work(ap_work_queue, &ap_config_work);
1527 ap_config_timer.expires = jiffies + ap_config_time * HZ;
1528 add_timer(&ap_config_timer);
1529}
1530
1531/**
Felix Beck1749a812008-04-17 07:46:28 +02001532 * ap_poll_read(): Receive pending reply messages from an AP device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001533 * @ap_dev: pointer to the AP device
1534 * @flags: pointer to control flags, bit 2^0 is set if another poll is
1535 * required, bit 2^1 is set if the poll timer needs to get armed
Felix Beck1749a812008-04-17 07:46:28 +02001536 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001537 * Returns 0 if the device is still present, -ENODEV if not.
1538 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +01001539static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001540{
1541 struct ap_queue_status status;
1542 struct ap_message *ap_msg;
1543
1544 if (ap_dev->queue_count <= 0)
1545 return 0;
1546 status = __ap_recv(ap_dev->qid, &ap_dev->reply->psmid,
1547 ap_dev->reply->message, ap_dev->reply->length);
1548 switch (status.response_code) {
1549 case AP_RESPONSE_NORMAL:
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001550 ap_dev->interrupt = status.int_enabled;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001551 atomic_dec(&ap_poll_requests);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001552 ap_decrease_queue_count(ap_dev);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001553 list_for_each_entry(ap_msg, &ap_dev->pendingq, list) {
1554 if (ap_msg->psmid != ap_dev->reply->psmid)
1555 continue;
1556 list_del_init(&ap_msg->list);
1557 ap_dev->pendingq_count--;
Holger Dengler54a8f562012-05-16 14:08:22 +02001558 ap_msg->receive(ap_dev, ap_msg, ap_dev->reply);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001559 break;
1560 }
1561 if (ap_dev->queue_count > 0)
1562 *flags |= 1;
1563 break;
1564 case AP_RESPONSE_NO_PENDING_REPLY:
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001565 ap_dev->interrupt = status.int_enabled;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001566 if (status.queue_empty) {
1567 /* The card shouldn't forget requests but who knows. */
Ralph Wuerthnere675c0d2007-03-26 20:42:43 +02001568 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001569 ap_dev->queue_count = 0;
1570 list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
1571 ap_dev->requestq_count += ap_dev->pendingq_count;
1572 ap_dev->pendingq_count = 0;
1573 } else
1574 *flags |= 2;
1575 break;
1576 default:
1577 return -ENODEV;
1578 }
1579 return 0;
1580}
1581
1582/**
Felix Beck1749a812008-04-17 07:46:28 +02001583 * ap_poll_write(): Send messages from the request queue to an AP device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001584 * @ap_dev: pointer to the AP device
1585 * @flags: pointer to control flags, bit 2^0 is set if another poll is
1586 * required, bit 2^1 is set if the poll timer needs to get armed
Felix Beck1749a812008-04-17 07:46:28 +02001587 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001588 * Returns 0 if the device is still present, -ENODEV if not.
1589 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +01001590static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001591{
1592 struct ap_queue_status status;
1593 struct ap_message *ap_msg;
1594
1595 if (ap_dev->requestq_count <= 0 ||
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001596 (ap_dev->queue_count >= ap_dev->queue_depth) ||
1597 (ap_dev->reset == AP_RESET_IN_PROGRESS))
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001598 return 0;
1599 /* Start the next request on the queue. */
1600 ap_msg = list_entry(ap_dev->requestq.next, struct ap_message, list);
1601 status = __ap_send(ap_dev->qid, ap_msg->psmid,
Felix Becka6a5d732009-12-07 12:51:55 +01001602 ap_msg->message, ap_msg->length, ap_msg->special);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001603 switch (status.response_code) {
1604 case AP_RESPONSE_NORMAL:
1605 atomic_inc(&ap_poll_requests);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001606 ap_increase_queue_count(ap_dev);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001607 list_move_tail(&ap_msg->list, &ap_dev->pendingq);
1608 ap_dev->requestq_count--;
1609 ap_dev->pendingq_count++;
1610 if (ap_dev->queue_count < ap_dev->queue_depth &&
1611 ap_dev->requestq_count > 0)
1612 *flags |= 1;
1613 *flags |= 2;
1614 break;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001615 case AP_RESPONSE_RESET_IN_PROGRESS:
Holger Denglerbc615de2011-11-14 11:19:04 +01001616 __ap_schedule_poll_timer();
1617 case AP_RESPONSE_Q_FULL:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001618 *flags |= 2;
1619 break;
1620 case AP_RESPONSE_MESSAGE_TOO_BIG:
Felix Becka6a5d732009-12-07 12:51:55 +01001621 case AP_RESPONSE_REQ_FAC_NOT_INST:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001622 return -EINVAL;
1623 default:
1624 return -ENODEV;
1625 }
1626 return 0;
1627}
1628
1629/**
Felix Beck1749a812008-04-17 07:46:28 +02001630 * ap_poll_queue(): Poll AP device for pending replies and send new messages.
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001631 * Check if the queue has a pending reset. In case it's done re-enable
1632 * interrupts, otherwise reschedule the poll_timer for another attempt.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001633 * @ap_dev: pointer to the bus device
1634 * @flags: pointer to control flags, bit 2^0 is set if another poll is
1635 * required, bit 2^1 is set if the poll timer needs to get armed
Felix Beck1749a812008-04-17 07:46:28 +02001636 *
1637 * Poll AP device for pending replies and send new messages. If either
1638 * ap_poll_read or ap_poll_write returns -ENODEV unregister the device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001639 * Returns 0.
1640 */
1641static inline int ap_poll_queue(struct ap_device *ap_dev, unsigned long *flags)
1642{
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001643 int rc, depth, type;
1644 struct ap_queue_status status;
1645
1646
1647 if (ap_dev->reset == AP_RESET_IN_PROGRESS) {
1648 status = ap_test_queue(ap_dev->qid, &depth, &type);
1649 switch (status.response_code) {
1650 case AP_RESPONSE_NORMAL:
1651 ap_dev->reset = AP_RESET_IGNORE;
1652 if (ap_using_interrupts()) {
1653 rc = ap_queue_enable_interruption(
1654 ap_dev, ap_airq.lsi_ptr);
1655 if (!rc)
1656 ap_dev->interrupt = AP_INTR_IN_PROGRESS;
1657 else if (rc == -ENODEV) {
1658 pr_err("Registering adapter interrupts for "
1659 "AP %d failed\n", AP_QID_DEVICE(ap_dev->qid));
1660 return rc;
1661 }
1662 }
1663 /* fall through */
1664 case AP_RESPONSE_BUSY:
1665 case AP_RESPONSE_RESET_IN_PROGRESS:
1666 *flags |= AP_POLL_AFTER_TIMEOUT;
1667 break;
1668 case AP_RESPONSE_Q_NOT_AVAIL:
1669 case AP_RESPONSE_DECONFIGURED:
1670 case AP_RESPONSE_CHECKSTOPPED:
1671 return -ENODEV;
1672 default:
1673 break;
1674 }
1675 }
1676
1677 if ((ap_dev->reset != AP_RESET_IN_PROGRESS) &&
1678 (ap_dev->interrupt == AP_INTR_IN_PROGRESS)) {
1679 status = ap_test_queue(ap_dev->qid, &depth, &type);
1680 if (ap_using_interrupts()) {
1681 if (status.int_enabled == 1)
1682 ap_dev->interrupt = AP_INTR_ENABLED;
1683 else
1684 *flags |= AP_POLL_AFTER_TIMEOUT;
1685 } else
1686 ap_dev->interrupt = AP_INTR_DISABLED;
1687 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001688
1689 rc = ap_poll_read(ap_dev, flags);
1690 if (rc)
1691 return rc;
1692 return ap_poll_write(ap_dev, flags);
1693}
1694
1695/**
Felix Beck1749a812008-04-17 07:46:28 +02001696 * __ap_queue_message(): Queue a message to a device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001697 * @ap_dev: pointer to the AP device
1698 * @ap_msg: the message to be queued
Felix Beck1749a812008-04-17 07:46:28 +02001699 *
1700 * Queue a message to a device. Returns 0 if successful.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001701 */
1702static int __ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
1703{
1704 struct ap_queue_status status;
1705
1706 if (list_empty(&ap_dev->requestq) &&
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001707 (ap_dev->queue_count < ap_dev->queue_depth) &&
1708 (ap_dev->reset != AP_RESET_IN_PROGRESS)) {
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001709 status = __ap_send(ap_dev->qid, ap_msg->psmid,
Felix Becka6a5d732009-12-07 12:51:55 +01001710 ap_msg->message, ap_msg->length,
1711 ap_msg->special);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001712 switch (status.response_code) {
1713 case AP_RESPONSE_NORMAL:
1714 list_add_tail(&ap_msg->list, &ap_dev->pendingq);
1715 atomic_inc(&ap_poll_requests);
1716 ap_dev->pendingq_count++;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001717 ap_increase_queue_count(ap_dev);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001718 ap_dev->total_request_count++;
1719 break;
1720 case AP_RESPONSE_Q_FULL:
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001721 case AP_RESPONSE_RESET_IN_PROGRESS:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001722 list_add_tail(&ap_msg->list, &ap_dev->requestq);
1723 ap_dev->requestq_count++;
1724 ap_dev->total_request_count++;
1725 return -EBUSY;
Felix Becka6a5d732009-12-07 12:51:55 +01001726 case AP_RESPONSE_REQ_FAC_NOT_INST:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001727 case AP_RESPONSE_MESSAGE_TOO_BIG:
Holger Dengler54a8f562012-05-16 14:08:22 +02001728 ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL));
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001729 return -EINVAL;
1730 default: /* Device is gone. */
Holger Dengler54a8f562012-05-16 14:08:22 +02001731 ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001732 return -ENODEV;
1733 }
1734 } else {
1735 list_add_tail(&ap_msg->list, &ap_dev->requestq);
1736 ap_dev->requestq_count++;
1737 ap_dev->total_request_count++;
1738 return -EBUSY;
1739 }
1740 ap_schedule_poll_timer();
1741 return 0;
1742}
1743
1744void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
1745{
1746 unsigned long flags;
1747 int rc;
1748
Holger Dengler54a8f562012-05-16 14:08:22 +02001749 /* For asynchronous message handling a valid receive-callback
1750 * is required. */
1751 BUG_ON(!ap_msg->receive);
1752
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001753 spin_lock_bh(&ap_dev->lock);
1754 if (!ap_dev->unregistered) {
1755 /* Make room on the queue by polling for finished requests. */
1756 rc = ap_poll_queue(ap_dev, &flags);
1757 if (!rc)
1758 rc = __ap_queue_message(ap_dev, ap_msg);
1759 if (!rc)
1760 wake_up(&ap_poll_wait);
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001761 if (rc == -ENODEV)
1762 ap_dev->unregistered = 1;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001763 } else {
Holger Dengler54a8f562012-05-16 14:08:22 +02001764 ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001765 rc = -ENODEV;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001766 }
1767 spin_unlock_bh(&ap_dev->lock);
1768 if (rc == -ENODEV)
1769 device_unregister(&ap_dev->device);
1770}
1771EXPORT_SYMBOL(ap_queue_message);
1772
1773/**
Felix Beck1749a812008-04-17 07:46:28 +02001774 * ap_cancel_message(): Cancel a crypto request.
1775 * @ap_dev: The AP device that has the message queued
1776 * @ap_msg: The message that is to be removed
1777 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001778 * Cancel a crypto request. This is done by removing the request
Felix Beck1749a812008-04-17 07:46:28 +02001779 * from the device pending or request queue. Note that the
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001780 * request stays on the AP queue. When it finishes the message
1781 * reply will be discarded because the psmid can't be found.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001782 */
1783void ap_cancel_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
1784{
1785 struct ap_message *tmp;
1786
1787 spin_lock_bh(&ap_dev->lock);
1788 if (!list_empty(&ap_msg->list)) {
1789 list_for_each_entry(tmp, &ap_dev->pendingq, list)
1790 if (tmp->psmid == ap_msg->psmid) {
1791 ap_dev->pendingq_count--;
1792 goto found;
1793 }
1794 ap_dev->requestq_count--;
1795 found:
1796 list_del_init(&ap_msg->list);
1797 }
1798 spin_unlock_bh(&ap_dev->lock);
1799}
1800EXPORT_SYMBOL(ap_cancel_message);
1801
1802/**
Felix Beck1749a812008-04-17 07:46:28 +02001803 * ap_poll_timeout(): AP receive polling for finished AP requests.
Felix Beckfe137232008-07-14 09:59:08 +02001804 * @unused: Unused pointer.
Felix Beck1749a812008-04-17 07:46:28 +02001805 *
Felix Beckfe137232008-07-14 09:59:08 +02001806 * Schedules the AP tasklet using a high resolution timer.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001807 */
Felix Beckfe137232008-07-14 09:59:08 +02001808static enum hrtimer_restart ap_poll_timeout(struct hrtimer *unused)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001809{
1810 tasklet_schedule(&ap_tasklet);
Felix Beckfe137232008-07-14 09:59:08 +02001811 return HRTIMER_NORESTART;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001812}
1813
1814/**
Felix Beck1749a812008-04-17 07:46:28 +02001815 * ap_reset(): Reset a not responding AP device.
1816 * @ap_dev: Pointer to the AP device
1817 *
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001818 * Reset a not responding AP device and move all requests from the
1819 * pending queue to the request queue.
1820 */
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001821static void ap_reset(struct ap_device *ap_dev, unsigned long *flags)
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001822{
1823 int rc;
1824
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001825 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
1826 ap_dev->queue_count = 0;
1827 list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
1828 ap_dev->requestq_count += ap_dev->pendingq_count;
1829 ap_dev->pendingq_count = 0;
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001830 rc = ap_init_queue(ap_dev);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001831 if (rc == -ENODEV)
1832 ap_dev->unregistered = 1;
Holger Dengler75464962011-12-01 13:32:23 +01001833 else
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001834 *flags |= AP_POLL_AFTER_TIMEOUT;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001835}
1836
Christian Maaser43c207e62008-12-25 13:38:42 +01001837static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001838{
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001839 if (!ap_dev->unregistered) {
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001840 if (ap_poll_queue(ap_dev, flags))
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001841 ap_dev->unregistered = 1;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001842 if (ap_dev->reset == AP_RESET_DO)
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001843 ap_reset(ap_dev, flags);
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001844 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001845 return 0;
1846}
1847
Felix Beck1749a812008-04-17 07:46:28 +02001848/**
1849 * ap_poll_all(): Poll all AP devices.
1850 * @dummy: Unused variable
1851 *
1852 * Poll all AP devices on the bus in a round robin fashion. Continue
1853 * polling until bit 2^0 of the control flags is not set. If bit 2^1
1854 * of the control flags has been set arm the poll timer.
1855 */
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001856static void ap_poll_all(unsigned long dummy)
1857{
1858 unsigned long flags;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001859 struct ap_device *ap_dev;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001860
Felix Beckcb17a632008-12-25 13:38:41 +01001861 /* Reset the indicator if interrupts are used. Thus new interrupts can
1862 * be received. Doing it in the beginning of the tasklet is therefor
1863 * important that no requests on any AP get lost.
1864 */
1865 if (ap_using_interrupts())
Martin Schwidefskyf4eae942013-06-24 10:30:41 +02001866 xchg(ap_airq.lsi_ptr, 0);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001867 do {
1868 flags = 0;
Christian Maaser43c207e62008-12-25 13:38:42 +01001869 spin_lock(&ap_device_list_lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001870 list_for_each_entry(ap_dev, &ap_device_list, list) {
Felix Beck95f15562009-09-11 10:28:51 +02001871 spin_lock(&ap_dev->lock);
Christian Maaser43c207e62008-12-25 13:38:42 +01001872 __ap_poll_device(ap_dev, &flags);
Felix Beck95f15562009-09-11 10:28:51 +02001873 spin_unlock(&ap_dev->lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001874 }
Christian Maaser43c207e62008-12-25 13:38:42 +01001875 spin_unlock(&ap_device_list_lock);
Ingo Tuchschererc50a1602015-06-17 16:19:15 +02001876 } while (flags & AP_POLL_IMMEDIATELY);
1877 if (flags & AP_POLL_AFTER_TIMEOUT)
1878 __ap_schedule_poll_timer();
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001879}
1880
1881/**
Felix Beck1749a812008-04-17 07:46:28 +02001882 * ap_poll_thread(): Thread that polls for finished requests.
1883 * @data: Unused pointer
1884 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001885 * AP bus poll thread. The purpose of this thread is to poll for
1886 * finished requests in a loop if there is a "free" cpu - that is
1887 * a cpu that doesn't have anything better to do. The polling stops
1888 * as soon as there is another task or if all messages have been
1889 * delivered.
1890 */
1891static int ap_poll_thread(void *data)
1892{
1893 DECLARE_WAITQUEUE(wait, current);
1894 unsigned long flags;
1895 int requests;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001896 struct ap_device *ap_dev;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001897
Dongsheng Yang8698a742014-03-11 18:09:12 +08001898 set_user_nice(current, MAX_NICE);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001899 while (1) {
Felix Beck772f5472009-06-22 12:08:16 +02001900 if (ap_suspend_flag)
1901 return 0;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001902 if (need_resched()) {
1903 schedule();
1904 continue;
1905 }
1906 add_wait_queue(&ap_poll_wait, &wait);
1907 set_current_state(TASK_INTERRUPTIBLE);
1908 if (kthread_should_stop())
1909 break;
1910 requests = atomic_read(&ap_poll_requests);
1911 if (requests <= 0)
1912 schedule();
1913 set_current_state(TASK_RUNNING);
1914 remove_wait_queue(&ap_poll_wait, &wait);
1915
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001916 flags = 0;
Christian Maaser43c207e62008-12-25 13:38:42 +01001917 spin_lock_bh(&ap_device_list_lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001918 list_for_each_entry(ap_dev, &ap_device_list, list) {
Felix Beck95f15562009-09-11 10:28:51 +02001919 spin_lock(&ap_dev->lock);
Christian Maaser43c207e62008-12-25 13:38:42 +01001920 __ap_poll_device(ap_dev, &flags);
Felix Beck95f15562009-09-11 10:28:51 +02001921 spin_unlock(&ap_dev->lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001922 }
Christian Maaser43c207e62008-12-25 13:38:42 +01001923 spin_unlock_bh(&ap_device_list_lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001924 }
1925 set_current_state(TASK_RUNNING);
1926 remove_wait_queue(&ap_poll_wait, &wait);
1927 return 0;
1928}
1929
1930static int ap_poll_thread_start(void)
1931{
1932 int rc;
1933
Felix Beck772f5472009-06-22 12:08:16 +02001934 if (ap_using_interrupts() || ap_suspend_flag)
Felix Beckcb17a632008-12-25 13:38:41 +01001935 return 0;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001936 mutex_lock(&ap_poll_thread_mutex);
1937 if (!ap_poll_kthread) {
1938 ap_poll_kthread = kthread_run(ap_poll_thread, NULL, "appoll");
Thomas Meyerba8da212013-06-01 11:51:13 +02001939 rc = PTR_RET(ap_poll_kthread);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001940 if (rc)
1941 ap_poll_kthread = NULL;
1942 }
1943 else
1944 rc = 0;
1945 mutex_unlock(&ap_poll_thread_mutex);
1946 return rc;
1947}
1948
1949static void ap_poll_thread_stop(void)
1950{
1951 mutex_lock(&ap_poll_thread_mutex);
1952 if (ap_poll_kthread) {
1953 kthread_stop(ap_poll_kthread);
1954 ap_poll_kthread = NULL;
1955 }
1956 mutex_unlock(&ap_poll_thread_mutex);
1957}
1958
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001959/**
Felix Beck1749a812008-04-17 07:46:28 +02001960 * ap_request_timeout(): Handling of request timeouts
1961 * @data: Holds the AP device.
1962 *
1963 * Handles request timeouts.
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001964 */
1965static void ap_request_timeout(unsigned long data)
1966{
1967 struct ap_device *ap_dev = (struct ap_device *) data;
1968
Felix Beckcb17a632008-12-25 13:38:41 +01001969 if (ap_dev->reset == AP_RESET_ARMED) {
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001970 ap_dev->reset = AP_RESET_DO;
Felix Beckcb17a632008-12-25 13:38:41 +01001971
1972 if (ap_using_interrupts())
1973 tasklet_schedule(&ap_tasklet);
1974 }
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001975}
1976
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001977static void ap_reset_domain(void)
1978{
1979 int i;
1980
Ingo Tuchschererf60b8d42015-04-30 15:36:48 +02001981 if ((ap_domain_index != -1) && (ap_test_config_domain(ap_domain_index)))
Ralph Wuerthner39aa7cf2007-10-12 16:11:29 +02001982 for (i = 0; i < AP_DEVICES; i++)
1983 ap_reset_queue(AP_MKQID(i, ap_domain_index));
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001984}
1985
1986static void ap_reset_all(void)
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001987{
1988 int i, j;
1989
Ingo Tuchscherer170387a2014-09-08 13:24:13 +02001990 for (i = 0; i < AP_DOMAINS; i++) {
1991 if (!ap_test_config_domain(i))
1992 continue;
1993 for (j = 0; j < AP_DEVICES; j++) {
1994 if (!ap_test_config_card_id(j))
1995 continue;
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001996 ap_reset_queue(AP_MKQID(j, i));
Ingo Tuchscherer170387a2014-09-08 13:24:13 +02001997 }
1998 }
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001999}
2000
2001static struct reset_call ap_reset_call = {
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01002002 .fn = ap_reset_all,
Ralph Wuerthner85eca852006-12-08 15:54:07 +01002003};
2004
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002005/**
Felix Beck1749a812008-04-17 07:46:28 +02002006 * ap_module_init(): The module initialization code.
2007 *
2008 * Initializes the module.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002009 */
2010int __init ap_module_init(void)
2011{
2012 int rc, i;
2013
2014 if (ap_domain_index < -1 || ap_domain_index >= AP_DOMAINS) {
Martin Schwidefsky136f7a12008-12-25 13:39:46 +01002015 pr_warning("%d is not a valid cryptographic domain\n",
2016 ap_domain_index);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002017 return -EINVAL;
2018 }
Felix Beck5314af62009-09-22 22:58:51 +02002019 /* In resume callback we need to know if the user had set the domain.
2020 * If so, we can not just reset it.
2021 */
2022 if (ap_domain_index >= 0)
2023 user_set_domain = 1;
2024
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002025 if (ap_instructions_available() != 0) {
Martin Schwidefsky136f7a12008-12-25 13:39:46 +01002026 pr_warning("The hardware system does not support "
2027 "AP instructions\n");
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002028 return -ENODEV;
2029 }
Felix Beckcb17a632008-12-25 13:38:41 +01002030 if (ap_interrupts_available()) {
Martin Schwidefskyf4eae942013-06-24 10:30:41 +02002031 rc = register_adapter_interrupt(&ap_airq);
2032 ap_airq_flag = (rc == 0);
Felix Beckcb17a632008-12-25 13:38:41 +01002033 }
2034
Ralph Wuerthner85eca852006-12-08 15:54:07 +01002035 register_reset_call(&ap_reset_call);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002036
2037 /* Create /sys/bus/ap. */
2038 rc = bus_register(&ap_bus_type);
2039 if (rc)
2040 goto out;
2041 for (i = 0; ap_bus_attrs[i]; i++) {
2042 rc = bus_create_file(&ap_bus_type, ap_bus_attrs[i]);
2043 if (rc)
2044 goto out_bus;
2045 }
2046
2047 /* Create /sys/devices/ap. */
Mark McLoughlin035da162008-12-15 12:58:29 +00002048 ap_root_device = root_device_register("ap");
Thomas Meyerba8da212013-06-01 11:51:13 +02002049 rc = PTR_RET(ap_root_device);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002050 if (rc)
2051 goto out_bus;
2052
2053 ap_work_queue = create_singlethread_workqueue("kapwork");
2054 if (!ap_work_queue) {
2055 rc = -ENOMEM;
2056 goto out_root;
2057 }
2058
Holger Dengler75014552012-08-28 16:41:50 +02002059 ap_query_configuration();
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002060 if (ap_select_domain() == 0)
2061 ap_scan_bus(NULL);
2062
Felix Beck1749a812008-04-17 07:46:28 +02002063 /* Setup the AP bus rescan timer. */
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002064 init_timer(&ap_config_timer);
2065 ap_config_timer.function = ap_config_timeout;
2066 ap_config_timer.data = 0;
2067 ap_config_timer.expires = jiffies + ap_config_time * HZ;
2068 add_timer(&ap_config_timer);
2069
Felix Beckfe137232008-07-14 09:59:08 +02002070 /* Setup the high resultion poll timer.
2071 * If we are running under z/VM adjust polling to z/VM polling rate.
2072 */
2073 if (MACHINE_IS_VM)
2074 poll_timeout = 1500000;
Felix Beck93521312009-12-07 12:52:00 +01002075 spin_lock_init(&ap_poll_timer_lock);
Felix Beckfe137232008-07-14 09:59:08 +02002076 hrtimer_init(&ap_poll_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
2077 ap_poll_timer.function = ap_poll_timeout;
2078
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002079 /* Start the low priority AP bus poll thread. */
2080 if (ap_thread_flag) {
2081 rc = ap_poll_thread_start();
2082 if (rc)
2083 goto out_work;
2084 }
2085
2086 return 0;
2087
2088out_work:
2089 del_timer_sync(&ap_config_timer);
Felix Beckfe137232008-07-14 09:59:08 +02002090 hrtimer_cancel(&ap_poll_timer);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002091 destroy_workqueue(ap_work_queue);
2092out_root:
Mark McLoughlin035da162008-12-15 12:58:29 +00002093 root_device_unregister(ap_root_device);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002094out_bus:
2095 while (i--)
2096 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
2097 bus_unregister(&ap_bus_type);
2098out:
Ralph Wuerthner85eca852006-12-08 15:54:07 +01002099 unregister_reset_call(&ap_reset_call);
Martin Schwidefskyf4eae942013-06-24 10:30:41 +02002100 if (ap_using_interrupts())
2101 unregister_adapter_interrupt(&ap_airq);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002102 return rc;
2103}
2104
2105static int __ap_match_all(struct device *dev, void *data)
2106{
2107 return 1;
2108}
2109
2110/**
Felix Beck1749a812008-04-17 07:46:28 +02002111 * ap_modules_exit(): The module termination code
2112 *
2113 * Terminates the module.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002114 */
2115void ap_module_exit(void)
2116{
2117 int i;
2118 struct device *dev;
2119
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01002120 ap_reset_domain();
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002121 ap_poll_thread_stop();
2122 del_timer_sync(&ap_config_timer);
Felix Beckfe137232008-07-14 09:59:08 +02002123 hrtimer_cancel(&ap_poll_timer);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002124 destroy_workqueue(ap_work_queue);
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01002125 tasklet_kill(&ap_tasklet);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002126 while ((dev = bus_find_device(&ap_bus_type, NULL, NULL,
2127 __ap_match_all)))
2128 {
2129 device_unregister(dev);
2130 put_device(dev);
2131 }
2132 for (i = 0; ap_bus_attrs[i]; i++)
2133 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
Ingo Tuchschererf60b8d42015-04-30 15:36:48 +02002134 root_device_unregister(ap_root_device);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002135 bus_unregister(&ap_bus_type);
Ralph Wuerthner85eca852006-12-08 15:54:07 +01002136 unregister_reset_call(&ap_reset_call);
Martin Schwidefskyf4eae942013-06-24 10:30:41 +02002137 if (ap_using_interrupts())
2138 unregister_adapter_interrupt(&ap_airq);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002139}
2140
Martin Schwidefsky1534c382006-09-20 15:58:25 +02002141module_init(ap_module_init);
2142module_exit(ap_module_exit);