blob: d334b0f7a1ec29dfea4f3f94290dd41ce762d5e6 [file] [log] [blame]
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001/*
2 * linux/drivers/s390/crypto/ap_bus.c
3 *
4 * Copyright (C) 2006 IBM Corporation
5 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
6 * Martin Schwidefsky <schwidefsky@de.ibm.com>
7 * Ralph Wuerthner <rwuerthn@de.ibm.com>
8 *
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
26#include <linux/module.h>
27#include <linux/init.h>
28#include <linux/delay.h>
29#include <linux/err.h>
30#include <linux/interrupt.h>
31#include <linux/workqueue.h>
32#include <linux/notifier.h>
33#include <linux/kthread.h>
34#include <linux/mutex.h>
35#include <asm/s390_rdev.h>
Ralph Wuerthner85eca852006-12-08 15:54:07 +010036#include <asm/reset.h>
Martin Schwidefsky1534c382006-09-20 15:58:25 +020037
38#include "ap_bus.h"
39
40/* Some prototypes. */
Al Viro4927b3f2006-12-06 19:18:20 +000041static void ap_scan_bus(struct work_struct *);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020042static void ap_poll_all(unsigned long);
43static void ap_poll_timeout(unsigned long);
44static int ap_poll_thread_start(void);
45static void ap_poll_thread_stop(void);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +020046static void ap_request_timeout(unsigned long);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020047
48/**
49 * Module description.
50 */
51MODULE_AUTHOR("IBM Corporation");
52MODULE_DESCRIPTION("Adjunct Processor Bus driver, "
53 "Copyright 2006 IBM Corporation");
54MODULE_LICENSE("GPL");
55
56/**
57 * Module parameter
58 */
59int ap_domain_index = -1; /* Adjunct Processor Domain Index */
60module_param_named(domain, ap_domain_index, int, 0000);
61MODULE_PARM_DESC(domain, "domain index for ap devices");
62EXPORT_SYMBOL(ap_domain_index);
63
64static int ap_thread_flag = 1;
65module_param_named(poll_thread, ap_thread_flag, int, 0000);
66MODULE_PARM_DESC(poll_thread, "Turn on/off poll thread, default is 1 (on).");
67
68static struct device *ap_root_device = NULL;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +010069static DEFINE_SPINLOCK(ap_device_lock);
70static LIST_HEAD(ap_device_list);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020071
72/**
73 * Workqueue & timer for bus rescan.
74 */
75static struct workqueue_struct *ap_work_queue;
76static struct timer_list ap_config_timer;
77static int ap_config_time = AP_CONFIG_TIME;
Al Viro4927b3f2006-12-06 19:18:20 +000078static DECLARE_WORK(ap_config_work, ap_scan_bus);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020079
80/**
81 * Tasklet & timer for AP request polling.
82 */
83static struct timer_list ap_poll_timer = TIMER_INITIALIZER(ap_poll_timeout,0,0);
84static DECLARE_TASKLET(ap_tasklet, ap_poll_all, 0);
85static atomic_t ap_poll_requests = ATOMIC_INIT(0);
86static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait);
87static struct task_struct *ap_poll_kthread = NULL;
88static DEFINE_MUTEX(ap_poll_thread_mutex);
89
90/**
91 * Test if ap instructions are available.
92 *
93 * Returns 0 if the ap instructions are installed.
94 */
95static inline int ap_instructions_available(void)
96{
97 register unsigned long reg0 asm ("0") = AP_MKQID(0,0);
98 register unsigned long reg1 asm ("1") = -ENODEV;
99 register unsigned long reg2 asm ("2") = 0UL;
100
101 asm volatile(
102 " .long 0xb2af0000\n" /* PQAP(TAPQ) */
103 "0: la %1,0\n"
104 "1:\n"
105 EX_TABLE(0b, 1b)
106 : "+d" (reg0), "+d" (reg1), "+d" (reg2) : : "cc" );
107 return reg1;
108}
109
110/**
111 * Test adjunct processor queue.
112 * @qid: the ap queue number
113 * @queue_depth: pointer to queue depth value
114 * @device_type: pointer to device type value
115 *
116 * Returns ap queue status structure.
117 */
118static inline struct ap_queue_status
119ap_test_queue(ap_qid_t qid, int *queue_depth, int *device_type)
120{
121 register unsigned long reg0 asm ("0") = qid;
122 register struct ap_queue_status reg1 asm ("1");
123 register unsigned long reg2 asm ("2") = 0UL;
124
125 asm volatile(".long 0xb2af0000" /* PQAP(TAPQ) */
126 : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
127 *device_type = (int) (reg2 >> 24);
128 *queue_depth = (int) (reg2 & 0xff);
129 return reg1;
130}
131
132/**
133 * Reset adjunct processor queue.
134 * @qid: the ap queue number
135 *
136 * Returns ap queue status structure.
137 */
138static inline struct ap_queue_status ap_reset_queue(ap_qid_t qid)
139{
140 register unsigned long reg0 asm ("0") = qid | 0x01000000UL;
141 register struct ap_queue_status reg1 asm ("1");
142 register unsigned long reg2 asm ("2") = 0UL;
143
144 asm volatile(
145 ".long 0xb2af0000" /* PQAP(RAPQ) */
146 : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
147 return reg1;
148}
149
150/**
151 * Send message to adjunct processor queue.
152 * @qid: the ap queue number
153 * @psmid: the program supplied message identifier
154 * @msg: the message text
155 * @length: the message length
156 *
157 * Returns ap queue status structure.
158 *
159 * Condition code 1 on NQAP can't happen because the L bit is 1.
160 *
161 * Condition code 2 on NQAP also means the send is incomplete,
162 * because a segment boundary was reached. The NQAP is repeated.
163 */
164static inline struct ap_queue_status
165__ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length)
166{
167 typedef struct { char _[length]; } msgblock;
168 register unsigned long reg0 asm ("0") = qid | 0x40000000UL;
169 register struct ap_queue_status reg1 asm ("1");
170 register unsigned long reg2 asm ("2") = (unsigned long) msg;
171 register unsigned long reg3 asm ("3") = (unsigned long) length;
172 register unsigned long reg4 asm ("4") = (unsigned int) (psmid >> 32);
173 register unsigned long reg5 asm ("5") = (unsigned int) psmid;
174
175 asm volatile (
176 "0: .long 0xb2ad0042\n" /* DQAP */
177 " brc 2,0b"
178 : "+d" (reg0), "=d" (reg1), "+d" (reg2), "+d" (reg3)
179 : "d" (reg4), "d" (reg5), "m" (*(msgblock *) msg)
180 : "cc" );
181 return reg1;
182}
183
184int ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length)
185{
186 struct ap_queue_status status;
187
188 status = __ap_send(qid, psmid, msg, length);
189 switch (status.response_code) {
190 case AP_RESPONSE_NORMAL:
191 return 0;
192 case AP_RESPONSE_Q_FULL:
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200193 case AP_RESPONSE_RESET_IN_PROGRESS:
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200194 return -EBUSY;
195 default: /* Device is gone. */
196 return -ENODEV;
197 }
198}
199EXPORT_SYMBOL(ap_send);
200
201/*
202 * Receive message from adjunct processor queue.
203 * @qid: the ap queue number
204 * @psmid: pointer to program supplied message identifier
205 * @msg: the message text
206 * @length: the message length
207 *
208 * Returns ap queue status structure.
209 *
210 * Condition code 1 on DQAP means the receive has taken place
211 * but only partially. The response is incomplete, hence the
212 * DQAP is repeated.
213 *
214 * Condition code 2 on DQAP also means the receive is incomplete,
215 * this time because a segment boundary was reached. Again, the
216 * DQAP is repeated.
217 *
218 * Note that gpr2 is used by the DQAP instruction to keep track of
219 * any 'residual' length, in case the instruction gets interrupted.
220 * Hence it gets zeroed before the instruction.
221 */
222static inline struct ap_queue_status
223__ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length)
224{
225 typedef struct { char _[length]; } msgblock;
226 register unsigned long reg0 asm("0") = qid | 0x80000000UL;
227 register struct ap_queue_status reg1 asm ("1");
228 register unsigned long reg2 asm("2") = 0UL;
229 register unsigned long reg4 asm("4") = (unsigned long) msg;
230 register unsigned long reg5 asm("5") = (unsigned long) length;
231 register unsigned long reg6 asm("6") = 0UL;
232 register unsigned long reg7 asm("7") = 0UL;
233
234
235 asm volatile(
236 "0: .long 0xb2ae0064\n"
237 " brc 6,0b\n"
238 : "+d" (reg0), "=d" (reg1), "+d" (reg2),
239 "+d" (reg4), "+d" (reg5), "+d" (reg6), "+d" (reg7),
240 "=m" (*(msgblock *) msg) : : "cc" );
241 *psmid = (((unsigned long long) reg6) << 32) + reg7;
242 return reg1;
243}
244
245int ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length)
246{
247 struct ap_queue_status status;
248
249 status = __ap_recv(qid, psmid, msg, length);
250 switch (status.response_code) {
251 case AP_RESPONSE_NORMAL:
252 return 0;
253 case AP_RESPONSE_NO_PENDING_REPLY:
254 if (status.queue_empty)
255 return -ENOENT;
256 return -EBUSY;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200257 case AP_RESPONSE_RESET_IN_PROGRESS:
258 return -EBUSY;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200259 default:
260 return -ENODEV;
261 }
262}
263EXPORT_SYMBOL(ap_recv);
264
265/**
266 * Check if an AP queue is available. The test is repeated for
267 * AP_MAX_RESET times.
268 * @qid: the ap queue number
269 * @queue_depth: pointer to queue depth value
270 * @device_type: pointer to device type value
271 */
272static int ap_query_queue(ap_qid_t qid, int *queue_depth, int *device_type)
273{
274 struct ap_queue_status status;
275 int t_depth, t_device_type, rc, i;
276
277 rc = -EBUSY;
278 for (i = 0; i < AP_MAX_RESET; i++) {
279 status = ap_test_queue(qid, &t_depth, &t_device_type);
280 switch (status.response_code) {
281 case AP_RESPONSE_NORMAL:
282 *queue_depth = t_depth + 1;
283 *device_type = t_device_type;
284 rc = 0;
285 break;
286 case AP_RESPONSE_Q_NOT_AVAIL:
287 rc = -ENODEV;
288 break;
289 case AP_RESPONSE_RESET_IN_PROGRESS:
290 break;
291 case AP_RESPONSE_DECONFIGURED:
292 rc = -ENODEV;
293 break;
294 case AP_RESPONSE_CHECKSTOPPED:
295 rc = -ENODEV;
296 break;
297 case AP_RESPONSE_BUSY:
298 break;
299 default:
300 BUG();
301 }
302 if (rc != -EBUSY)
303 break;
304 if (i < AP_MAX_RESET - 1)
305 udelay(5);
306 }
307 return rc;
308}
309
310/**
311 * Reset an AP queue and wait for it to become available again.
312 * @qid: the ap queue number
313 */
314static int ap_init_queue(ap_qid_t qid)
315{
316 struct ap_queue_status status;
317 int rc, dummy, i;
318
319 rc = -ENODEV;
320 status = ap_reset_queue(qid);
321 for (i = 0; i < AP_MAX_RESET; i++) {
322 switch (status.response_code) {
323 case AP_RESPONSE_NORMAL:
324 if (status.queue_empty)
325 rc = 0;
326 break;
327 case AP_RESPONSE_Q_NOT_AVAIL:
328 case AP_RESPONSE_DECONFIGURED:
329 case AP_RESPONSE_CHECKSTOPPED:
330 i = AP_MAX_RESET; /* return with -ENODEV */
331 break;
332 case AP_RESPONSE_RESET_IN_PROGRESS:
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200333 rc = -EBUSY;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200334 case AP_RESPONSE_BUSY:
335 default:
336 break;
337 }
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200338 if (rc != -ENODEV && rc != -EBUSY)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200339 break;
340 if (i < AP_MAX_RESET - 1) {
341 udelay(5);
342 status = ap_test_queue(qid, &dummy, &dummy);
343 }
344 }
345 return rc;
346}
347
348/**
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200349 * Arm request timeout if a AP device was idle and a new request is submitted.
350 */
351static void ap_increase_queue_count(struct ap_device *ap_dev)
352{
353 int timeout = ap_dev->drv->request_timeout;
354
355 ap_dev->queue_count++;
356 if (ap_dev->queue_count == 1) {
357 mod_timer(&ap_dev->timeout, jiffies + timeout);
358 ap_dev->reset = AP_RESET_ARMED;
359 }
360}
361
362/**
363 * AP device is still alive, re-schedule request timeout if there are still
364 * pending requests.
365 */
366static void ap_decrease_queue_count(struct ap_device *ap_dev)
367{
368 int timeout = ap_dev->drv->request_timeout;
369
370 ap_dev->queue_count--;
371 if (ap_dev->queue_count > 0)
372 mod_timer(&ap_dev->timeout, jiffies + timeout);
373 else
374 /**
375 * The timeout timer should to be disabled now - since
376 * del_timer_sync() is very expensive, we just tell via the
377 * reset flag to ignore the pending timeout timer.
378 */
379 ap_dev->reset = AP_RESET_IGNORE;
380}
381
382/**
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200383 * AP device related attributes.
384 */
385static ssize_t ap_hwtype_show(struct device *dev,
386 struct device_attribute *attr, char *buf)
387{
388 struct ap_device *ap_dev = to_ap_dev(dev);
389 return snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->device_type);
390}
391static DEVICE_ATTR(hwtype, 0444, ap_hwtype_show, NULL);
392
393static ssize_t ap_depth_show(struct device *dev, struct device_attribute *attr,
394 char *buf)
395{
396 struct ap_device *ap_dev = to_ap_dev(dev);
397 return snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->queue_depth);
398}
399static DEVICE_ATTR(depth, 0444, ap_depth_show, NULL);
400
401static ssize_t ap_request_count_show(struct device *dev,
402 struct device_attribute *attr,
403 char *buf)
404{
405 struct ap_device *ap_dev = to_ap_dev(dev);
406 int rc;
407
408 spin_lock_bh(&ap_dev->lock);
409 rc = snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->total_request_count);
410 spin_unlock_bh(&ap_dev->lock);
411 return rc;
412}
413
414static DEVICE_ATTR(request_count, 0444, ap_request_count_show, NULL);
415
416static ssize_t ap_modalias_show(struct device *dev,
417 struct device_attribute *attr, char *buf)
418{
419 return sprintf(buf, "ap:t%02X", to_ap_dev(dev)->device_type);
420}
421
422static DEVICE_ATTR(modalias, 0444, ap_modalias_show, NULL);
423
424static struct attribute *ap_dev_attrs[] = {
425 &dev_attr_hwtype.attr,
426 &dev_attr_depth.attr,
427 &dev_attr_request_count.attr,
428 &dev_attr_modalias.attr,
429 NULL
430};
431static struct attribute_group ap_dev_attr_group = {
432 .attrs = ap_dev_attrs
433};
434
435/**
436 * AP bus driver registration/unregistration.
437 */
438static int ap_bus_match(struct device *dev, struct device_driver *drv)
439{
440 struct ap_device *ap_dev = to_ap_dev(dev);
441 struct ap_driver *ap_drv = to_ap_drv(drv);
442 struct ap_device_id *id;
443
444 /**
445 * Compare device type of the device with the list of
446 * supported types of the device_driver.
447 */
448 for (id = ap_drv->ids; id->match_flags; id++) {
449 if ((id->match_flags & AP_DEVICE_ID_MATCH_DEVICE_TYPE) &&
450 (id->dev_type != ap_dev->device_type))
451 continue;
452 return 1;
453 }
454 return 0;
455}
456
457/**
458 * uevent function for AP devices. It sets up a single environment
459 * variable DEV_TYPE which contains the hardware device type.
460 */
461static int ap_uevent (struct device *dev, char **envp, int num_envp,
462 char *buffer, int buffer_size)
463{
464 struct ap_device *ap_dev = to_ap_dev(dev);
Eric Rannaudbf624562007-03-30 22:23:12 -0700465 int retval = 0, length = 0, i = 0;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200466
467 if (!ap_dev)
468 return -ENODEV;
469
470 /* Set up DEV_TYPE environment variable. */
Eric Rannaudbf624562007-03-30 22:23:12 -0700471 retval = add_uevent_var(envp, num_envp, &i,
472 buffer, buffer_size, &length,
473 "DEV_TYPE=%04X", ap_dev->device_type);
474 if (retval)
475 return retval;
476
Cornelia Huck66a4263b2006-12-04 15:40:10 +0100477 /* Add MODALIAS= */
Eric Rannaudbf624562007-03-30 22:23:12 -0700478 retval = add_uevent_var(envp, num_envp, &i,
479 buffer, buffer_size, &length,
480 "MODALIAS=ap:t%02X", ap_dev->device_type);
481
482 envp[i] = NULL;
483 return retval;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200484}
485
486static struct bus_type ap_bus_type = {
487 .name = "ap",
488 .match = &ap_bus_match,
489 .uevent = &ap_uevent,
490};
491
492static int ap_device_probe(struct device *dev)
493{
494 struct ap_device *ap_dev = to_ap_dev(dev);
495 struct ap_driver *ap_drv = to_ap_drv(dev->driver);
496 int rc;
497
498 ap_dev->drv = ap_drv;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +0100499 spin_lock_bh(&ap_device_lock);
500 list_add(&ap_dev->list, &ap_device_list);
501 spin_unlock_bh(&ap_device_lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200502 rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200503 return rc;
504}
505
506/**
507 * Flush all requests from the request/pending queue of an AP device.
508 * @ap_dev: pointer to the AP device.
509 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +0100510static void __ap_flush_queue(struct ap_device *ap_dev)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200511{
512 struct ap_message *ap_msg, *next;
513
514 list_for_each_entry_safe(ap_msg, next, &ap_dev->pendingq, list) {
515 list_del_init(&ap_msg->list);
516 ap_dev->pendingq_count--;
517 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
518 }
519 list_for_each_entry_safe(ap_msg, next, &ap_dev->requestq, list) {
520 list_del_init(&ap_msg->list);
521 ap_dev->requestq_count--;
522 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
523 }
524}
525
526void ap_flush_queue(struct ap_device *ap_dev)
527{
528 spin_lock_bh(&ap_dev->lock);
529 __ap_flush_queue(ap_dev);
530 spin_unlock_bh(&ap_dev->lock);
531}
532EXPORT_SYMBOL(ap_flush_queue);
533
534static int ap_device_remove(struct device *dev)
535{
536 struct ap_device *ap_dev = to_ap_dev(dev);
537 struct ap_driver *ap_drv = ap_dev->drv;
538
Ralph Wuerthner4e562962006-10-04 20:02:05 +0200539 ap_flush_queue(ap_dev);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200540 del_timer_sync(&ap_dev->timeout);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200541 if (ap_drv->remove)
542 ap_drv->remove(ap_dev);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +0100543 spin_lock_bh(&ap_device_lock);
544 list_del_init(&ap_dev->list);
545 spin_unlock_bh(&ap_device_lock);
Ralph Wuerthnere675c0d2007-03-26 20:42:43 +0200546 spin_lock_bh(&ap_dev->lock);
547 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
548 spin_unlock_bh(&ap_dev->lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200549 return 0;
550}
551
552int ap_driver_register(struct ap_driver *ap_drv, struct module *owner,
553 char *name)
554{
555 struct device_driver *drv = &ap_drv->driver;
556
557 drv->bus = &ap_bus_type;
558 drv->probe = ap_device_probe;
559 drv->remove = ap_device_remove;
560 drv->owner = owner;
561 drv->name = name;
562 return driver_register(drv);
563}
564EXPORT_SYMBOL(ap_driver_register);
565
566void ap_driver_unregister(struct ap_driver *ap_drv)
567{
568 driver_unregister(&ap_drv->driver);
569}
570EXPORT_SYMBOL(ap_driver_unregister);
571
572/**
573 * AP bus attributes.
574 */
575static ssize_t ap_domain_show(struct bus_type *bus, char *buf)
576{
577 return snprintf(buf, PAGE_SIZE, "%d\n", ap_domain_index);
578}
579
580static BUS_ATTR(ap_domain, 0444, ap_domain_show, NULL);
581
582static ssize_t ap_config_time_show(struct bus_type *bus, char *buf)
583{
584 return snprintf(buf, PAGE_SIZE, "%d\n", ap_config_time);
585}
586
587static ssize_t ap_config_time_store(struct bus_type *bus,
588 const char *buf, size_t count)
589{
590 int time;
591
592 if (sscanf(buf, "%d\n", &time) != 1 || time < 5 || time > 120)
593 return -EINVAL;
594 ap_config_time = time;
595 if (!timer_pending(&ap_config_timer) ||
596 !mod_timer(&ap_config_timer, jiffies + ap_config_time * HZ)) {
597 ap_config_timer.expires = jiffies + ap_config_time * HZ;
598 add_timer(&ap_config_timer);
599 }
600 return count;
601}
602
603static BUS_ATTR(config_time, 0644, ap_config_time_show, ap_config_time_store);
604
605static ssize_t ap_poll_thread_show(struct bus_type *bus, char *buf)
606{
607 return snprintf(buf, PAGE_SIZE, "%d\n", ap_poll_kthread ? 1 : 0);
608}
609
610static ssize_t ap_poll_thread_store(struct bus_type *bus,
611 const char *buf, size_t count)
612{
613 int flag, rc;
614
615 if (sscanf(buf, "%d\n", &flag) != 1)
616 return -EINVAL;
617 if (flag) {
618 rc = ap_poll_thread_start();
619 if (rc)
620 return rc;
621 }
622 else
623 ap_poll_thread_stop();
624 return count;
625}
626
627static BUS_ATTR(poll_thread, 0644, ap_poll_thread_show, ap_poll_thread_store);
628
629static struct bus_attribute *const ap_bus_attrs[] = {
630 &bus_attr_ap_domain,
631 &bus_attr_config_time,
632 &bus_attr_poll_thread,
633 NULL
634};
635
636/**
637 * Pick one of the 16 ap domains.
638 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +0100639static int ap_select_domain(void)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200640{
641 int queue_depth, device_type, count, max_count, best_domain;
642 int rc, i, j;
643
644 /**
645 * We want to use a single domain. Either the one specified with
646 * the "domain=" parameter or the domain with the maximum number
647 * of devices.
648 */
649 if (ap_domain_index >= 0 && ap_domain_index < AP_DOMAINS)
650 /* Domain has already been selected. */
651 return 0;
652 best_domain = -1;
653 max_count = 0;
654 for (i = 0; i < AP_DOMAINS; i++) {
655 count = 0;
656 for (j = 0; j < AP_DEVICES; j++) {
657 ap_qid_t qid = AP_MKQID(j, i);
658 rc = ap_query_queue(qid, &queue_depth, &device_type);
659 if (rc)
660 continue;
661 count++;
662 }
663 if (count > max_count) {
664 max_count = count;
665 best_domain = i;
666 }
667 }
668 if (best_domain >= 0){
669 ap_domain_index = best_domain;
670 return 0;
671 }
672 return -ENODEV;
673}
674
675/**
676 * Find the device type if query queue returned a device type of 0.
677 * @ap_dev: pointer to the AP device.
678 */
679static int ap_probe_device_type(struct ap_device *ap_dev)
680{
681 static unsigned char msg[] = {
682 0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
683 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
684 0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,
685 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
686 0x01,0x00,0x43,0x43,0x41,0x2d,0x41,0x50,
687 0x50,0x4c,0x20,0x20,0x20,0x01,0x01,0x01,
688 0x00,0x00,0x00,0x00,0x50,0x4b,0x00,0x00,
689 0x00,0x00,0x01,0x1c,0x00,0x00,0x00,0x00,
690 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
691 0x00,0x00,0x05,0xb8,0x00,0x00,0x00,0x00,
692 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
693 0x70,0x00,0x41,0x00,0x00,0x00,0x00,0x00,
694 0x00,0x00,0x54,0x32,0x01,0x00,0xa0,0x00,
695 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
696 0x00,0x00,0x00,0x00,0xb8,0x05,0x00,0x00,
697 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
698 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
699 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
700 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
701 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
702 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
703 0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,
704 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
705 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,
706 0x49,0x43,0x53,0x46,0x20,0x20,0x20,0x20,
707 0x50,0x4b,0x0a,0x00,0x50,0x4b,0x43,0x53,
708 0x2d,0x31,0x2e,0x32,0x37,0x00,0x11,0x22,
709 0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,
710 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,
711 0x99,0x00,0x11,0x22,0x33,0x44,0x55,0x66,
712 0x77,0x88,0x99,0x00,0x11,0x22,0x33,0x44,
713 0x55,0x66,0x77,0x88,0x99,0x00,0x11,0x22,
714 0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,
715 0x11,0x22,0x33,0x5d,0x00,0x5b,0x00,0x77,
716 0x88,0x1e,0x00,0x00,0x57,0x00,0x00,0x00,
717 0x00,0x04,0x00,0x00,0x4f,0x00,0x00,0x00,
718 0x03,0x02,0x00,0x00,0x40,0x01,0x00,0x01,
719 0xce,0x02,0x68,0x2d,0x5f,0xa9,0xde,0x0c,
720 0xf6,0xd2,0x7b,0x58,0x4b,0xf9,0x28,0x68,
721 0x3d,0xb4,0xf4,0xef,0x78,0xd5,0xbe,0x66,
722 0x63,0x42,0xef,0xf8,0xfd,0xa4,0xf8,0xb0,
723 0x8e,0x29,0xc2,0xc9,0x2e,0xd8,0x45,0xb8,
724 0x53,0x8c,0x6f,0x4e,0x72,0x8f,0x6c,0x04,
725 0x9c,0x88,0xfc,0x1e,0xc5,0x83,0x55,0x57,
726 0xf7,0xdd,0xfd,0x4f,0x11,0x36,0x95,0x5d,
727 };
728 struct ap_queue_status status;
729 unsigned long long psmid;
730 char *reply;
731 int rc, i;
732
733 reply = (void *) get_zeroed_page(GFP_KERNEL);
734 if (!reply) {
735 rc = -ENOMEM;
736 goto out;
737 }
738
739 status = __ap_send(ap_dev->qid, 0x0102030405060708ULL,
740 msg, sizeof(msg));
741 if (status.response_code != AP_RESPONSE_NORMAL) {
742 rc = -ENODEV;
743 goto out_free;
744 }
745
746 /* Wait for the test message to complete. */
747 for (i = 0; i < 6; i++) {
748 mdelay(300);
749 status = __ap_recv(ap_dev->qid, &psmid, reply, 4096);
750 if (status.response_code == AP_RESPONSE_NORMAL &&
751 psmid == 0x0102030405060708ULL)
752 break;
753 }
754 if (i < 6) {
755 /* Got an answer. */
756 if (reply[0] == 0x00 && reply[1] == 0x86)
757 ap_dev->device_type = AP_DEVICE_TYPE_PCICC;
758 else
759 ap_dev->device_type = AP_DEVICE_TYPE_PCICA;
760 rc = 0;
761 } else
762 rc = -ENODEV;
763
764out_free:
765 free_page((unsigned long) reply);
766out:
767 return rc;
768}
769
770/**
771 * Scan the ap bus for new devices.
772 */
773static int __ap_scan_bus(struct device *dev, void *data)
774{
775 return to_ap_dev(dev)->qid == (ap_qid_t)(unsigned long) data;
776}
777
778static void ap_device_release(struct device *dev)
779{
780 struct ap_device *ap_dev = to_ap_dev(dev);
781
782 kfree(ap_dev);
783}
784
Al Viro4927b3f2006-12-06 19:18:20 +0000785static void ap_scan_bus(struct work_struct *unused)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200786{
787 struct ap_device *ap_dev;
788 struct device *dev;
789 ap_qid_t qid;
790 int queue_depth, device_type;
791 int rc, i;
792
793 if (ap_select_domain() != 0)
794 return;
795 for (i = 0; i < AP_DEVICES; i++) {
796 qid = AP_MKQID(i, ap_domain_index);
797 dev = bus_find_device(&ap_bus_type, NULL,
798 (void *)(unsigned long)qid,
799 __ap_scan_bus);
Ralph Wuerthnerf3b017d2006-10-27 12:39:26 +0200800 rc = ap_query_queue(qid, &queue_depth, &device_type);
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +0200801 if (dev) {
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200802 if (rc == -EBUSY) {
803 set_current_state(TASK_UNINTERRUPTIBLE);
804 schedule_timeout(AP_RESET_TIMEOUT);
805 rc = ap_query_queue(qid, &queue_depth,
806 &device_type);
807 }
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +0200808 ap_dev = to_ap_dev(dev);
809 spin_lock_bh(&ap_dev->lock);
810 if (rc || ap_dev->unregistered) {
811 spin_unlock_bh(&ap_dev->lock);
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +0200812 device_unregister(dev);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200813 put_device(dev);
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +0200814 continue;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200815 }
816 spin_unlock_bh(&ap_dev->lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200817 put_device(dev);
818 continue;
819 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200820 if (rc)
821 continue;
822 rc = ap_init_queue(qid);
823 if (rc)
824 continue;
825 ap_dev = kzalloc(sizeof(*ap_dev), GFP_KERNEL);
826 if (!ap_dev)
827 break;
828 ap_dev->qid = qid;
829 ap_dev->queue_depth = queue_depth;
Ralph Wuerthner4e562962006-10-04 20:02:05 +0200830 ap_dev->unregistered = 1;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200831 spin_lock_init(&ap_dev->lock);
832 INIT_LIST_HEAD(&ap_dev->pendingq);
833 INIT_LIST_HEAD(&ap_dev->requestq);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +0100834 INIT_LIST_HEAD(&ap_dev->list);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200835 setup_timer(&ap_dev->timeout, ap_request_timeout,
836 (unsigned long) ap_dev);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200837 if (device_type == 0)
838 ap_probe_device_type(ap_dev);
839 else
840 ap_dev->device_type = device_type;
841
842 ap_dev->device.bus = &ap_bus_type;
843 ap_dev->device.parent = ap_root_device;
844 snprintf(ap_dev->device.bus_id, BUS_ID_SIZE, "card%02x",
845 AP_QID_DEVICE(ap_dev->qid));
846 ap_dev->device.release = ap_device_release;
847 rc = device_register(&ap_dev->device);
848 if (rc) {
849 kfree(ap_dev);
850 continue;
851 }
852 /* Add device attributes. */
853 rc = sysfs_create_group(&ap_dev->device.kobj,
854 &ap_dev_attr_group);
Ralph Wuerthner4e562962006-10-04 20:02:05 +0200855 if (!rc) {
856 spin_lock_bh(&ap_dev->lock);
857 ap_dev->unregistered = 0;
858 spin_unlock_bh(&ap_dev->lock);
859 }
860 else
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200861 device_unregister(&ap_dev->device);
862 }
863}
864
865static void
866ap_config_timeout(unsigned long ptr)
867{
868 queue_work(ap_work_queue, &ap_config_work);
869 ap_config_timer.expires = jiffies + ap_config_time * HZ;
870 add_timer(&ap_config_timer);
871}
872
873/**
874 * Set up the timer to run the poll tasklet
875 */
876static inline void ap_schedule_poll_timer(void)
877{
878 if (timer_pending(&ap_poll_timer))
879 return;
880 mod_timer(&ap_poll_timer, jiffies + AP_POLL_TIME);
881}
882
883/**
884 * Receive pending reply messages from an AP device.
885 * @ap_dev: pointer to the AP device
886 * @flags: pointer to control flags, bit 2^0 is set if another poll is
887 * required, bit 2^1 is set if the poll timer needs to get armed
888 * Returns 0 if the device is still present, -ENODEV if not.
889 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +0100890static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200891{
892 struct ap_queue_status status;
893 struct ap_message *ap_msg;
894
895 if (ap_dev->queue_count <= 0)
896 return 0;
897 status = __ap_recv(ap_dev->qid, &ap_dev->reply->psmid,
898 ap_dev->reply->message, ap_dev->reply->length);
899 switch (status.response_code) {
900 case AP_RESPONSE_NORMAL:
901 atomic_dec(&ap_poll_requests);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200902 ap_decrease_queue_count(ap_dev);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200903 list_for_each_entry(ap_msg, &ap_dev->pendingq, list) {
904 if (ap_msg->psmid != ap_dev->reply->psmid)
905 continue;
906 list_del_init(&ap_msg->list);
907 ap_dev->pendingq_count--;
908 ap_dev->drv->receive(ap_dev, ap_msg, ap_dev->reply);
909 break;
910 }
911 if (ap_dev->queue_count > 0)
912 *flags |= 1;
913 break;
914 case AP_RESPONSE_NO_PENDING_REPLY:
915 if (status.queue_empty) {
916 /* The card shouldn't forget requests but who knows. */
Ralph Wuerthnere675c0d2007-03-26 20:42:43 +0200917 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200918 ap_dev->queue_count = 0;
919 list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
920 ap_dev->requestq_count += ap_dev->pendingq_count;
921 ap_dev->pendingq_count = 0;
922 } else
923 *flags |= 2;
924 break;
925 default:
926 return -ENODEV;
927 }
928 return 0;
929}
930
931/**
932 * Send messages from the request queue to an AP device.
933 * @ap_dev: pointer to the AP device
934 * @flags: pointer to control flags, bit 2^0 is set if another poll is
935 * required, bit 2^1 is set if the poll timer needs to get armed
936 * Returns 0 if the device is still present, -ENODEV if not.
937 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +0100938static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200939{
940 struct ap_queue_status status;
941 struct ap_message *ap_msg;
942
943 if (ap_dev->requestq_count <= 0 ||
944 ap_dev->queue_count >= ap_dev->queue_depth)
945 return 0;
946 /* Start the next request on the queue. */
947 ap_msg = list_entry(ap_dev->requestq.next, struct ap_message, list);
948 status = __ap_send(ap_dev->qid, ap_msg->psmid,
949 ap_msg->message, ap_msg->length);
950 switch (status.response_code) {
951 case AP_RESPONSE_NORMAL:
952 atomic_inc(&ap_poll_requests);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200953 ap_increase_queue_count(ap_dev);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200954 list_move_tail(&ap_msg->list, &ap_dev->pendingq);
955 ap_dev->requestq_count--;
956 ap_dev->pendingq_count++;
957 if (ap_dev->queue_count < ap_dev->queue_depth &&
958 ap_dev->requestq_count > 0)
959 *flags |= 1;
960 *flags |= 2;
961 break;
962 case AP_RESPONSE_Q_FULL:
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200963 case AP_RESPONSE_RESET_IN_PROGRESS:
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200964 *flags |= 2;
965 break;
966 case AP_RESPONSE_MESSAGE_TOO_BIG:
967 return -EINVAL;
968 default:
969 return -ENODEV;
970 }
971 return 0;
972}
973
974/**
975 * Poll AP device for pending replies and send new messages. If either
976 * ap_poll_read or ap_poll_write returns -ENODEV unregister the device.
977 * @ap_dev: pointer to the bus device
978 * @flags: pointer to control flags, bit 2^0 is set if another poll is
979 * required, bit 2^1 is set if the poll timer needs to get armed
980 * Returns 0.
981 */
982static inline int ap_poll_queue(struct ap_device *ap_dev, unsigned long *flags)
983{
984 int rc;
985
986 rc = ap_poll_read(ap_dev, flags);
987 if (rc)
988 return rc;
989 return ap_poll_write(ap_dev, flags);
990}
991
992/**
993 * Queue a message to a device.
994 * @ap_dev: pointer to the AP device
995 * @ap_msg: the message to be queued
996 */
997static int __ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
998{
999 struct ap_queue_status status;
1000
1001 if (list_empty(&ap_dev->requestq) &&
1002 ap_dev->queue_count < ap_dev->queue_depth) {
1003 status = __ap_send(ap_dev->qid, ap_msg->psmid,
1004 ap_msg->message, ap_msg->length);
1005 switch (status.response_code) {
1006 case AP_RESPONSE_NORMAL:
1007 list_add_tail(&ap_msg->list, &ap_dev->pendingq);
1008 atomic_inc(&ap_poll_requests);
1009 ap_dev->pendingq_count++;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001010 ap_increase_queue_count(ap_dev);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001011 ap_dev->total_request_count++;
1012 break;
1013 case AP_RESPONSE_Q_FULL:
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001014 case AP_RESPONSE_RESET_IN_PROGRESS:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001015 list_add_tail(&ap_msg->list, &ap_dev->requestq);
1016 ap_dev->requestq_count++;
1017 ap_dev->total_request_count++;
1018 return -EBUSY;
1019 case AP_RESPONSE_MESSAGE_TOO_BIG:
1020 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL));
1021 return -EINVAL;
1022 default: /* Device is gone. */
1023 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
1024 return -ENODEV;
1025 }
1026 } else {
1027 list_add_tail(&ap_msg->list, &ap_dev->requestq);
1028 ap_dev->requestq_count++;
1029 ap_dev->total_request_count++;
1030 return -EBUSY;
1031 }
1032 ap_schedule_poll_timer();
1033 return 0;
1034}
1035
1036void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
1037{
1038 unsigned long flags;
1039 int rc;
1040
1041 spin_lock_bh(&ap_dev->lock);
1042 if (!ap_dev->unregistered) {
1043 /* Make room on the queue by polling for finished requests. */
1044 rc = ap_poll_queue(ap_dev, &flags);
1045 if (!rc)
1046 rc = __ap_queue_message(ap_dev, ap_msg);
1047 if (!rc)
1048 wake_up(&ap_poll_wait);
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001049 if (rc == -ENODEV)
1050 ap_dev->unregistered = 1;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001051 } else {
1052 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001053 rc = -ENODEV;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001054 }
1055 spin_unlock_bh(&ap_dev->lock);
1056 if (rc == -ENODEV)
1057 device_unregister(&ap_dev->device);
1058}
1059EXPORT_SYMBOL(ap_queue_message);
1060
1061/**
1062 * Cancel a crypto request. This is done by removing the request
1063 * from the devive pendingq or requestq queue. Note that the
1064 * request stays on the AP queue. When it finishes the message
1065 * reply will be discarded because the psmid can't be found.
1066 * @ap_dev: AP device that has the message queued
1067 * @ap_msg: the message that is to be removed
1068 */
1069void ap_cancel_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
1070{
1071 struct ap_message *tmp;
1072
1073 spin_lock_bh(&ap_dev->lock);
1074 if (!list_empty(&ap_msg->list)) {
1075 list_for_each_entry(tmp, &ap_dev->pendingq, list)
1076 if (tmp->psmid == ap_msg->psmid) {
1077 ap_dev->pendingq_count--;
1078 goto found;
1079 }
1080 ap_dev->requestq_count--;
1081 found:
1082 list_del_init(&ap_msg->list);
1083 }
1084 spin_unlock_bh(&ap_dev->lock);
1085}
1086EXPORT_SYMBOL(ap_cancel_message);
1087
1088/**
1089 * AP receive polling for finished AP requests
1090 */
1091static void ap_poll_timeout(unsigned long unused)
1092{
1093 tasklet_schedule(&ap_tasklet);
1094}
1095
1096/**
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001097 * Reset a not responding AP device and move all requests from the
1098 * pending queue to the request queue.
1099 */
1100static void ap_reset(struct ap_device *ap_dev)
1101{
1102 int rc;
1103
1104 ap_dev->reset = AP_RESET_IGNORE;
1105 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
1106 ap_dev->queue_count = 0;
1107 list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
1108 ap_dev->requestq_count += ap_dev->pendingq_count;
1109 ap_dev->pendingq_count = 0;
1110 rc = ap_init_queue(ap_dev->qid);
1111 if (rc == -ENODEV)
1112 ap_dev->unregistered = 1;
1113}
1114
1115/**
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001116 * Poll all AP devices on the bus in a round robin fashion. Continue
1117 * polling until bit 2^0 of the control flags is not set. If bit 2^1
1118 * of the control flags has been set arm the poll timer.
1119 */
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001120static int __ap_poll_all(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001121{
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001122 spin_lock(&ap_dev->lock);
1123 if (!ap_dev->unregistered) {
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001124 if (ap_poll_queue(ap_dev, flags))
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001125 ap_dev->unregistered = 1;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001126 if (ap_dev->reset == AP_RESET_DO)
1127 ap_reset(ap_dev);
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001128 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001129 spin_unlock(&ap_dev->lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001130 return 0;
1131}
1132
1133static void ap_poll_all(unsigned long dummy)
1134{
1135 unsigned long flags;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001136 struct ap_device *ap_dev;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001137
1138 do {
1139 flags = 0;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001140 spin_lock(&ap_device_lock);
1141 list_for_each_entry(ap_dev, &ap_device_list, list) {
1142 __ap_poll_all(ap_dev, &flags);
1143 }
1144 spin_unlock(&ap_device_lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001145 } while (flags & 1);
1146 if (flags & 2)
1147 ap_schedule_poll_timer();
1148}
1149
1150/**
1151 * AP bus poll thread. The purpose of this thread is to poll for
1152 * finished requests in a loop if there is a "free" cpu - that is
1153 * a cpu that doesn't have anything better to do. The polling stops
1154 * as soon as there is another task or if all messages have been
1155 * delivered.
1156 */
1157static int ap_poll_thread(void *data)
1158{
1159 DECLARE_WAITQUEUE(wait, current);
1160 unsigned long flags;
1161 int requests;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001162 struct ap_device *ap_dev;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001163
Christian Borntraegerd83682b2006-10-06 16:38:22 +02001164 set_user_nice(current, 19);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001165 while (1) {
1166 if (need_resched()) {
1167 schedule();
1168 continue;
1169 }
1170 add_wait_queue(&ap_poll_wait, &wait);
1171 set_current_state(TASK_INTERRUPTIBLE);
1172 if (kthread_should_stop())
1173 break;
1174 requests = atomic_read(&ap_poll_requests);
1175 if (requests <= 0)
1176 schedule();
1177 set_current_state(TASK_RUNNING);
1178 remove_wait_queue(&ap_poll_wait, &wait);
1179
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001180 flags = 0;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001181 spin_lock_bh(&ap_device_lock);
1182 list_for_each_entry(ap_dev, &ap_device_list, list) {
1183 __ap_poll_all(ap_dev, &flags);
1184 }
1185 spin_unlock_bh(&ap_device_lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001186 }
1187 set_current_state(TASK_RUNNING);
1188 remove_wait_queue(&ap_poll_wait, &wait);
1189 return 0;
1190}
1191
1192static int ap_poll_thread_start(void)
1193{
1194 int rc;
1195
1196 mutex_lock(&ap_poll_thread_mutex);
1197 if (!ap_poll_kthread) {
1198 ap_poll_kthread = kthread_run(ap_poll_thread, NULL, "appoll");
1199 rc = IS_ERR(ap_poll_kthread) ? PTR_ERR(ap_poll_kthread) : 0;
1200 if (rc)
1201 ap_poll_kthread = NULL;
1202 }
1203 else
1204 rc = 0;
1205 mutex_unlock(&ap_poll_thread_mutex);
1206 return rc;
1207}
1208
1209static void ap_poll_thread_stop(void)
1210{
1211 mutex_lock(&ap_poll_thread_mutex);
1212 if (ap_poll_kthread) {
1213 kthread_stop(ap_poll_kthread);
1214 ap_poll_kthread = NULL;
1215 }
1216 mutex_unlock(&ap_poll_thread_mutex);
1217}
1218
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001219/**
1220 * Handling of request timeouts
1221 */
1222static void ap_request_timeout(unsigned long data)
1223{
1224 struct ap_device *ap_dev = (struct ap_device *) data;
1225
1226 if (ap_dev->reset == AP_RESET_ARMED)
1227 ap_dev->reset = AP_RESET_DO;
1228}
1229
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001230static void ap_reset_domain(void)
1231{
1232 int i;
1233
Ralph Wuerthner39aa7cf2007-10-12 16:11:29 +02001234 if (ap_domain_index != -1)
1235 for (i = 0; i < AP_DEVICES; i++)
1236 ap_reset_queue(AP_MKQID(i, ap_domain_index));
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001237}
1238
1239static void ap_reset_all(void)
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001240{
1241 int i, j;
1242
1243 for (i = 0; i < AP_DOMAINS; i++)
1244 for (j = 0; j < AP_DEVICES; j++)
1245 ap_reset_queue(AP_MKQID(j, i));
1246}
1247
1248static struct reset_call ap_reset_call = {
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001249 .fn = ap_reset_all,
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001250};
1251
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001252/**
1253 * The module initialization code.
1254 */
1255int __init ap_module_init(void)
1256{
1257 int rc, i;
1258
1259 if (ap_domain_index < -1 || ap_domain_index >= AP_DOMAINS) {
1260 printk(KERN_WARNING "Invalid param: domain = %d. "
1261 " Not loading.\n", ap_domain_index);
1262 return -EINVAL;
1263 }
1264 if (ap_instructions_available() != 0) {
1265 printk(KERN_WARNING "AP instructions not installed.\n");
1266 return -ENODEV;
1267 }
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001268 register_reset_call(&ap_reset_call);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001269
1270 /* Create /sys/bus/ap. */
1271 rc = bus_register(&ap_bus_type);
1272 if (rc)
1273 goto out;
1274 for (i = 0; ap_bus_attrs[i]; i++) {
1275 rc = bus_create_file(&ap_bus_type, ap_bus_attrs[i]);
1276 if (rc)
1277 goto out_bus;
1278 }
1279
1280 /* Create /sys/devices/ap. */
1281 ap_root_device = s390_root_dev_register("ap");
1282 rc = IS_ERR(ap_root_device) ? PTR_ERR(ap_root_device) : 0;
1283 if (rc)
1284 goto out_bus;
1285
1286 ap_work_queue = create_singlethread_workqueue("kapwork");
1287 if (!ap_work_queue) {
1288 rc = -ENOMEM;
1289 goto out_root;
1290 }
1291
1292 if (ap_select_domain() == 0)
1293 ap_scan_bus(NULL);
1294
1295 /* Setup the ap bus rescan timer. */
1296 init_timer(&ap_config_timer);
1297 ap_config_timer.function = ap_config_timeout;
1298 ap_config_timer.data = 0;
1299 ap_config_timer.expires = jiffies + ap_config_time * HZ;
1300 add_timer(&ap_config_timer);
1301
1302 /* Start the low priority AP bus poll thread. */
1303 if (ap_thread_flag) {
1304 rc = ap_poll_thread_start();
1305 if (rc)
1306 goto out_work;
1307 }
1308
1309 return 0;
1310
1311out_work:
1312 del_timer_sync(&ap_config_timer);
1313 del_timer_sync(&ap_poll_timer);
1314 destroy_workqueue(ap_work_queue);
1315out_root:
1316 s390_root_dev_unregister(ap_root_device);
1317out_bus:
1318 while (i--)
1319 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
1320 bus_unregister(&ap_bus_type);
1321out:
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001322 unregister_reset_call(&ap_reset_call);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001323 return rc;
1324}
1325
1326static int __ap_match_all(struct device *dev, void *data)
1327{
1328 return 1;
1329}
1330
1331/**
1332 * The module termination code
1333 */
1334void ap_module_exit(void)
1335{
1336 int i;
1337 struct device *dev;
1338
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001339 ap_reset_domain();
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001340 ap_poll_thread_stop();
1341 del_timer_sync(&ap_config_timer);
1342 del_timer_sync(&ap_poll_timer);
1343 destroy_workqueue(ap_work_queue);
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001344 tasklet_kill(&ap_tasklet);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001345 s390_root_dev_unregister(ap_root_device);
1346 while ((dev = bus_find_device(&ap_bus_type, NULL, NULL,
1347 __ap_match_all)))
1348 {
1349 device_unregister(dev);
1350 put_device(dev);
1351 }
1352 for (i = 0; ap_bus_attrs[i]; i++)
1353 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
1354 bus_unregister(&ap_bus_type);
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001355 unregister_reset_call(&ap_reset_call);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001356}
1357
1358#ifndef CONFIG_ZCRYPT_MONOLITHIC
1359module_init(ap_module_init);
1360module_exit(ap_module_exit);
1361#endif