blob: f0b53ee6802fee9641841b1c61ca4388b5690bc4 [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);
61static void ap_interrupt_handler(void *unused1, void *unused2);
62static 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");
74
Felix Beck1749a812008-04-17 07:46:28 +020075/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +020076 * Module parameter
77 */
78int ap_domain_index = -1; /* Adjunct Processor Domain Index */
79module_param_named(domain, ap_domain_index, int, 0000);
80MODULE_PARM_DESC(domain, "domain index for ap devices");
81EXPORT_SYMBOL(ap_domain_index);
82
Felix Beckb90b34c2008-02-09 18:24:30 +010083static int ap_thread_flag = 0;
Martin Schwidefsky1534c382006-09-20 15:58:25 +020084module_param_named(poll_thread, ap_thread_flag, int, 0000);
Felix Beckb90b34c2008-02-09 18:24:30 +010085MODULE_PARM_DESC(poll_thread, "Turn on/off poll thread, default is 0 (off).");
Martin Schwidefsky1534c382006-09-20 15:58:25 +020086
87static struct device *ap_root_device = NULL;
Holger Dengler75014552012-08-28 16:41:50 +020088static struct ap_config_info *ap_configuration;
Christian Maaser43c207e62008-12-25 13:38:42 +010089static DEFINE_SPINLOCK(ap_device_list_lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +010090static LIST_HEAD(ap_device_list);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020091
Felix Beck1749a812008-04-17 07:46:28 +020092/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +020093 * Workqueue & timer for bus rescan.
94 */
95static struct workqueue_struct *ap_work_queue;
96static struct timer_list ap_config_timer;
97static int ap_config_time = AP_CONFIG_TIME;
Al Viro4927b3f2006-12-06 19:18:20 +000098static DECLARE_WORK(ap_config_work, ap_scan_bus);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020099
Felix Beck1749a812008-04-17 07:46:28 +0200100/*
Felix Beckcb17a632008-12-25 13:38:41 +0100101 * Tasklet & timer for AP request polling and interrupts
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200102 */
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200103static DECLARE_TASKLET(ap_tasklet, ap_poll_all, 0);
104static atomic_t ap_poll_requests = ATOMIC_INIT(0);
105static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait);
106static struct task_struct *ap_poll_kthread = NULL;
107static DEFINE_MUTEX(ap_poll_thread_mutex);
Felix Beck93521312009-12-07 12:52:00 +0100108static DEFINE_SPINLOCK(ap_poll_timer_lock);
Felix Beckcb17a632008-12-25 13:38:41 +0100109static void *ap_interrupt_indicator;
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 Schwidefsky1534c382006-09-20 15:58:25 +0200123/**
Felix Beckcb17a632008-12-25 13:38:41 +0100124 * ap_using_interrupts() - Returns non-zero if interrupt support is
125 * available.
126 */
127static inline int ap_using_interrupts(void)
128{
129 return ap_interrupt_indicator != NULL;
130}
131
132/**
Felix Beck1749a812008-04-17 07:46:28 +0200133 * ap_intructions_available() - Test if AP instructions are available.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200134 *
Felix Beck1749a812008-04-17 07:46:28 +0200135 * Returns 0 if the AP instructions are installed.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200136 */
137static inline int ap_instructions_available(void)
138{
139 register unsigned long reg0 asm ("0") = AP_MKQID(0,0);
140 register unsigned long reg1 asm ("1") = -ENODEV;
141 register unsigned long reg2 asm ("2") = 0UL;
142
143 asm volatile(
144 " .long 0xb2af0000\n" /* PQAP(TAPQ) */
145 "0: la %1,0\n"
146 "1:\n"
147 EX_TABLE(0b, 1b)
148 : "+d" (reg0), "+d" (reg1), "+d" (reg2) : : "cc" );
149 return reg1;
150}
151
152/**
Felix Beckcb17a632008-12-25 13:38:41 +0100153 * ap_interrupts_available(): Test if AP interrupts are available.
154 *
155 * Returns 1 if AP interrupts are available.
156 */
157static int ap_interrupts_available(void)
158{
Felix Beck53ec24b12011-01-05 12:46:44 +0100159 return test_facility(2) && test_facility(65);
Felix Beckcb17a632008-12-25 13:38:41 +0100160}
161
162/**
Holger Dengler75014552012-08-28 16:41:50 +0200163 * ap_configuration_available(): Test if AP configuration
164 * information is available.
165 *
166 * Returns 1 if AP configuration information is available.
167 */
168static int ap_configuration_available(void)
169{
170 return test_facility(2) && test_facility(12);
171}
172
173/**
Felix Beck1749a812008-04-17 07:46:28 +0200174 * ap_test_queue(): Test adjunct processor queue.
175 * @qid: The AP queue number
176 * @queue_depth: Pointer to queue depth value
177 * @device_type: Pointer to device type value
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200178 *
Felix Beck1749a812008-04-17 07:46:28 +0200179 * Returns AP queue status structure.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200180 */
181static inline struct ap_queue_status
182ap_test_queue(ap_qid_t qid, int *queue_depth, int *device_type)
183{
184 register unsigned long reg0 asm ("0") = qid;
185 register struct ap_queue_status reg1 asm ("1");
186 register unsigned long reg2 asm ("2") = 0UL;
187
188 asm volatile(".long 0xb2af0000" /* PQAP(TAPQ) */
189 : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
190 *device_type = (int) (reg2 >> 24);
191 *queue_depth = (int) (reg2 & 0xff);
192 return reg1;
193}
194
195/**
Felix Beck1749a812008-04-17 07:46:28 +0200196 * ap_reset_queue(): Reset adjunct processor queue.
197 * @qid: The AP queue number
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200198 *
Felix Beck1749a812008-04-17 07:46:28 +0200199 * Returns AP queue status structure.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200200 */
201static inline struct ap_queue_status ap_reset_queue(ap_qid_t qid)
202{
203 register unsigned long reg0 asm ("0") = qid | 0x01000000UL;
204 register struct ap_queue_status reg1 asm ("1");
205 register unsigned long reg2 asm ("2") = 0UL;
206
207 asm volatile(
208 ".long 0xb2af0000" /* PQAP(RAPQ) */
209 : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
210 return reg1;
211}
212
Felix Beckcb17a632008-12-25 13:38:41 +0100213#ifdef CONFIG_64BIT
214/**
215 * ap_queue_interruption_control(): Enable interruption for a specific AP.
216 * @qid: The AP queue number
217 * @ind: The notification indicator byte
218 *
219 * Returns AP queue status.
220 */
221static inline struct ap_queue_status
222ap_queue_interruption_control(ap_qid_t qid, void *ind)
223{
224 register unsigned long reg0 asm ("0") = qid | 0x03000000UL;
225 register unsigned long reg1_in asm ("1") = 0x0000800000000000UL | AP_ISC;
226 register struct ap_queue_status reg1_out asm ("1");
227 register void *reg2 asm ("2") = ind;
228 asm volatile(
Holger Denglera7475af2012-05-16 14:10:26 +0200229 ".long 0xb2af0000" /* PQAP(AQIC) */
Felix Beckcb17a632008-12-25 13:38:41 +0100230 : "+d" (reg0), "+d" (reg1_in), "=d" (reg1_out), "+d" (reg2)
231 :
232 : "cc" );
233 return reg1_out;
234}
235#endif
236
Holger Dengler6bed05b2011-07-24 10:48:25 +0200237#ifdef CONFIG_64BIT
238static inline struct ap_queue_status
239__ap_query_functions(ap_qid_t qid, unsigned int *functions)
Felix Beckb1f933d2011-01-05 12:47:44 +0100240{
241 register unsigned long reg0 asm ("0") = 0UL | qid | (1UL << 23);
Holger Dengler6bed05b2011-07-24 10:48:25 +0200242 register struct ap_queue_status reg1 asm ("1") = AP_QUEUE_STATUS_INVALID;
243 register unsigned long reg2 asm ("2");
Felix Beckb1f933d2011-01-05 12:47:44 +0100244
245 asm volatile(
Holger Denglera7475af2012-05-16 14:10:26 +0200246 ".long 0xb2af0000\n" /* PQAP(TAPQ) */
Holger Dengler6bed05b2011-07-24 10:48:25 +0200247 "0:\n"
248 EX_TABLE(0b, 0b)
249 : "+d" (reg0), "+d" (reg1), "=d" (reg2)
Felix Beckb1f933d2011-01-05 12:47:44 +0100250 :
251 : "cc");
252
Holger Dengler6bed05b2011-07-24 10:48:25 +0200253 *functions = (unsigned int)(reg2 >> 32);
Felix Beckb1f933d2011-01-05 12:47:44 +0100254 return reg1;
255}
Holger Dengler6bed05b2011-07-24 10:48:25 +0200256#endif
257
Holger Dengler75014552012-08-28 16:41:50 +0200258#ifdef CONFIG_64BIT
259static inline int __ap_query_configuration(struct ap_config_info *config)
260{
261 register unsigned long reg0 asm ("0") = 0x04000000UL;
262 register unsigned long reg1 asm ("1") = -EINVAL;
263 register unsigned char *reg2 asm ("2") = (unsigned char *)config;
264
265 asm volatile(
266 ".long 0xb2af0000\n" /* PQAP(QCI) */
267 "0: la %1,0\n"
268 "1:\n"
269 EX_TABLE(0b, 1b)
270 : "+d" (reg0), "+d" (reg1), "+d" (reg2)
271 :
272 : "cc");
273
274 return reg1;
275}
276#endif
277
Holger Dengler6bed05b2011-07-24 10:48:25 +0200278/**
279 * ap_query_functions(): Query supported functions.
280 * @qid: The AP queue number
281 * @functions: Pointer to functions field.
282 *
283 * Returns
284 * 0 on success.
285 * -ENODEV if queue not valid.
286 * -EBUSY if device busy.
287 * -EINVAL if query function is not supported
288 */
289static int ap_query_functions(ap_qid_t qid, unsigned int *functions)
290{
291#ifdef CONFIG_64BIT
292 struct ap_queue_status status;
293 int i;
294 status = __ap_query_functions(qid, functions);
295
296 for (i = 0; i < AP_MAX_RESET; i++) {
297 if (ap_queue_status_invalid_test(&status))
298 return -ENODEV;
299
300 switch (status.response_code) {
301 case AP_RESPONSE_NORMAL:
302 return 0;
303 case AP_RESPONSE_RESET_IN_PROGRESS:
304 case AP_RESPONSE_BUSY:
305 break;
306 case AP_RESPONSE_Q_NOT_AVAIL:
307 case AP_RESPONSE_DECONFIGURED:
308 case AP_RESPONSE_CHECKSTOPPED:
309 case AP_RESPONSE_INVALID_ADDRESS:
310 return -ENODEV;
311 case AP_RESPONSE_OTHERWISE_CHANGED:
312 break;
313 default:
314 break;
315 }
316 if (i < AP_MAX_RESET - 1) {
317 udelay(5);
318 status = __ap_query_functions(qid, functions);
319 }
320 }
321 return -EBUSY;
322#else
323 return -EINVAL;
324#endif
325}
Felix Beckb1f933d2011-01-05 12:47:44 +0100326
327/**
Felix Beckcb17a632008-12-25 13:38:41 +0100328 * ap_queue_enable_interruption(): Enable interruption on an AP.
329 * @qid: The AP queue number
330 * @ind: the notification indicator byte
331 *
332 * Enables interruption on AP queue via ap_queue_interruption_control(). Based
333 * on the return value it waits a while and tests the AP queue if interrupts
334 * have been switched on using ap_test_queue().
335 */
336static int ap_queue_enable_interruption(ap_qid_t qid, void *ind)
337{
338#ifdef CONFIG_64BIT
339 struct ap_queue_status status;
340 int t_depth, t_device_type, rc, i;
341
342 rc = -EBUSY;
343 status = ap_queue_interruption_control(qid, ind);
344
345 for (i = 0; i < AP_MAX_RESET; i++) {
346 switch (status.response_code) {
347 case AP_RESPONSE_NORMAL:
348 if (status.int_enabled)
349 return 0;
350 break;
351 case AP_RESPONSE_RESET_IN_PROGRESS:
352 case AP_RESPONSE_BUSY:
Holger Dengler8738e072012-07-02 12:39:59 +0200353 if (i < AP_MAX_RESET - 1) {
354 udelay(5);
355 status = ap_queue_interruption_control(qid,
356 ind);
357 continue;
358 }
Felix Beckcb17a632008-12-25 13:38:41 +0100359 break;
360 case AP_RESPONSE_Q_NOT_AVAIL:
361 case AP_RESPONSE_DECONFIGURED:
362 case AP_RESPONSE_CHECKSTOPPED:
363 case AP_RESPONSE_INVALID_ADDRESS:
364 return -ENODEV;
365 case AP_RESPONSE_OTHERWISE_CHANGED:
366 if (status.int_enabled)
367 return 0;
368 break;
369 default:
370 break;
371 }
372 if (i < AP_MAX_RESET - 1) {
373 udelay(5);
374 status = ap_test_queue(qid, &t_depth, &t_device_type);
375 }
376 }
377 return rc;
378#else
379 return -EINVAL;
380#endif
381}
382
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200383/**
Felix Beck1749a812008-04-17 07:46:28 +0200384 * __ap_send(): Send message to adjunct processor queue.
385 * @qid: The AP queue number
386 * @psmid: The program supplied message identifier
387 * @msg: The message text
388 * @length: The message length
Felix Becka6a5d732009-12-07 12:51:55 +0100389 * @special: Special Bit
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200390 *
Felix Beck1749a812008-04-17 07:46:28 +0200391 * Returns AP queue status structure.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200392 * Condition code 1 on NQAP can't happen because the L bit is 1.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200393 * Condition code 2 on NQAP also means the send is incomplete,
394 * because a segment boundary was reached. The NQAP is repeated.
395 */
396static inline struct ap_queue_status
Felix Becka6a5d732009-12-07 12:51:55 +0100397__ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length,
398 unsigned int special)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200399{
400 typedef struct { char _[length]; } msgblock;
401 register unsigned long reg0 asm ("0") = qid | 0x40000000UL;
402 register struct ap_queue_status reg1 asm ("1");
403 register unsigned long reg2 asm ("2") = (unsigned long) msg;
404 register unsigned long reg3 asm ("3") = (unsigned long) length;
405 register unsigned long reg4 asm ("4") = (unsigned int) (psmid >> 32);
406 register unsigned long reg5 asm ("5") = (unsigned int) psmid;
407
Felix Becka6a5d732009-12-07 12:51:55 +0100408 if (special == 1)
409 reg0 |= 0x400000UL;
410
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200411 asm volatile (
Holger Denglera7475af2012-05-16 14:10:26 +0200412 "0: .long 0xb2ad0042\n" /* NQAP */
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200413 " brc 2,0b"
414 : "+d" (reg0), "=d" (reg1), "+d" (reg2), "+d" (reg3)
415 : "d" (reg4), "d" (reg5), "m" (*(msgblock *) msg)
416 : "cc" );
417 return reg1;
418}
419
420int ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length)
421{
422 struct ap_queue_status status;
423
Felix Becka6a5d732009-12-07 12:51:55 +0100424 status = __ap_send(qid, psmid, msg, length, 0);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200425 switch (status.response_code) {
426 case AP_RESPONSE_NORMAL:
427 return 0;
428 case AP_RESPONSE_Q_FULL:
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200429 case AP_RESPONSE_RESET_IN_PROGRESS:
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200430 return -EBUSY;
Felix Becka6a5d732009-12-07 12:51:55 +0100431 case AP_RESPONSE_REQ_FAC_NOT_INST:
432 return -EINVAL;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200433 default: /* Device is gone. */
434 return -ENODEV;
435 }
436}
437EXPORT_SYMBOL(ap_send);
438
Felix Beck1749a812008-04-17 07:46:28 +0200439/**
440 * __ap_recv(): Receive message from adjunct processor queue.
441 * @qid: The AP queue number
442 * @psmid: Pointer to program supplied message identifier
443 * @msg: The message text
444 * @length: The message length
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200445 *
Felix Beck1749a812008-04-17 07:46:28 +0200446 * Returns AP queue status structure.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200447 * Condition code 1 on DQAP means the receive has taken place
448 * but only partially. The response is incomplete, hence the
449 * DQAP is repeated.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200450 * Condition code 2 on DQAP also means the receive is incomplete,
451 * this time because a segment boundary was reached. Again, the
452 * DQAP is repeated.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200453 * Note that gpr2 is used by the DQAP instruction to keep track of
454 * any 'residual' length, in case the instruction gets interrupted.
455 * Hence it gets zeroed before the instruction.
456 */
457static inline struct ap_queue_status
458__ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length)
459{
460 typedef struct { char _[length]; } msgblock;
461 register unsigned long reg0 asm("0") = qid | 0x80000000UL;
462 register struct ap_queue_status reg1 asm ("1");
463 register unsigned long reg2 asm("2") = 0UL;
464 register unsigned long reg4 asm("4") = (unsigned long) msg;
465 register unsigned long reg5 asm("5") = (unsigned long) length;
466 register unsigned long reg6 asm("6") = 0UL;
467 register unsigned long reg7 asm("7") = 0UL;
468
469
470 asm volatile(
Holger Denglera7475af2012-05-16 14:10:26 +0200471 "0: .long 0xb2ae0064\n" /* DQAP */
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200472 " brc 6,0b\n"
473 : "+d" (reg0), "=d" (reg1), "+d" (reg2),
474 "+d" (reg4), "+d" (reg5), "+d" (reg6), "+d" (reg7),
475 "=m" (*(msgblock *) msg) : : "cc" );
476 *psmid = (((unsigned long long) reg6) << 32) + reg7;
477 return reg1;
478}
479
480int ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length)
481{
482 struct ap_queue_status status;
483
484 status = __ap_recv(qid, psmid, msg, length);
485 switch (status.response_code) {
486 case AP_RESPONSE_NORMAL:
487 return 0;
488 case AP_RESPONSE_NO_PENDING_REPLY:
489 if (status.queue_empty)
490 return -ENOENT;
491 return -EBUSY;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200492 case AP_RESPONSE_RESET_IN_PROGRESS:
493 return -EBUSY;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200494 default:
495 return -ENODEV;
496 }
497}
498EXPORT_SYMBOL(ap_recv);
499
500/**
Felix Beck1749a812008-04-17 07:46:28 +0200501 * ap_query_queue(): Check if an AP queue is available.
502 * @qid: The AP queue number
503 * @queue_depth: Pointer to queue depth value
504 * @device_type: Pointer to device type value
505 *
506 * The test is repeated for AP_MAX_RESET times.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200507 */
508static int ap_query_queue(ap_qid_t qid, int *queue_depth, int *device_type)
509{
510 struct ap_queue_status status;
511 int t_depth, t_device_type, rc, i;
512
513 rc = -EBUSY;
514 for (i = 0; i < AP_MAX_RESET; i++) {
515 status = ap_test_queue(qid, &t_depth, &t_device_type);
516 switch (status.response_code) {
517 case AP_RESPONSE_NORMAL:
518 *queue_depth = t_depth + 1;
519 *device_type = t_device_type;
520 rc = 0;
521 break;
522 case AP_RESPONSE_Q_NOT_AVAIL:
523 rc = -ENODEV;
524 break;
525 case AP_RESPONSE_RESET_IN_PROGRESS:
526 break;
527 case AP_RESPONSE_DECONFIGURED:
528 rc = -ENODEV;
529 break;
530 case AP_RESPONSE_CHECKSTOPPED:
531 rc = -ENODEV;
532 break;
Felix Beckcb17a632008-12-25 13:38:41 +0100533 case AP_RESPONSE_INVALID_ADDRESS:
534 rc = -ENODEV;
535 break;
536 case AP_RESPONSE_OTHERWISE_CHANGED:
537 break;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200538 case AP_RESPONSE_BUSY:
539 break;
540 default:
541 BUG();
542 }
543 if (rc != -EBUSY)
544 break;
545 if (i < AP_MAX_RESET - 1)
546 udelay(5);
547 }
548 return rc;
549}
550
551/**
Felix Beck1749a812008-04-17 07:46:28 +0200552 * ap_init_queue(): Reset an AP queue.
553 * @qid: The AP queue number
554 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200555 * Reset an AP queue and wait for it to become available again.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200556 */
557static int ap_init_queue(ap_qid_t qid)
558{
559 struct ap_queue_status status;
560 int rc, dummy, i;
561
562 rc = -ENODEV;
563 status = ap_reset_queue(qid);
564 for (i = 0; i < AP_MAX_RESET; i++) {
565 switch (status.response_code) {
566 case AP_RESPONSE_NORMAL:
567 if (status.queue_empty)
568 rc = 0;
569 break;
570 case AP_RESPONSE_Q_NOT_AVAIL:
571 case AP_RESPONSE_DECONFIGURED:
572 case AP_RESPONSE_CHECKSTOPPED:
573 i = AP_MAX_RESET; /* return with -ENODEV */
574 break;
575 case AP_RESPONSE_RESET_IN_PROGRESS:
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200576 rc = -EBUSY;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200577 case AP_RESPONSE_BUSY:
578 default:
579 break;
580 }
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200581 if (rc != -ENODEV && rc != -EBUSY)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200582 break;
583 if (i < AP_MAX_RESET - 1) {
584 udelay(5);
585 status = ap_test_queue(qid, &dummy, &dummy);
586 }
587 }
Felix Beckcb17a632008-12-25 13:38:41 +0100588 if (rc == 0 && ap_using_interrupts()) {
589 rc = ap_queue_enable_interruption(qid, ap_interrupt_indicator);
590 /* If interruption mode is supported by the machine,
591 * but an AP can not be enabled for interruption then
592 * the AP will be discarded. */
593 if (rc)
594 pr_err("Registering adapter interrupts for "
595 "AP %d failed\n", AP_QID_DEVICE(qid));
596 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200597 return rc;
598}
599
600/**
Felix Beck1749a812008-04-17 07:46:28 +0200601 * ap_increase_queue_count(): Arm request timeout.
602 * @ap_dev: Pointer to an AP device.
603 *
604 * Arm request timeout if an AP device was idle and a new request is submitted.
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200605 */
606static void ap_increase_queue_count(struct ap_device *ap_dev)
607{
608 int timeout = ap_dev->drv->request_timeout;
609
610 ap_dev->queue_count++;
611 if (ap_dev->queue_count == 1) {
612 mod_timer(&ap_dev->timeout, jiffies + timeout);
613 ap_dev->reset = AP_RESET_ARMED;
614 }
615}
616
617/**
Felix Beck1749a812008-04-17 07:46:28 +0200618 * ap_decrease_queue_count(): Decrease queue count.
619 * @ap_dev: Pointer to an AP device.
620 *
621 * If AP device is still alive, re-schedule request timeout if there are still
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200622 * pending requests.
623 */
624static void ap_decrease_queue_count(struct ap_device *ap_dev)
625{
626 int timeout = ap_dev->drv->request_timeout;
627
628 ap_dev->queue_count--;
629 if (ap_dev->queue_count > 0)
630 mod_timer(&ap_dev->timeout, jiffies + timeout);
631 else
Felix Beck1749a812008-04-17 07:46:28 +0200632 /*
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200633 * The timeout timer should to be disabled now - since
634 * del_timer_sync() is very expensive, we just tell via the
635 * reset flag to ignore the pending timeout timer.
636 */
637 ap_dev->reset = AP_RESET_IGNORE;
638}
639
Felix Beck1749a812008-04-17 07:46:28 +0200640/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200641 * AP device related attributes.
642 */
643static ssize_t ap_hwtype_show(struct device *dev,
644 struct device_attribute *attr, char *buf)
645{
646 struct ap_device *ap_dev = to_ap_dev(dev);
647 return snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->device_type);
648}
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200649
Christian Maaser43c207e62008-12-25 13:38:42 +0100650static DEVICE_ATTR(hwtype, 0444, ap_hwtype_show, NULL);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200651static ssize_t ap_depth_show(struct device *dev, struct device_attribute *attr,
652 char *buf)
653{
654 struct ap_device *ap_dev = to_ap_dev(dev);
655 return snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->queue_depth);
656}
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200657
Christian Maaser43c207e62008-12-25 13:38:42 +0100658static DEVICE_ATTR(depth, 0444, ap_depth_show, NULL);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200659static ssize_t ap_request_count_show(struct device *dev,
660 struct device_attribute *attr,
661 char *buf)
662{
663 struct ap_device *ap_dev = to_ap_dev(dev);
664 int rc;
665
666 spin_lock_bh(&ap_dev->lock);
667 rc = snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->total_request_count);
668 spin_unlock_bh(&ap_dev->lock);
669 return rc;
670}
671
672static DEVICE_ATTR(request_count, 0444, ap_request_count_show, NULL);
673
Holger Denglerb26bd942012-08-28 16:43:48 +0200674static ssize_t ap_requestq_count_show(struct device *dev,
675 struct device_attribute *attr, char *buf)
676{
677 struct ap_device *ap_dev = to_ap_dev(dev);
678 int rc;
679
680 spin_lock_bh(&ap_dev->lock);
681 rc = snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->requestq_count);
682 spin_unlock_bh(&ap_dev->lock);
683 return rc;
684}
685
686static DEVICE_ATTR(requestq_count, 0444, ap_requestq_count_show, NULL);
687
688static ssize_t ap_pendingq_count_show(struct device *dev,
689 struct device_attribute *attr, char *buf)
690{
691 struct ap_device *ap_dev = to_ap_dev(dev);
692 int rc;
693
694 spin_lock_bh(&ap_dev->lock);
695 rc = snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->pendingq_count);
696 spin_unlock_bh(&ap_dev->lock);
697 return rc;
698}
699
700static DEVICE_ATTR(pendingq_count, 0444, ap_pendingq_count_show, NULL);
701
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200702static ssize_t ap_modalias_show(struct device *dev,
703 struct device_attribute *attr, char *buf)
704{
705 return sprintf(buf, "ap:t%02X", to_ap_dev(dev)->device_type);
706}
707
708static DEVICE_ATTR(modalias, 0444, ap_modalias_show, NULL);
709
Holger Denglerb26bd942012-08-28 16:43:48 +0200710static ssize_t ap_functions_show(struct device *dev,
711 struct device_attribute *attr, char *buf)
712{
713 struct ap_device *ap_dev = to_ap_dev(dev);
714 return snprintf(buf, PAGE_SIZE, "0x%08X\n", ap_dev->functions);
715}
716
717static DEVICE_ATTR(ap_functions, 0444, ap_functions_show, NULL);
718
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200719static struct attribute *ap_dev_attrs[] = {
720 &dev_attr_hwtype.attr,
721 &dev_attr_depth.attr,
722 &dev_attr_request_count.attr,
Holger Denglerb26bd942012-08-28 16:43:48 +0200723 &dev_attr_requestq_count.attr,
724 &dev_attr_pendingq_count.attr,
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200725 &dev_attr_modalias.attr,
Holger Denglerb26bd942012-08-28 16:43:48 +0200726 &dev_attr_ap_functions.attr,
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200727 NULL
728};
729static struct attribute_group ap_dev_attr_group = {
730 .attrs = ap_dev_attrs
731};
732
733/**
Felix Beck1749a812008-04-17 07:46:28 +0200734 * ap_bus_match()
735 * @dev: Pointer to device
736 * @drv: Pointer to device_driver
737 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200738 * AP bus driver registration/unregistration.
739 */
740static int ap_bus_match(struct device *dev, struct device_driver *drv)
741{
742 struct ap_device *ap_dev = to_ap_dev(dev);
743 struct ap_driver *ap_drv = to_ap_drv(drv);
744 struct ap_device_id *id;
745
Felix Beck1749a812008-04-17 07:46:28 +0200746 /*
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200747 * Compare device type of the device with the list of
748 * supported types of the device_driver.
749 */
750 for (id = ap_drv->ids; id->match_flags; id++) {
751 if ((id->match_flags & AP_DEVICE_ID_MATCH_DEVICE_TYPE) &&
752 (id->dev_type != ap_dev->device_type))
753 continue;
754 return 1;
755 }
756 return 0;
757}
758
759/**
Felix Beck1749a812008-04-17 07:46:28 +0200760 * ap_uevent(): Uevent function for AP devices.
761 * @dev: Pointer to device
762 * @env: Pointer to kobj_uevent_env
763 *
764 * It sets up a single environment variable DEV_TYPE which contains the
765 * hardware device type.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200766 */
Kay Sievers7eff2e72007-08-14 15:15:12 +0200767static int ap_uevent (struct device *dev, struct kobj_uevent_env *env)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200768{
769 struct ap_device *ap_dev = to_ap_dev(dev);
Kay Sievers7eff2e72007-08-14 15:15:12 +0200770 int retval = 0;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200771
772 if (!ap_dev)
773 return -ENODEV;
774
775 /* Set up DEV_TYPE environment variable. */
Kay Sievers7eff2e72007-08-14 15:15:12 +0200776 retval = add_uevent_var(env, "DEV_TYPE=%04X", ap_dev->device_type);
Eric Rannaudbf624562007-03-30 22:23:12 -0700777 if (retval)
778 return retval;
779
Cornelia Huck66a4263b2006-12-04 15:40:10 +0100780 /* Add MODALIAS= */
Kay Sievers7eff2e72007-08-14 15:15:12 +0200781 retval = add_uevent_var(env, "MODALIAS=ap:t%02X", ap_dev->device_type);
Eric Rannaudbf624562007-03-30 22:23:12 -0700782
Eric Rannaudbf624562007-03-30 22:23:12 -0700783 return retval;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200784}
785
Felix Beck772f5472009-06-22 12:08:16 +0200786static int ap_bus_suspend(struct device *dev, pm_message_t state)
787{
788 struct ap_device *ap_dev = to_ap_dev(dev);
789 unsigned long flags;
790
791 if (!ap_suspend_flag) {
792 ap_suspend_flag = 1;
793
794 /* Disable scanning for devices, thus we do not want to scan
795 * for them after removing.
796 */
797 del_timer_sync(&ap_config_timer);
798 if (ap_work_queue != NULL) {
799 destroy_workqueue(ap_work_queue);
800 ap_work_queue = NULL;
801 }
Felix Beck5314af62009-09-22 22:58:51 +0200802
Felix Beck772f5472009-06-22 12:08:16 +0200803 tasklet_disable(&ap_tasklet);
804 }
805 /* Poll on the device until all requests are finished. */
806 do {
807 flags = 0;
Felix Beck95f15562009-09-11 10:28:51 +0200808 spin_lock_bh(&ap_dev->lock);
Felix Beck772f5472009-06-22 12:08:16 +0200809 __ap_poll_device(ap_dev, &flags);
Felix Beck95f15562009-09-11 10:28:51 +0200810 spin_unlock_bh(&ap_dev->lock);
Felix Beck772f5472009-06-22 12:08:16 +0200811 } while ((flags & 1) || (flags & 2));
812
Felix Beck5314af62009-09-22 22:58:51 +0200813 spin_lock_bh(&ap_dev->lock);
814 ap_dev->unregistered = 1;
815 spin_unlock_bh(&ap_dev->lock);
816
Felix Beck772f5472009-06-22 12:08:16 +0200817 return 0;
818}
819
820static int ap_bus_resume(struct device *dev)
821{
822 int rc = 0;
823 struct ap_device *ap_dev = to_ap_dev(dev);
824
825 if (ap_suspend_flag) {
826 ap_suspend_flag = 0;
827 if (!ap_interrupts_available())
828 ap_interrupt_indicator = NULL;
Holger Dengler75014552012-08-28 16:41:50 +0200829 ap_query_configuration();
Felix Beck5314af62009-09-22 22:58:51 +0200830 if (!user_set_domain) {
831 ap_domain_index = -1;
832 ap_select_domain();
833 }
Felix Beck772f5472009-06-22 12:08:16 +0200834 init_timer(&ap_config_timer);
835 ap_config_timer.function = ap_config_timeout;
836 ap_config_timer.data = 0;
837 ap_config_timer.expires = jiffies + ap_config_time * HZ;
838 add_timer(&ap_config_timer);
839 ap_work_queue = create_singlethread_workqueue("kapwork");
840 if (!ap_work_queue)
841 return -ENOMEM;
842 tasklet_enable(&ap_tasklet);
843 if (!ap_using_interrupts())
844 ap_schedule_poll_timer();
845 else
846 tasklet_schedule(&ap_tasklet);
847 if (ap_thread_flag)
848 rc = ap_poll_thread_start();
Felix Beck772f5472009-06-22 12:08:16 +0200849 }
Felix Beck5314af62009-09-22 22:58:51 +0200850 if (AP_QID_QUEUE(ap_dev->qid) != ap_domain_index) {
851 spin_lock_bh(&ap_dev->lock);
852 ap_dev->qid = AP_MKQID(AP_QID_DEVICE(ap_dev->qid),
853 ap_domain_index);
854 spin_unlock_bh(&ap_dev->lock);
855 }
856 queue_work(ap_work_queue, &ap_config_work);
Felix Beck772f5472009-06-22 12:08:16 +0200857
858 return rc;
859}
860
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200861static struct bus_type ap_bus_type = {
862 .name = "ap",
863 .match = &ap_bus_match,
864 .uevent = &ap_uevent,
Felix Beck772f5472009-06-22 12:08:16 +0200865 .suspend = ap_bus_suspend,
866 .resume = ap_bus_resume
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200867};
868
869static int ap_device_probe(struct device *dev)
870{
871 struct ap_device *ap_dev = to_ap_dev(dev);
872 struct ap_driver *ap_drv = to_ap_drv(dev->driver);
873 int rc;
874
875 ap_dev->drv = ap_drv;
876 rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV;
Ralph Wuerthnerfaa582c2008-03-05 12:37:13 +0100877 if (!rc) {
Christian Maaser43c207e62008-12-25 13:38:42 +0100878 spin_lock_bh(&ap_device_list_lock);
Ralph Wuerthnerfaa582c2008-03-05 12:37:13 +0100879 list_add(&ap_dev->list, &ap_device_list);
Christian Maaser43c207e62008-12-25 13:38:42 +0100880 spin_unlock_bh(&ap_device_list_lock);
Ralph Wuerthnerfaa582c2008-03-05 12:37:13 +0100881 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200882 return rc;
883}
884
885/**
Felix Beck1749a812008-04-17 07:46:28 +0200886 * __ap_flush_queue(): Flush requests.
887 * @ap_dev: Pointer to the AP device
888 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200889 * Flush all requests from the request/pending queue of an AP device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200890 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +0100891static void __ap_flush_queue(struct ap_device *ap_dev)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200892{
893 struct ap_message *ap_msg, *next;
894
895 list_for_each_entry_safe(ap_msg, next, &ap_dev->pendingq, list) {
896 list_del_init(&ap_msg->list);
897 ap_dev->pendingq_count--;
Holger Dengler54a8f562012-05-16 14:08:22 +0200898 ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200899 }
900 list_for_each_entry_safe(ap_msg, next, &ap_dev->requestq, list) {
901 list_del_init(&ap_msg->list);
902 ap_dev->requestq_count--;
Holger Dengler54a8f562012-05-16 14:08:22 +0200903 ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200904 }
905}
906
907void ap_flush_queue(struct ap_device *ap_dev)
908{
909 spin_lock_bh(&ap_dev->lock);
910 __ap_flush_queue(ap_dev);
911 spin_unlock_bh(&ap_dev->lock);
912}
913EXPORT_SYMBOL(ap_flush_queue);
914
915static int ap_device_remove(struct device *dev)
916{
917 struct ap_device *ap_dev = to_ap_dev(dev);
918 struct ap_driver *ap_drv = ap_dev->drv;
919
Ralph Wuerthner4e562962006-10-04 20:02:05 +0200920 ap_flush_queue(ap_dev);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200921 del_timer_sync(&ap_dev->timeout);
Christian Maaser43c207e62008-12-25 13:38:42 +0100922 spin_lock_bh(&ap_device_list_lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +0100923 list_del_init(&ap_dev->list);
Christian Maaser43c207e62008-12-25 13:38:42 +0100924 spin_unlock_bh(&ap_device_list_lock);
Ralph Wuerthnerfaa582c2008-03-05 12:37:13 +0100925 if (ap_drv->remove)
926 ap_drv->remove(ap_dev);
Ralph Wuerthnere675c0d2007-03-26 20:42:43 +0200927 spin_lock_bh(&ap_dev->lock);
928 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
929 spin_unlock_bh(&ap_dev->lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200930 return 0;
931}
932
933int ap_driver_register(struct ap_driver *ap_drv, struct module *owner,
934 char *name)
935{
936 struct device_driver *drv = &ap_drv->driver;
937
938 drv->bus = &ap_bus_type;
939 drv->probe = ap_device_probe;
940 drv->remove = ap_device_remove;
941 drv->owner = owner;
942 drv->name = name;
943 return driver_register(drv);
944}
945EXPORT_SYMBOL(ap_driver_register);
946
947void ap_driver_unregister(struct ap_driver *ap_drv)
948{
949 driver_unregister(&ap_drv->driver);
950}
951EXPORT_SYMBOL(ap_driver_unregister);
952
Felix Beck1749a812008-04-17 07:46:28 +0200953/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200954 * AP bus attributes.
955 */
956static ssize_t ap_domain_show(struct bus_type *bus, char *buf)
957{
958 return snprintf(buf, PAGE_SIZE, "%d\n", ap_domain_index);
959}
960
961static BUS_ATTR(ap_domain, 0444, ap_domain_show, NULL);
962
963static ssize_t ap_config_time_show(struct bus_type *bus, char *buf)
964{
965 return snprintf(buf, PAGE_SIZE, "%d\n", ap_config_time);
966}
967
Felix Beckcb17a632008-12-25 13:38:41 +0100968static ssize_t ap_interrupts_show(struct bus_type *bus, char *buf)
969{
970 return snprintf(buf, PAGE_SIZE, "%d\n",
971 ap_using_interrupts() ? 1 : 0);
972}
973
974static BUS_ATTR(ap_interrupts, 0444, ap_interrupts_show, NULL);
975
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200976static ssize_t ap_config_time_store(struct bus_type *bus,
977 const char *buf, size_t count)
978{
979 int time;
980
981 if (sscanf(buf, "%d\n", &time) != 1 || time < 5 || time > 120)
982 return -EINVAL;
983 ap_config_time = time;
984 if (!timer_pending(&ap_config_timer) ||
985 !mod_timer(&ap_config_timer, jiffies + ap_config_time * HZ)) {
986 ap_config_timer.expires = jiffies + ap_config_time * HZ;
987 add_timer(&ap_config_timer);
988 }
989 return count;
990}
991
992static BUS_ATTR(config_time, 0644, ap_config_time_show, ap_config_time_store);
993
994static ssize_t ap_poll_thread_show(struct bus_type *bus, char *buf)
995{
996 return snprintf(buf, PAGE_SIZE, "%d\n", ap_poll_kthread ? 1 : 0);
997}
998
999static ssize_t ap_poll_thread_store(struct bus_type *bus,
1000 const char *buf, size_t count)
1001{
1002 int flag, rc;
1003
1004 if (sscanf(buf, "%d\n", &flag) != 1)
1005 return -EINVAL;
1006 if (flag) {
1007 rc = ap_poll_thread_start();
1008 if (rc)
1009 return rc;
1010 }
1011 else
1012 ap_poll_thread_stop();
1013 return count;
1014}
1015
1016static BUS_ATTR(poll_thread, 0644, ap_poll_thread_show, ap_poll_thread_store);
1017
Felix Beckfe137232008-07-14 09:59:08 +02001018static ssize_t poll_timeout_show(struct bus_type *bus, char *buf)
1019{
1020 return snprintf(buf, PAGE_SIZE, "%llu\n", poll_timeout);
1021}
1022
1023static ssize_t poll_timeout_store(struct bus_type *bus, const char *buf,
1024 size_t count)
1025{
1026 unsigned long long time;
1027 ktime_t hr_time;
1028
1029 /* 120 seconds = maximum poll interval */
Felix Beckcb17a632008-12-25 13:38:41 +01001030 if (sscanf(buf, "%llu\n", &time) != 1 || time < 1 ||
1031 time > 120000000000ULL)
Felix Beckfe137232008-07-14 09:59:08 +02001032 return -EINVAL;
1033 poll_timeout = time;
1034 hr_time = ktime_set(0, poll_timeout);
1035
1036 if (!hrtimer_is_queued(&ap_poll_timer) ||
Arjan van de Ven6c644ea2008-09-01 15:20:30 -07001037 !hrtimer_forward(&ap_poll_timer, hrtimer_get_expires(&ap_poll_timer), hr_time)) {
1038 hrtimer_set_expires(&ap_poll_timer, hr_time);
1039 hrtimer_start_expires(&ap_poll_timer, HRTIMER_MODE_ABS);
Felix Beckfe137232008-07-14 09:59:08 +02001040 }
1041 return count;
1042}
1043
1044static BUS_ATTR(poll_timeout, 0644, poll_timeout_show, poll_timeout_store);
1045
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001046static struct bus_attribute *const ap_bus_attrs[] = {
1047 &bus_attr_ap_domain,
1048 &bus_attr_config_time,
1049 &bus_attr_poll_thread,
Felix Beckcb17a632008-12-25 13:38:41 +01001050 &bus_attr_ap_interrupts,
Felix Beckfe137232008-07-14 09:59:08 +02001051 &bus_attr_poll_timeout,
1052 NULL,
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001053};
1054
Holger Dengler75014552012-08-28 16:41:50 +02001055static inline int ap_test_config(unsigned int *field, unsigned int nr)
1056{
1057 if (nr > 0xFFu)
1058 return 0;
1059 return ap_test_bit((field + (nr >> 5)), (nr & 0x1f));
1060}
1061
1062/*
1063 * ap_test_config_card_id(): Test, whether an AP card ID is configured.
1064 * @id AP card ID
1065 *
1066 * Returns 0 if the card is not configured
1067 * 1 if the card is configured or
1068 * if the configuration information is not available
1069 */
1070static inline int ap_test_config_card_id(unsigned int id)
1071{
1072 if (!ap_configuration)
1073 return 1;
1074 return ap_test_config(ap_configuration->apm, id);
1075}
1076
1077/*
1078 * ap_test_config_domain(): Test, whether an AP usage domain is configured.
1079 * @domain AP usage domain ID
1080 *
1081 * Returns 0 if the usage domain is not configured
1082 * 1 if the usage domain is configured or
1083 * if the configuration information is not available
1084 */
1085static inline int ap_test_config_domain(unsigned int domain)
1086{
1087 if (!ap_configuration)
1088 return 1;
1089 return ap_test_config(ap_configuration->aqm, domain);
1090}
1091
1092/**
1093 * ap_query_configuration(): Query AP configuration information.
1094 *
1095 * Query information of installed cards and configured domains from AP.
1096 */
1097static void ap_query_configuration(void)
1098{
1099#ifdef CONFIG_64BIT
1100 if (ap_configuration_available()) {
1101 if (!ap_configuration)
1102 ap_configuration =
1103 kzalloc(sizeof(struct ap_config_info),
1104 GFP_KERNEL);
1105 if (ap_configuration)
1106 __ap_query_configuration(ap_configuration);
1107 } else
1108 ap_configuration = NULL;
1109#else
1110 ap_configuration = NULL;
1111#endif
1112}
1113
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001114/**
Felix Beck1749a812008-04-17 07:46:28 +02001115 * ap_select_domain(): Select an AP domain.
1116 *
1117 * Pick one of the 16 AP domains.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001118 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +01001119static int ap_select_domain(void)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001120{
1121 int queue_depth, device_type, count, max_count, best_domain;
Holger Dengler75014552012-08-28 16:41:50 +02001122 ap_qid_t qid;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001123 int rc, i, j;
1124
Felix Beck1749a812008-04-17 07:46:28 +02001125 /*
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001126 * We want to use a single domain. Either the one specified with
1127 * the "domain=" parameter or the domain with the maximum number
1128 * of devices.
1129 */
1130 if (ap_domain_index >= 0 && ap_domain_index < AP_DOMAINS)
1131 /* Domain has already been selected. */
1132 return 0;
1133 best_domain = -1;
1134 max_count = 0;
1135 for (i = 0; i < AP_DOMAINS; i++) {
Holger Dengler75014552012-08-28 16:41:50 +02001136 if (!ap_test_config_domain(i))
1137 continue;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001138 count = 0;
1139 for (j = 0; j < AP_DEVICES; j++) {
Holger Dengler75014552012-08-28 16:41:50 +02001140 if (!ap_test_config_card_id(j))
1141 continue;
1142 qid = AP_MKQID(j, i);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001143 rc = ap_query_queue(qid, &queue_depth, &device_type);
1144 if (rc)
1145 continue;
1146 count++;
1147 }
1148 if (count > max_count) {
1149 max_count = count;
1150 best_domain = i;
1151 }
1152 }
1153 if (best_domain >= 0){
1154 ap_domain_index = best_domain;
1155 return 0;
1156 }
1157 return -ENODEV;
1158}
1159
1160/**
Felix Beck1749a812008-04-17 07:46:28 +02001161 * ap_probe_device_type(): Find the device type of an AP.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001162 * @ap_dev: pointer to the AP device.
Felix Beck1749a812008-04-17 07:46:28 +02001163 *
1164 * Find the device type if query queue returned a device type of 0.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001165 */
1166static int ap_probe_device_type(struct ap_device *ap_dev)
1167{
1168 static unsigned char msg[] = {
1169 0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
1170 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1171 0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,
1172 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1173 0x01,0x00,0x43,0x43,0x41,0x2d,0x41,0x50,
1174 0x50,0x4c,0x20,0x20,0x20,0x01,0x01,0x01,
1175 0x00,0x00,0x00,0x00,0x50,0x4b,0x00,0x00,
1176 0x00,0x00,0x01,0x1c,0x00,0x00,0x00,0x00,
1177 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1178 0x00,0x00,0x05,0xb8,0x00,0x00,0x00,0x00,
1179 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1180 0x70,0x00,0x41,0x00,0x00,0x00,0x00,0x00,
1181 0x00,0x00,0x54,0x32,0x01,0x00,0xa0,0x00,
1182 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1183 0x00,0x00,0x00,0x00,0xb8,0x05,0x00,0x00,
1184 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1185 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1186 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1187 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1188 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1189 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1190 0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,
1191 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1192 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,
1193 0x49,0x43,0x53,0x46,0x20,0x20,0x20,0x20,
1194 0x50,0x4b,0x0a,0x00,0x50,0x4b,0x43,0x53,
1195 0x2d,0x31,0x2e,0x32,0x37,0x00,0x11,0x22,
1196 0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,
1197 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,
1198 0x99,0x00,0x11,0x22,0x33,0x44,0x55,0x66,
1199 0x77,0x88,0x99,0x00,0x11,0x22,0x33,0x44,
1200 0x55,0x66,0x77,0x88,0x99,0x00,0x11,0x22,
1201 0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,
1202 0x11,0x22,0x33,0x5d,0x00,0x5b,0x00,0x77,
1203 0x88,0x1e,0x00,0x00,0x57,0x00,0x00,0x00,
1204 0x00,0x04,0x00,0x00,0x4f,0x00,0x00,0x00,
1205 0x03,0x02,0x00,0x00,0x40,0x01,0x00,0x01,
1206 0xce,0x02,0x68,0x2d,0x5f,0xa9,0xde,0x0c,
1207 0xf6,0xd2,0x7b,0x58,0x4b,0xf9,0x28,0x68,
1208 0x3d,0xb4,0xf4,0xef,0x78,0xd5,0xbe,0x66,
1209 0x63,0x42,0xef,0xf8,0xfd,0xa4,0xf8,0xb0,
1210 0x8e,0x29,0xc2,0xc9,0x2e,0xd8,0x45,0xb8,
1211 0x53,0x8c,0x6f,0x4e,0x72,0x8f,0x6c,0x04,
1212 0x9c,0x88,0xfc,0x1e,0xc5,0x83,0x55,0x57,
1213 0xf7,0xdd,0xfd,0x4f,0x11,0x36,0x95,0x5d,
1214 };
1215 struct ap_queue_status status;
1216 unsigned long long psmid;
1217 char *reply;
1218 int rc, i;
1219
1220 reply = (void *) get_zeroed_page(GFP_KERNEL);
1221 if (!reply) {
1222 rc = -ENOMEM;
1223 goto out;
1224 }
1225
1226 status = __ap_send(ap_dev->qid, 0x0102030405060708ULL,
Felix Becka6a5d732009-12-07 12:51:55 +01001227 msg, sizeof(msg), 0);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001228 if (status.response_code != AP_RESPONSE_NORMAL) {
1229 rc = -ENODEV;
1230 goto out_free;
1231 }
1232
1233 /* Wait for the test message to complete. */
1234 for (i = 0; i < 6; i++) {
1235 mdelay(300);
1236 status = __ap_recv(ap_dev->qid, &psmid, reply, 4096);
1237 if (status.response_code == AP_RESPONSE_NORMAL &&
1238 psmid == 0x0102030405060708ULL)
1239 break;
1240 }
1241 if (i < 6) {
1242 /* Got an answer. */
1243 if (reply[0] == 0x00 && reply[1] == 0x86)
1244 ap_dev->device_type = AP_DEVICE_TYPE_PCICC;
1245 else
1246 ap_dev->device_type = AP_DEVICE_TYPE_PCICA;
1247 rc = 0;
1248 } else
1249 rc = -ENODEV;
1250
1251out_free:
1252 free_page((unsigned long) reply);
1253out:
1254 return rc;
1255}
1256
Felix Beckcb17a632008-12-25 13:38:41 +01001257static void ap_interrupt_handler(void *unused1, void *unused2)
1258{
Holger Dengler62d146f2011-01-05 12:47:38 +01001259 kstat_cpu(smp_processor_id()).irqs[IOINT_APB]++;
Felix Beckcb17a632008-12-25 13:38:41 +01001260 tasklet_schedule(&ap_tasklet);
1261}
1262
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001263/**
Felix Beck1749a812008-04-17 07:46:28 +02001264 * __ap_scan_bus(): Scan the AP bus.
1265 * @dev: Pointer to device
1266 * @data: Pointer to data
1267 *
1268 * Scan the AP bus for new devices.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001269 */
1270static int __ap_scan_bus(struct device *dev, void *data)
1271{
1272 return to_ap_dev(dev)->qid == (ap_qid_t)(unsigned long) data;
1273}
1274
1275static void ap_device_release(struct device *dev)
1276{
1277 struct ap_device *ap_dev = to_ap_dev(dev);
1278
1279 kfree(ap_dev);
1280}
1281
Al Viro4927b3f2006-12-06 19:18:20 +00001282static void ap_scan_bus(struct work_struct *unused)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001283{
1284 struct ap_device *ap_dev;
1285 struct device *dev;
1286 ap_qid_t qid;
1287 int queue_depth, device_type;
Holger Dengler6bed05b2011-07-24 10:48:25 +02001288 unsigned int device_functions;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001289 int rc, i;
1290
Holger Dengler75014552012-08-28 16:41:50 +02001291 ap_query_configuration();
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001292 if (ap_select_domain() != 0)
1293 return;
1294 for (i = 0; i < AP_DEVICES; i++) {
1295 qid = AP_MKQID(i, ap_domain_index);
1296 dev = bus_find_device(&ap_bus_type, NULL,
1297 (void *)(unsigned long)qid,
1298 __ap_scan_bus);
Holger Dengler75014552012-08-28 16:41:50 +02001299 if (ap_test_config_card_id(i))
1300 rc = ap_query_queue(qid, &queue_depth, &device_type);
1301 else
1302 rc = -ENODEV;
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001303 if (dev) {
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001304 if (rc == -EBUSY) {
1305 set_current_state(TASK_UNINTERRUPTIBLE);
1306 schedule_timeout(AP_RESET_TIMEOUT);
1307 rc = ap_query_queue(qid, &queue_depth,
1308 &device_type);
1309 }
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001310 ap_dev = to_ap_dev(dev);
1311 spin_lock_bh(&ap_dev->lock);
1312 if (rc || ap_dev->unregistered) {
1313 spin_unlock_bh(&ap_dev->lock);
Felix Beck5314af62009-09-22 22:58:51 +02001314 if (ap_dev->unregistered)
1315 i--;
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001316 device_unregister(dev);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001317 put_device(dev);
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001318 continue;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001319 }
1320 spin_unlock_bh(&ap_dev->lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001321 put_device(dev);
1322 continue;
1323 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001324 if (rc)
1325 continue;
1326 rc = ap_init_queue(qid);
1327 if (rc)
1328 continue;
1329 ap_dev = kzalloc(sizeof(*ap_dev), GFP_KERNEL);
1330 if (!ap_dev)
1331 break;
1332 ap_dev->qid = qid;
1333 ap_dev->queue_depth = queue_depth;
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001334 ap_dev->unregistered = 1;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001335 spin_lock_init(&ap_dev->lock);
1336 INIT_LIST_HEAD(&ap_dev->pendingq);
1337 INIT_LIST_HEAD(&ap_dev->requestq);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001338 INIT_LIST_HEAD(&ap_dev->list);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001339 setup_timer(&ap_dev->timeout, ap_request_timeout,
1340 (unsigned long) ap_dev);
Holger Dengler6bed05b2011-07-24 10:48:25 +02001341 switch (device_type) {
1342 case 0:
Holger Denglercf2d0072011-05-23 10:24:30 +02001343 if (ap_probe_device_type(ap_dev)) {
1344 kfree(ap_dev);
1345 continue;
1346 }
Holger Dengler6bed05b2011-07-24 10:48:25 +02001347 break;
1348 case 10:
1349 if (ap_query_functions(qid, &device_functions)) {
1350 kfree(ap_dev);
1351 continue;
1352 }
Holger Denglerb26bd942012-08-28 16:43:48 +02001353 ap_dev->functions = device_functions;
Holger Dengler75014552012-08-28 16:41:50 +02001354 if (ap_test_bit(&device_functions, 3))
Holger Dengler6bed05b2011-07-24 10:48:25 +02001355 ap_dev->device_type = AP_DEVICE_TYPE_CEX3C;
Holger Dengler75014552012-08-28 16:41:50 +02001356 else if (ap_test_bit(&device_functions, 4))
Holger Dengler6bed05b2011-07-24 10:48:25 +02001357 ap_dev->device_type = AP_DEVICE_TYPE_CEX3A;
1358 else {
1359 kfree(ap_dev);
1360 continue;
1361 }
1362 break;
1363 default:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001364 ap_dev->device_type = device_type;
Holger Dengler6bed05b2011-07-24 10:48:25 +02001365 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001366
1367 ap_dev->device.bus = &ap_bus_type;
1368 ap_dev->device.parent = ap_root_device;
Felix Beckedc44fa2009-09-11 10:28:52 +02001369 if (dev_set_name(&ap_dev->device, "card%02x",
1370 AP_QID_DEVICE(ap_dev->qid))) {
1371 kfree(ap_dev);
1372 continue;
1373 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001374 ap_dev->device.release = ap_device_release;
1375 rc = device_register(&ap_dev->device);
1376 if (rc) {
Sebastian Ottc6304932009-09-11 10:28:38 +02001377 put_device(&ap_dev->device);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001378 continue;
1379 }
1380 /* Add device attributes. */
1381 rc = sysfs_create_group(&ap_dev->device.kobj,
1382 &ap_dev_attr_group);
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001383 if (!rc) {
1384 spin_lock_bh(&ap_dev->lock);
1385 ap_dev->unregistered = 0;
1386 spin_unlock_bh(&ap_dev->lock);
1387 }
1388 else
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001389 device_unregister(&ap_dev->device);
1390 }
1391}
1392
1393static void
1394ap_config_timeout(unsigned long ptr)
1395{
1396 queue_work(ap_work_queue, &ap_config_work);
1397 ap_config_timer.expires = jiffies + ap_config_time * HZ;
1398 add_timer(&ap_config_timer);
1399}
1400
1401/**
Holger Denglerbc615de2011-11-14 11:19:04 +01001402 * __ap_schedule_poll_timer(): Schedule poll timer.
Felix Beck1749a812008-04-17 07:46:28 +02001403 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001404 * Set up the timer to run the poll tasklet
1405 */
Holger Denglerbc615de2011-11-14 11:19:04 +01001406static inline void __ap_schedule_poll_timer(void)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001407{
Felix Beck8d406c62009-07-24 12:39:53 +02001408 ktime_t hr_time;
Felix Beck93521312009-12-07 12:52:00 +01001409
1410 spin_lock_bh(&ap_poll_timer_lock);
Holger Denglerbc615de2011-11-14 11:19:04 +01001411 if (hrtimer_is_queued(&ap_poll_timer) || ap_suspend_flag)
Felix Beck93521312009-12-07 12:52:00 +01001412 goto out;
Felix Beck8d406c62009-07-24 12:39:53 +02001413 if (ktime_to_ns(hrtimer_expires_remaining(&ap_poll_timer)) <= 0) {
1414 hr_time = ktime_set(0, poll_timeout);
1415 hrtimer_forward_now(&ap_poll_timer, hr_time);
1416 hrtimer_restart(&ap_poll_timer);
1417 }
Felix Beck93521312009-12-07 12:52:00 +01001418out:
1419 spin_unlock_bh(&ap_poll_timer_lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001420}
1421
1422/**
Holger Denglerbc615de2011-11-14 11:19:04 +01001423 * ap_schedule_poll_timer(): Schedule poll timer.
1424 *
1425 * Set up the timer to run the poll tasklet
1426 */
1427static inline void ap_schedule_poll_timer(void)
1428{
1429 if (ap_using_interrupts())
1430 return;
1431 __ap_schedule_poll_timer();
1432}
1433
1434/**
Felix Beck1749a812008-04-17 07:46:28 +02001435 * ap_poll_read(): Receive pending reply messages from an AP device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001436 * @ap_dev: pointer to the AP device
1437 * @flags: pointer to control flags, bit 2^0 is set if another poll is
1438 * required, bit 2^1 is set if the poll timer needs to get armed
Felix Beck1749a812008-04-17 07:46:28 +02001439 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001440 * Returns 0 if the device is still present, -ENODEV if not.
1441 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +01001442static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001443{
1444 struct ap_queue_status status;
1445 struct ap_message *ap_msg;
1446
1447 if (ap_dev->queue_count <= 0)
1448 return 0;
1449 status = __ap_recv(ap_dev->qid, &ap_dev->reply->psmid,
1450 ap_dev->reply->message, ap_dev->reply->length);
1451 switch (status.response_code) {
1452 case AP_RESPONSE_NORMAL:
1453 atomic_dec(&ap_poll_requests);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001454 ap_decrease_queue_count(ap_dev);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001455 list_for_each_entry(ap_msg, &ap_dev->pendingq, list) {
1456 if (ap_msg->psmid != ap_dev->reply->psmid)
1457 continue;
1458 list_del_init(&ap_msg->list);
1459 ap_dev->pendingq_count--;
Holger Dengler54a8f562012-05-16 14:08:22 +02001460 ap_msg->receive(ap_dev, ap_msg, ap_dev->reply);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001461 break;
1462 }
1463 if (ap_dev->queue_count > 0)
1464 *flags |= 1;
1465 break;
1466 case AP_RESPONSE_NO_PENDING_REPLY:
1467 if (status.queue_empty) {
1468 /* The card shouldn't forget requests but who knows. */
Ralph Wuerthnere675c0d2007-03-26 20:42:43 +02001469 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001470 ap_dev->queue_count = 0;
1471 list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
1472 ap_dev->requestq_count += ap_dev->pendingq_count;
1473 ap_dev->pendingq_count = 0;
1474 } else
1475 *flags |= 2;
1476 break;
1477 default:
1478 return -ENODEV;
1479 }
1480 return 0;
1481}
1482
1483/**
Felix Beck1749a812008-04-17 07:46:28 +02001484 * ap_poll_write(): Send messages from the request queue to an AP device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001485 * @ap_dev: pointer to the AP device
1486 * @flags: pointer to control flags, bit 2^0 is set if another poll is
1487 * required, bit 2^1 is set if the poll timer needs to get armed
Felix Beck1749a812008-04-17 07:46:28 +02001488 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001489 * Returns 0 if the device is still present, -ENODEV if not.
1490 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +01001491static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001492{
1493 struct ap_queue_status status;
1494 struct ap_message *ap_msg;
1495
1496 if (ap_dev->requestq_count <= 0 ||
1497 ap_dev->queue_count >= ap_dev->queue_depth)
1498 return 0;
1499 /* Start the next request on the queue. */
1500 ap_msg = list_entry(ap_dev->requestq.next, struct ap_message, list);
1501 status = __ap_send(ap_dev->qid, ap_msg->psmid,
Felix Becka6a5d732009-12-07 12:51:55 +01001502 ap_msg->message, ap_msg->length, ap_msg->special);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001503 switch (status.response_code) {
1504 case AP_RESPONSE_NORMAL:
1505 atomic_inc(&ap_poll_requests);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001506 ap_increase_queue_count(ap_dev);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001507 list_move_tail(&ap_msg->list, &ap_dev->pendingq);
1508 ap_dev->requestq_count--;
1509 ap_dev->pendingq_count++;
1510 if (ap_dev->queue_count < ap_dev->queue_depth &&
1511 ap_dev->requestq_count > 0)
1512 *flags |= 1;
1513 *flags |= 2;
1514 break;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001515 case AP_RESPONSE_RESET_IN_PROGRESS:
Holger Denglerbc615de2011-11-14 11:19:04 +01001516 __ap_schedule_poll_timer();
1517 case AP_RESPONSE_Q_FULL:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001518 *flags |= 2;
1519 break;
1520 case AP_RESPONSE_MESSAGE_TOO_BIG:
Felix Becka6a5d732009-12-07 12:51:55 +01001521 case AP_RESPONSE_REQ_FAC_NOT_INST:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001522 return -EINVAL;
1523 default:
1524 return -ENODEV;
1525 }
1526 return 0;
1527}
1528
1529/**
Felix Beck1749a812008-04-17 07:46:28 +02001530 * ap_poll_queue(): Poll AP device for pending replies and send new messages.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001531 * @ap_dev: pointer to the bus device
1532 * @flags: pointer to control flags, bit 2^0 is set if another poll is
1533 * required, bit 2^1 is set if the poll timer needs to get armed
Felix Beck1749a812008-04-17 07:46:28 +02001534 *
1535 * Poll AP device for pending replies and send new messages. If either
1536 * ap_poll_read or ap_poll_write returns -ENODEV unregister the device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001537 * Returns 0.
1538 */
1539static inline int ap_poll_queue(struct ap_device *ap_dev, unsigned long *flags)
1540{
1541 int rc;
1542
1543 rc = ap_poll_read(ap_dev, flags);
1544 if (rc)
1545 return rc;
1546 return ap_poll_write(ap_dev, flags);
1547}
1548
1549/**
Felix Beck1749a812008-04-17 07:46:28 +02001550 * __ap_queue_message(): Queue a message to a device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001551 * @ap_dev: pointer to the AP device
1552 * @ap_msg: the message to be queued
Felix Beck1749a812008-04-17 07:46:28 +02001553 *
1554 * Queue a message to a device. Returns 0 if successful.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001555 */
1556static int __ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
1557{
1558 struct ap_queue_status status;
1559
1560 if (list_empty(&ap_dev->requestq) &&
1561 ap_dev->queue_count < ap_dev->queue_depth) {
1562 status = __ap_send(ap_dev->qid, ap_msg->psmid,
Felix Becka6a5d732009-12-07 12:51:55 +01001563 ap_msg->message, ap_msg->length,
1564 ap_msg->special);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001565 switch (status.response_code) {
1566 case AP_RESPONSE_NORMAL:
1567 list_add_tail(&ap_msg->list, &ap_dev->pendingq);
1568 atomic_inc(&ap_poll_requests);
1569 ap_dev->pendingq_count++;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001570 ap_increase_queue_count(ap_dev);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001571 ap_dev->total_request_count++;
1572 break;
1573 case AP_RESPONSE_Q_FULL:
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001574 case AP_RESPONSE_RESET_IN_PROGRESS:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001575 list_add_tail(&ap_msg->list, &ap_dev->requestq);
1576 ap_dev->requestq_count++;
1577 ap_dev->total_request_count++;
1578 return -EBUSY;
Felix Becka6a5d732009-12-07 12:51:55 +01001579 case AP_RESPONSE_REQ_FAC_NOT_INST:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001580 case AP_RESPONSE_MESSAGE_TOO_BIG:
Holger Dengler54a8f562012-05-16 14:08:22 +02001581 ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL));
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001582 return -EINVAL;
1583 default: /* Device is gone. */
Holger Dengler54a8f562012-05-16 14:08:22 +02001584 ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001585 return -ENODEV;
1586 }
1587 } else {
1588 list_add_tail(&ap_msg->list, &ap_dev->requestq);
1589 ap_dev->requestq_count++;
1590 ap_dev->total_request_count++;
1591 return -EBUSY;
1592 }
1593 ap_schedule_poll_timer();
1594 return 0;
1595}
1596
1597void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
1598{
1599 unsigned long flags;
1600 int rc;
1601
Holger Dengler54a8f562012-05-16 14:08:22 +02001602 /* For asynchronous message handling a valid receive-callback
1603 * is required. */
1604 BUG_ON(!ap_msg->receive);
1605
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001606 spin_lock_bh(&ap_dev->lock);
1607 if (!ap_dev->unregistered) {
1608 /* Make room on the queue by polling for finished requests. */
1609 rc = ap_poll_queue(ap_dev, &flags);
1610 if (!rc)
1611 rc = __ap_queue_message(ap_dev, ap_msg);
1612 if (!rc)
1613 wake_up(&ap_poll_wait);
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001614 if (rc == -ENODEV)
1615 ap_dev->unregistered = 1;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001616 } else {
Holger Dengler54a8f562012-05-16 14:08:22 +02001617 ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001618 rc = -ENODEV;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001619 }
1620 spin_unlock_bh(&ap_dev->lock);
1621 if (rc == -ENODEV)
1622 device_unregister(&ap_dev->device);
1623}
1624EXPORT_SYMBOL(ap_queue_message);
1625
1626/**
Felix Beck1749a812008-04-17 07:46:28 +02001627 * ap_cancel_message(): Cancel a crypto request.
1628 * @ap_dev: The AP device that has the message queued
1629 * @ap_msg: The message that is to be removed
1630 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001631 * Cancel a crypto request. This is done by removing the request
Felix Beck1749a812008-04-17 07:46:28 +02001632 * from the device pending or request queue. Note that the
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001633 * request stays on the AP queue. When it finishes the message
1634 * reply will be discarded because the psmid can't be found.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001635 */
1636void ap_cancel_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
1637{
1638 struct ap_message *tmp;
1639
1640 spin_lock_bh(&ap_dev->lock);
1641 if (!list_empty(&ap_msg->list)) {
1642 list_for_each_entry(tmp, &ap_dev->pendingq, list)
1643 if (tmp->psmid == ap_msg->psmid) {
1644 ap_dev->pendingq_count--;
1645 goto found;
1646 }
1647 ap_dev->requestq_count--;
1648 found:
1649 list_del_init(&ap_msg->list);
1650 }
1651 spin_unlock_bh(&ap_dev->lock);
1652}
1653EXPORT_SYMBOL(ap_cancel_message);
1654
1655/**
Felix Beck1749a812008-04-17 07:46:28 +02001656 * ap_poll_timeout(): AP receive polling for finished AP requests.
Felix Beckfe137232008-07-14 09:59:08 +02001657 * @unused: Unused pointer.
Felix Beck1749a812008-04-17 07:46:28 +02001658 *
Felix Beckfe137232008-07-14 09:59:08 +02001659 * Schedules the AP tasklet using a high resolution timer.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001660 */
Felix Beckfe137232008-07-14 09:59:08 +02001661static enum hrtimer_restart ap_poll_timeout(struct hrtimer *unused)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001662{
1663 tasklet_schedule(&ap_tasklet);
Felix Beckfe137232008-07-14 09:59:08 +02001664 return HRTIMER_NORESTART;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001665}
1666
1667/**
Felix Beck1749a812008-04-17 07:46:28 +02001668 * ap_reset(): Reset a not responding AP device.
1669 * @ap_dev: Pointer to the AP device
1670 *
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001671 * Reset a not responding AP device and move all requests from the
1672 * pending queue to the request queue.
1673 */
1674static void ap_reset(struct ap_device *ap_dev)
1675{
1676 int rc;
1677
1678 ap_dev->reset = AP_RESET_IGNORE;
1679 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
1680 ap_dev->queue_count = 0;
1681 list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
1682 ap_dev->requestq_count += ap_dev->pendingq_count;
1683 ap_dev->pendingq_count = 0;
1684 rc = ap_init_queue(ap_dev->qid);
1685 if (rc == -ENODEV)
1686 ap_dev->unregistered = 1;
Holger Dengler75464962011-12-01 13:32:23 +01001687 else
1688 __ap_schedule_poll_timer();
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001689}
1690
Christian Maaser43c207e62008-12-25 13:38:42 +01001691static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001692{
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001693 if (!ap_dev->unregistered) {
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001694 if (ap_poll_queue(ap_dev, flags))
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001695 ap_dev->unregistered = 1;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001696 if (ap_dev->reset == AP_RESET_DO)
1697 ap_reset(ap_dev);
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001698 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001699 return 0;
1700}
1701
Felix Beck1749a812008-04-17 07:46:28 +02001702/**
1703 * ap_poll_all(): Poll all AP devices.
1704 * @dummy: Unused variable
1705 *
1706 * Poll all AP devices on the bus in a round robin fashion. Continue
1707 * polling until bit 2^0 of the control flags is not set. If bit 2^1
1708 * of the control flags has been set arm the poll timer.
1709 */
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001710static void ap_poll_all(unsigned long dummy)
1711{
1712 unsigned long flags;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001713 struct ap_device *ap_dev;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001714
Felix Beckcb17a632008-12-25 13:38:41 +01001715 /* Reset the indicator if interrupts are used. Thus new interrupts can
1716 * be received. Doing it in the beginning of the tasklet is therefor
1717 * important that no requests on any AP get lost.
1718 */
1719 if (ap_using_interrupts())
1720 xchg((u8 *)ap_interrupt_indicator, 0);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001721 do {
1722 flags = 0;
Christian Maaser43c207e62008-12-25 13:38:42 +01001723 spin_lock(&ap_device_list_lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001724 list_for_each_entry(ap_dev, &ap_device_list, list) {
Felix Beck95f15562009-09-11 10:28:51 +02001725 spin_lock(&ap_dev->lock);
Christian Maaser43c207e62008-12-25 13:38:42 +01001726 __ap_poll_device(ap_dev, &flags);
Felix Beck95f15562009-09-11 10:28:51 +02001727 spin_unlock(&ap_dev->lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001728 }
Christian Maaser43c207e62008-12-25 13:38:42 +01001729 spin_unlock(&ap_device_list_lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001730 } while (flags & 1);
1731 if (flags & 2)
1732 ap_schedule_poll_timer();
1733}
1734
1735/**
Felix Beck1749a812008-04-17 07:46:28 +02001736 * ap_poll_thread(): Thread that polls for finished requests.
1737 * @data: Unused pointer
1738 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001739 * AP bus poll thread. The purpose of this thread is to poll for
1740 * finished requests in a loop if there is a "free" cpu - that is
1741 * a cpu that doesn't have anything better to do. The polling stops
1742 * as soon as there is another task or if all messages have been
1743 * delivered.
1744 */
1745static int ap_poll_thread(void *data)
1746{
1747 DECLARE_WAITQUEUE(wait, current);
1748 unsigned long flags;
1749 int requests;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001750 struct ap_device *ap_dev;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001751
Christian Borntraegerd83682b2006-10-06 16:38:22 +02001752 set_user_nice(current, 19);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001753 while (1) {
Felix Beck772f5472009-06-22 12:08:16 +02001754 if (ap_suspend_flag)
1755 return 0;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001756 if (need_resched()) {
1757 schedule();
1758 continue;
1759 }
1760 add_wait_queue(&ap_poll_wait, &wait);
1761 set_current_state(TASK_INTERRUPTIBLE);
1762 if (kthread_should_stop())
1763 break;
1764 requests = atomic_read(&ap_poll_requests);
1765 if (requests <= 0)
1766 schedule();
1767 set_current_state(TASK_RUNNING);
1768 remove_wait_queue(&ap_poll_wait, &wait);
1769
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001770 flags = 0;
Christian Maaser43c207e62008-12-25 13:38:42 +01001771 spin_lock_bh(&ap_device_list_lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001772 list_for_each_entry(ap_dev, &ap_device_list, list) {
Felix Beck95f15562009-09-11 10:28:51 +02001773 spin_lock(&ap_dev->lock);
Christian Maaser43c207e62008-12-25 13:38:42 +01001774 __ap_poll_device(ap_dev, &flags);
Felix Beck95f15562009-09-11 10:28:51 +02001775 spin_unlock(&ap_dev->lock);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001776 }
Christian Maaser43c207e62008-12-25 13:38:42 +01001777 spin_unlock_bh(&ap_device_list_lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001778 }
1779 set_current_state(TASK_RUNNING);
1780 remove_wait_queue(&ap_poll_wait, &wait);
1781 return 0;
1782}
1783
1784static int ap_poll_thread_start(void)
1785{
1786 int rc;
1787
Felix Beck772f5472009-06-22 12:08:16 +02001788 if (ap_using_interrupts() || ap_suspend_flag)
Felix Beckcb17a632008-12-25 13:38:41 +01001789 return 0;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001790 mutex_lock(&ap_poll_thread_mutex);
1791 if (!ap_poll_kthread) {
1792 ap_poll_kthread = kthread_run(ap_poll_thread, NULL, "appoll");
1793 rc = IS_ERR(ap_poll_kthread) ? PTR_ERR(ap_poll_kthread) : 0;
1794 if (rc)
1795 ap_poll_kthread = NULL;
1796 }
1797 else
1798 rc = 0;
1799 mutex_unlock(&ap_poll_thread_mutex);
1800 return rc;
1801}
1802
1803static void ap_poll_thread_stop(void)
1804{
1805 mutex_lock(&ap_poll_thread_mutex);
1806 if (ap_poll_kthread) {
1807 kthread_stop(ap_poll_kthread);
1808 ap_poll_kthread = NULL;
1809 }
1810 mutex_unlock(&ap_poll_thread_mutex);
1811}
1812
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001813/**
Felix Beck1749a812008-04-17 07:46:28 +02001814 * ap_request_timeout(): Handling of request timeouts
1815 * @data: Holds the AP device.
1816 *
1817 * Handles request timeouts.
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001818 */
1819static void ap_request_timeout(unsigned long data)
1820{
1821 struct ap_device *ap_dev = (struct ap_device *) data;
1822
Felix Beckcb17a632008-12-25 13:38:41 +01001823 if (ap_dev->reset == AP_RESET_ARMED) {
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001824 ap_dev->reset = AP_RESET_DO;
Felix Beckcb17a632008-12-25 13:38:41 +01001825
1826 if (ap_using_interrupts())
1827 tasklet_schedule(&ap_tasklet);
1828 }
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001829}
1830
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001831static void ap_reset_domain(void)
1832{
1833 int i;
1834
Ralph Wuerthner39aa7cf2007-10-12 16:11:29 +02001835 if (ap_domain_index != -1)
1836 for (i = 0; i < AP_DEVICES; i++)
1837 ap_reset_queue(AP_MKQID(i, ap_domain_index));
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001838}
1839
1840static void ap_reset_all(void)
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001841{
1842 int i, j;
1843
1844 for (i = 0; i < AP_DOMAINS; i++)
1845 for (j = 0; j < AP_DEVICES; j++)
1846 ap_reset_queue(AP_MKQID(j, i));
1847}
1848
1849static struct reset_call ap_reset_call = {
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001850 .fn = ap_reset_all,
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001851};
1852
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001853/**
Felix Beck1749a812008-04-17 07:46:28 +02001854 * ap_module_init(): The module initialization code.
1855 *
1856 * Initializes the module.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001857 */
1858int __init ap_module_init(void)
1859{
1860 int rc, i;
1861
1862 if (ap_domain_index < -1 || ap_domain_index >= AP_DOMAINS) {
Martin Schwidefsky136f7a12008-12-25 13:39:46 +01001863 pr_warning("%d is not a valid cryptographic domain\n",
1864 ap_domain_index);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001865 return -EINVAL;
1866 }
Felix Beck5314af62009-09-22 22:58:51 +02001867 /* In resume callback we need to know if the user had set the domain.
1868 * If so, we can not just reset it.
1869 */
1870 if (ap_domain_index >= 0)
1871 user_set_domain = 1;
1872
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001873 if (ap_instructions_available() != 0) {
Martin Schwidefsky136f7a12008-12-25 13:39:46 +01001874 pr_warning("The hardware system does not support "
1875 "AP instructions\n");
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001876 return -ENODEV;
1877 }
Felix Beckcb17a632008-12-25 13:38:41 +01001878 if (ap_interrupts_available()) {
1879 isc_register(AP_ISC);
1880 ap_interrupt_indicator = s390_register_adapter_interrupt(
1881 &ap_interrupt_handler, NULL, AP_ISC);
1882 if (IS_ERR(ap_interrupt_indicator)) {
1883 ap_interrupt_indicator = NULL;
1884 isc_unregister(AP_ISC);
1885 }
1886 }
1887
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001888 register_reset_call(&ap_reset_call);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001889
1890 /* Create /sys/bus/ap. */
1891 rc = bus_register(&ap_bus_type);
1892 if (rc)
1893 goto out;
1894 for (i = 0; ap_bus_attrs[i]; i++) {
1895 rc = bus_create_file(&ap_bus_type, ap_bus_attrs[i]);
1896 if (rc)
1897 goto out_bus;
1898 }
1899
1900 /* Create /sys/devices/ap. */
Mark McLoughlin035da162008-12-15 12:58:29 +00001901 ap_root_device = root_device_register("ap");
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001902 rc = IS_ERR(ap_root_device) ? PTR_ERR(ap_root_device) : 0;
1903 if (rc)
1904 goto out_bus;
1905
1906 ap_work_queue = create_singlethread_workqueue("kapwork");
1907 if (!ap_work_queue) {
1908 rc = -ENOMEM;
1909 goto out_root;
1910 }
1911
Holger Dengler75014552012-08-28 16:41:50 +02001912 ap_query_configuration();
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001913 if (ap_select_domain() == 0)
1914 ap_scan_bus(NULL);
1915
Felix Beck1749a812008-04-17 07:46:28 +02001916 /* Setup the AP bus rescan timer. */
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001917 init_timer(&ap_config_timer);
1918 ap_config_timer.function = ap_config_timeout;
1919 ap_config_timer.data = 0;
1920 ap_config_timer.expires = jiffies + ap_config_time * HZ;
1921 add_timer(&ap_config_timer);
1922
Felix Beckfe137232008-07-14 09:59:08 +02001923 /* Setup the high resultion poll timer.
1924 * If we are running under z/VM adjust polling to z/VM polling rate.
1925 */
1926 if (MACHINE_IS_VM)
1927 poll_timeout = 1500000;
Felix Beck93521312009-12-07 12:52:00 +01001928 spin_lock_init(&ap_poll_timer_lock);
Felix Beckfe137232008-07-14 09:59:08 +02001929 hrtimer_init(&ap_poll_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
1930 ap_poll_timer.function = ap_poll_timeout;
1931
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001932 /* Start the low priority AP bus poll thread. */
1933 if (ap_thread_flag) {
1934 rc = ap_poll_thread_start();
1935 if (rc)
1936 goto out_work;
1937 }
1938
1939 return 0;
1940
1941out_work:
1942 del_timer_sync(&ap_config_timer);
Felix Beckfe137232008-07-14 09:59:08 +02001943 hrtimer_cancel(&ap_poll_timer);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001944 destroy_workqueue(ap_work_queue);
1945out_root:
Mark McLoughlin035da162008-12-15 12:58:29 +00001946 root_device_unregister(ap_root_device);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001947out_bus:
1948 while (i--)
1949 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
1950 bus_unregister(&ap_bus_type);
1951out:
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001952 unregister_reset_call(&ap_reset_call);
Felix Beckcb17a632008-12-25 13:38:41 +01001953 if (ap_using_interrupts()) {
1954 s390_unregister_adapter_interrupt(ap_interrupt_indicator, AP_ISC);
1955 isc_unregister(AP_ISC);
1956 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001957 return rc;
1958}
1959
1960static int __ap_match_all(struct device *dev, void *data)
1961{
1962 return 1;
1963}
1964
1965/**
Felix Beck1749a812008-04-17 07:46:28 +02001966 * ap_modules_exit(): The module termination code
1967 *
1968 * Terminates the module.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001969 */
1970void ap_module_exit(void)
1971{
1972 int i;
1973 struct device *dev;
1974
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001975 ap_reset_domain();
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001976 ap_poll_thread_stop();
1977 del_timer_sync(&ap_config_timer);
Felix Beckfe137232008-07-14 09:59:08 +02001978 hrtimer_cancel(&ap_poll_timer);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001979 destroy_workqueue(ap_work_queue);
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001980 tasklet_kill(&ap_tasklet);
Mark McLoughlin035da162008-12-15 12:58:29 +00001981 root_device_unregister(ap_root_device);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001982 while ((dev = bus_find_device(&ap_bus_type, NULL, NULL,
1983 __ap_match_all)))
1984 {
1985 device_unregister(dev);
1986 put_device(dev);
1987 }
1988 for (i = 0; ap_bus_attrs[i]; i++)
1989 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
1990 bus_unregister(&ap_bus_type);
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001991 unregister_reset_call(&ap_reset_call);
Felix Beckcb17a632008-12-25 13:38:41 +01001992 if (ap_using_interrupts()) {
1993 s390_unregister_adapter_interrupt(ap_interrupt_indicator, AP_ISC);
1994 isc_unregister(AP_ISC);
1995 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001996}
1997
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001998module_init(ap_module_init);
1999module_exit(ap_module_exit);