blob: bf37cdf43faec1b8f98010849c760873eca1afb4 [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);
46
47/**
48 * Module description.
49 */
50MODULE_AUTHOR("IBM Corporation");
51MODULE_DESCRIPTION("Adjunct Processor Bus driver, "
52 "Copyright 2006 IBM Corporation");
53MODULE_LICENSE("GPL");
54
55/**
56 * Module parameter
57 */
58int ap_domain_index = -1; /* Adjunct Processor Domain Index */
59module_param_named(domain, ap_domain_index, int, 0000);
60MODULE_PARM_DESC(domain, "domain index for ap devices");
61EXPORT_SYMBOL(ap_domain_index);
62
63static int ap_thread_flag = 1;
64module_param_named(poll_thread, ap_thread_flag, int, 0000);
65MODULE_PARM_DESC(poll_thread, "Turn on/off poll thread, default is 1 (on).");
66
67static struct device *ap_root_device = NULL;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +010068static DEFINE_SPINLOCK(ap_device_lock);
69static LIST_HEAD(ap_device_list);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020070
71/**
72 * Workqueue & timer for bus rescan.
73 */
74static struct workqueue_struct *ap_work_queue;
75static struct timer_list ap_config_timer;
76static int ap_config_time = AP_CONFIG_TIME;
Al Viro4927b3f2006-12-06 19:18:20 +000077static DECLARE_WORK(ap_config_work, ap_scan_bus);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020078
79/**
80 * Tasklet & timer for AP request polling.
81 */
82static struct timer_list ap_poll_timer = TIMER_INITIALIZER(ap_poll_timeout,0,0);
83static DECLARE_TASKLET(ap_tasklet, ap_poll_all, 0);
84static atomic_t ap_poll_requests = ATOMIC_INIT(0);
85static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait);
86static struct task_struct *ap_poll_kthread = NULL;
87static DEFINE_MUTEX(ap_poll_thread_mutex);
88
89/**
90 * Test if ap instructions are available.
91 *
92 * Returns 0 if the ap instructions are installed.
93 */
94static inline int ap_instructions_available(void)
95{
96 register unsigned long reg0 asm ("0") = AP_MKQID(0,0);
97 register unsigned long reg1 asm ("1") = -ENODEV;
98 register unsigned long reg2 asm ("2") = 0UL;
99
100 asm volatile(
101 " .long 0xb2af0000\n" /* PQAP(TAPQ) */
102 "0: la %1,0\n"
103 "1:\n"
104 EX_TABLE(0b, 1b)
105 : "+d" (reg0), "+d" (reg1), "+d" (reg2) : : "cc" );
106 return reg1;
107}
108
109/**
110 * Test adjunct processor queue.
111 * @qid: the ap queue number
112 * @queue_depth: pointer to queue depth value
113 * @device_type: pointer to device type value
114 *
115 * Returns ap queue status structure.
116 */
117static inline struct ap_queue_status
118ap_test_queue(ap_qid_t qid, int *queue_depth, int *device_type)
119{
120 register unsigned long reg0 asm ("0") = qid;
121 register struct ap_queue_status reg1 asm ("1");
122 register unsigned long reg2 asm ("2") = 0UL;
123
124 asm volatile(".long 0xb2af0000" /* PQAP(TAPQ) */
125 : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
126 *device_type = (int) (reg2 >> 24);
127 *queue_depth = (int) (reg2 & 0xff);
128 return reg1;
129}
130
131/**
132 * Reset adjunct processor queue.
133 * @qid: the ap queue number
134 *
135 * Returns ap queue status structure.
136 */
137static inline struct ap_queue_status ap_reset_queue(ap_qid_t qid)
138{
139 register unsigned long reg0 asm ("0") = qid | 0x01000000UL;
140 register struct ap_queue_status reg1 asm ("1");
141 register unsigned long reg2 asm ("2") = 0UL;
142
143 asm volatile(
144 ".long 0xb2af0000" /* PQAP(RAPQ) */
145 : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
146 return reg1;
147}
148
149/**
150 * Send message to adjunct processor queue.
151 * @qid: the ap queue number
152 * @psmid: the program supplied message identifier
153 * @msg: the message text
154 * @length: the message length
155 *
156 * Returns ap queue status structure.
157 *
158 * Condition code 1 on NQAP can't happen because the L bit is 1.
159 *
160 * Condition code 2 on NQAP also means the send is incomplete,
161 * because a segment boundary was reached. The NQAP is repeated.
162 */
163static inline struct ap_queue_status
164__ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length)
165{
166 typedef struct { char _[length]; } msgblock;
167 register unsigned long reg0 asm ("0") = qid | 0x40000000UL;
168 register struct ap_queue_status reg1 asm ("1");
169 register unsigned long reg2 asm ("2") = (unsigned long) msg;
170 register unsigned long reg3 asm ("3") = (unsigned long) length;
171 register unsigned long reg4 asm ("4") = (unsigned int) (psmid >> 32);
172 register unsigned long reg5 asm ("5") = (unsigned int) psmid;
173
174 asm volatile (
175 "0: .long 0xb2ad0042\n" /* DQAP */
176 " brc 2,0b"
177 : "+d" (reg0), "=d" (reg1), "+d" (reg2), "+d" (reg3)
178 : "d" (reg4), "d" (reg5), "m" (*(msgblock *) msg)
179 : "cc" );
180 return reg1;
181}
182
183int ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length)
184{
185 struct ap_queue_status status;
186
187 status = __ap_send(qid, psmid, msg, length);
188 switch (status.response_code) {
189 case AP_RESPONSE_NORMAL:
190 return 0;
191 case AP_RESPONSE_Q_FULL:
192 return -EBUSY;
193 default: /* Device is gone. */
194 return -ENODEV;
195 }
196}
197EXPORT_SYMBOL(ap_send);
198
199/*
200 * Receive message from adjunct processor queue.
201 * @qid: the ap queue number
202 * @psmid: pointer to program supplied message identifier
203 * @msg: the message text
204 * @length: the message length
205 *
206 * Returns ap queue status structure.
207 *
208 * Condition code 1 on DQAP means the receive has taken place
209 * but only partially. The response is incomplete, hence the
210 * DQAP is repeated.
211 *
212 * Condition code 2 on DQAP also means the receive is incomplete,
213 * this time because a segment boundary was reached. Again, the
214 * DQAP is repeated.
215 *
216 * Note that gpr2 is used by the DQAP instruction to keep track of
217 * any 'residual' length, in case the instruction gets interrupted.
218 * Hence it gets zeroed before the instruction.
219 */
220static inline struct ap_queue_status
221__ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length)
222{
223 typedef struct { char _[length]; } msgblock;
224 register unsigned long reg0 asm("0") = qid | 0x80000000UL;
225 register struct ap_queue_status reg1 asm ("1");
226 register unsigned long reg2 asm("2") = 0UL;
227 register unsigned long reg4 asm("4") = (unsigned long) msg;
228 register unsigned long reg5 asm("5") = (unsigned long) length;
229 register unsigned long reg6 asm("6") = 0UL;
230 register unsigned long reg7 asm("7") = 0UL;
231
232
233 asm volatile(
234 "0: .long 0xb2ae0064\n"
235 " brc 6,0b\n"
236 : "+d" (reg0), "=d" (reg1), "+d" (reg2),
237 "+d" (reg4), "+d" (reg5), "+d" (reg6), "+d" (reg7),
238 "=m" (*(msgblock *) msg) : : "cc" );
239 *psmid = (((unsigned long long) reg6) << 32) + reg7;
240 return reg1;
241}
242
243int ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length)
244{
245 struct ap_queue_status status;
246
247 status = __ap_recv(qid, psmid, msg, length);
248 switch (status.response_code) {
249 case AP_RESPONSE_NORMAL:
250 return 0;
251 case AP_RESPONSE_NO_PENDING_REPLY:
252 if (status.queue_empty)
253 return -ENOENT;
254 return -EBUSY;
255 default:
256 return -ENODEV;
257 }
258}
259EXPORT_SYMBOL(ap_recv);
260
261/**
262 * Check if an AP queue is available. The test is repeated for
263 * AP_MAX_RESET times.
264 * @qid: the ap queue number
265 * @queue_depth: pointer to queue depth value
266 * @device_type: pointer to device type value
267 */
268static int ap_query_queue(ap_qid_t qid, int *queue_depth, int *device_type)
269{
270 struct ap_queue_status status;
271 int t_depth, t_device_type, rc, i;
272
273 rc = -EBUSY;
274 for (i = 0; i < AP_MAX_RESET; i++) {
275 status = ap_test_queue(qid, &t_depth, &t_device_type);
276 switch (status.response_code) {
277 case AP_RESPONSE_NORMAL:
278 *queue_depth = t_depth + 1;
279 *device_type = t_device_type;
280 rc = 0;
281 break;
282 case AP_RESPONSE_Q_NOT_AVAIL:
283 rc = -ENODEV;
284 break;
285 case AP_RESPONSE_RESET_IN_PROGRESS:
286 break;
287 case AP_RESPONSE_DECONFIGURED:
288 rc = -ENODEV;
289 break;
290 case AP_RESPONSE_CHECKSTOPPED:
291 rc = -ENODEV;
292 break;
293 case AP_RESPONSE_BUSY:
294 break;
295 default:
296 BUG();
297 }
298 if (rc != -EBUSY)
299 break;
300 if (i < AP_MAX_RESET - 1)
301 udelay(5);
302 }
303 return rc;
304}
305
306/**
307 * Reset an AP queue and wait for it to become available again.
308 * @qid: the ap queue number
309 */
310static int ap_init_queue(ap_qid_t qid)
311{
312 struct ap_queue_status status;
313 int rc, dummy, i;
314
315 rc = -ENODEV;
316 status = ap_reset_queue(qid);
317 for (i = 0; i < AP_MAX_RESET; i++) {
318 switch (status.response_code) {
319 case AP_RESPONSE_NORMAL:
320 if (status.queue_empty)
321 rc = 0;
322 break;
323 case AP_RESPONSE_Q_NOT_AVAIL:
324 case AP_RESPONSE_DECONFIGURED:
325 case AP_RESPONSE_CHECKSTOPPED:
326 i = AP_MAX_RESET; /* return with -ENODEV */
327 break;
328 case AP_RESPONSE_RESET_IN_PROGRESS:
329 case AP_RESPONSE_BUSY:
330 default:
331 break;
332 }
333 if (rc != -ENODEV)
334 break;
335 if (i < AP_MAX_RESET - 1) {
336 udelay(5);
337 status = ap_test_queue(qid, &dummy, &dummy);
338 }
339 }
340 return rc;
341}
342
343/**
344 * AP device related attributes.
345 */
346static ssize_t ap_hwtype_show(struct device *dev,
347 struct device_attribute *attr, char *buf)
348{
349 struct ap_device *ap_dev = to_ap_dev(dev);
350 return snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->device_type);
351}
352static DEVICE_ATTR(hwtype, 0444, ap_hwtype_show, NULL);
353
354static ssize_t ap_depth_show(struct device *dev, struct device_attribute *attr,
355 char *buf)
356{
357 struct ap_device *ap_dev = to_ap_dev(dev);
358 return snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->queue_depth);
359}
360static DEVICE_ATTR(depth, 0444, ap_depth_show, NULL);
361
362static ssize_t ap_request_count_show(struct device *dev,
363 struct device_attribute *attr,
364 char *buf)
365{
366 struct ap_device *ap_dev = to_ap_dev(dev);
367 int rc;
368
369 spin_lock_bh(&ap_dev->lock);
370 rc = snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->total_request_count);
371 spin_unlock_bh(&ap_dev->lock);
372 return rc;
373}
374
375static DEVICE_ATTR(request_count, 0444, ap_request_count_show, NULL);
376
377static ssize_t ap_modalias_show(struct device *dev,
378 struct device_attribute *attr, char *buf)
379{
380 return sprintf(buf, "ap:t%02X", to_ap_dev(dev)->device_type);
381}
382
383static DEVICE_ATTR(modalias, 0444, ap_modalias_show, NULL);
384
385static struct attribute *ap_dev_attrs[] = {
386 &dev_attr_hwtype.attr,
387 &dev_attr_depth.attr,
388 &dev_attr_request_count.attr,
389 &dev_attr_modalias.attr,
390 NULL
391};
392static struct attribute_group ap_dev_attr_group = {
393 .attrs = ap_dev_attrs
394};
395
396/**
397 * AP bus driver registration/unregistration.
398 */
399static int ap_bus_match(struct device *dev, struct device_driver *drv)
400{
401 struct ap_device *ap_dev = to_ap_dev(dev);
402 struct ap_driver *ap_drv = to_ap_drv(drv);
403 struct ap_device_id *id;
404
405 /**
406 * Compare device type of the device with the list of
407 * supported types of the device_driver.
408 */
409 for (id = ap_drv->ids; id->match_flags; id++) {
410 if ((id->match_flags & AP_DEVICE_ID_MATCH_DEVICE_TYPE) &&
411 (id->dev_type != ap_dev->device_type))
412 continue;
413 return 1;
414 }
415 return 0;
416}
417
418/**
419 * uevent function for AP devices. It sets up a single environment
420 * variable DEV_TYPE which contains the hardware device type.
421 */
422static int ap_uevent (struct device *dev, char **envp, int num_envp,
423 char *buffer, int buffer_size)
424{
425 struct ap_device *ap_dev = to_ap_dev(dev);
426 int length;
427
428 if (!ap_dev)
429 return -ENODEV;
430
431 /* Set up DEV_TYPE environment variable. */
432 envp[0] = buffer;
433 length = scnprintf(buffer, buffer_size, "DEV_TYPE=%04X",
434 ap_dev->device_type);
435 if (buffer_size - length <= 0)
436 return -ENOMEM;
Cornelia Huck66a4263b2006-12-04 15:40:10 +0100437 buffer += length;
438 buffer_size -= length;
439 /* Add MODALIAS= */
440 envp[1] = buffer;
441 length = scnprintf(buffer, buffer_size, "MODALIAS=ap:t%02X",
442 ap_dev->device_type);
443 if (buffer_size - length <= 0)
444 return -ENOMEM;
445 envp[2] = NULL;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200446 return 0;
447}
448
449static struct bus_type ap_bus_type = {
450 .name = "ap",
451 .match = &ap_bus_match,
452 .uevent = &ap_uevent,
453};
454
455static int ap_device_probe(struct device *dev)
456{
457 struct ap_device *ap_dev = to_ap_dev(dev);
458 struct ap_driver *ap_drv = to_ap_drv(dev->driver);
459 int rc;
460
461 ap_dev->drv = ap_drv;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +0100462 spin_lock_bh(&ap_device_lock);
463 list_add(&ap_dev->list, &ap_device_list);
464 spin_unlock_bh(&ap_device_lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200465 rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200466 return rc;
467}
468
469/**
470 * Flush all requests from the request/pending queue of an AP device.
471 * @ap_dev: pointer to the AP device.
472 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +0100473static void __ap_flush_queue(struct ap_device *ap_dev)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200474{
475 struct ap_message *ap_msg, *next;
476
477 list_for_each_entry_safe(ap_msg, next, &ap_dev->pendingq, list) {
478 list_del_init(&ap_msg->list);
479 ap_dev->pendingq_count--;
480 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
481 }
482 list_for_each_entry_safe(ap_msg, next, &ap_dev->requestq, list) {
483 list_del_init(&ap_msg->list);
484 ap_dev->requestq_count--;
485 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
486 }
487}
488
489void ap_flush_queue(struct ap_device *ap_dev)
490{
491 spin_lock_bh(&ap_dev->lock);
492 __ap_flush_queue(ap_dev);
493 spin_unlock_bh(&ap_dev->lock);
494}
495EXPORT_SYMBOL(ap_flush_queue);
496
497static int ap_device_remove(struct device *dev)
498{
499 struct ap_device *ap_dev = to_ap_dev(dev);
500 struct ap_driver *ap_drv = ap_dev->drv;
501
Ralph Wuerthner4e562962006-10-04 20:02:05 +0200502 ap_flush_queue(ap_dev);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200503 if (ap_drv->remove)
504 ap_drv->remove(ap_dev);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +0100505 spin_lock_bh(&ap_device_lock);
506 list_del_init(&ap_dev->list);
507 spin_unlock_bh(&ap_device_lock);
Ralph Wuerthnere675c0d2007-03-26 20:42:43 +0200508 spin_lock_bh(&ap_dev->lock);
509 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
510 spin_unlock_bh(&ap_dev->lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200511 return 0;
512}
513
514int ap_driver_register(struct ap_driver *ap_drv, struct module *owner,
515 char *name)
516{
517 struct device_driver *drv = &ap_drv->driver;
518
519 drv->bus = &ap_bus_type;
520 drv->probe = ap_device_probe;
521 drv->remove = ap_device_remove;
522 drv->owner = owner;
523 drv->name = name;
524 return driver_register(drv);
525}
526EXPORT_SYMBOL(ap_driver_register);
527
528void ap_driver_unregister(struct ap_driver *ap_drv)
529{
530 driver_unregister(&ap_drv->driver);
531}
532EXPORT_SYMBOL(ap_driver_unregister);
533
534/**
535 * AP bus attributes.
536 */
537static ssize_t ap_domain_show(struct bus_type *bus, char *buf)
538{
539 return snprintf(buf, PAGE_SIZE, "%d\n", ap_domain_index);
540}
541
542static BUS_ATTR(ap_domain, 0444, ap_domain_show, NULL);
543
544static ssize_t ap_config_time_show(struct bus_type *bus, char *buf)
545{
546 return snprintf(buf, PAGE_SIZE, "%d\n", ap_config_time);
547}
548
549static ssize_t ap_config_time_store(struct bus_type *bus,
550 const char *buf, size_t count)
551{
552 int time;
553
554 if (sscanf(buf, "%d\n", &time) != 1 || time < 5 || time > 120)
555 return -EINVAL;
556 ap_config_time = time;
557 if (!timer_pending(&ap_config_timer) ||
558 !mod_timer(&ap_config_timer, jiffies + ap_config_time * HZ)) {
559 ap_config_timer.expires = jiffies + ap_config_time * HZ;
560 add_timer(&ap_config_timer);
561 }
562 return count;
563}
564
565static BUS_ATTR(config_time, 0644, ap_config_time_show, ap_config_time_store);
566
567static ssize_t ap_poll_thread_show(struct bus_type *bus, char *buf)
568{
569 return snprintf(buf, PAGE_SIZE, "%d\n", ap_poll_kthread ? 1 : 0);
570}
571
572static ssize_t ap_poll_thread_store(struct bus_type *bus,
573 const char *buf, size_t count)
574{
575 int flag, rc;
576
577 if (sscanf(buf, "%d\n", &flag) != 1)
578 return -EINVAL;
579 if (flag) {
580 rc = ap_poll_thread_start();
581 if (rc)
582 return rc;
583 }
584 else
585 ap_poll_thread_stop();
586 return count;
587}
588
589static BUS_ATTR(poll_thread, 0644, ap_poll_thread_show, ap_poll_thread_store);
590
591static struct bus_attribute *const ap_bus_attrs[] = {
592 &bus_attr_ap_domain,
593 &bus_attr_config_time,
594 &bus_attr_poll_thread,
595 NULL
596};
597
598/**
599 * Pick one of the 16 ap domains.
600 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +0100601static int ap_select_domain(void)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200602{
603 int queue_depth, device_type, count, max_count, best_domain;
604 int rc, i, j;
605
606 /**
607 * We want to use a single domain. Either the one specified with
608 * the "domain=" parameter or the domain with the maximum number
609 * of devices.
610 */
611 if (ap_domain_index >= 0 && ap_domain_index < AP_DOMAINS)
612 /* Domain has already been selected. */
613 return 0;
614 best_domain = -1;
615 max_count = 0;
616 for (i = 0; i < AP_DOMAINS; i++) {
617 count = 0;
618 for (j = 0; j < AP_DEVICES; j++) {
619 ap_qid_t qid = AP_MKQID(j, i);
620 rc = ap_query_queue(qid, &queue_depth, &device_type);
621 if (rc)
622 continue;
623 count++;
624 }
625 if (count > max_count) {
626 max_count = count;
627 best_domain = i;
628 }
629 }
630 if (best_domain >= 0){
631 ap_domain_index = best_domain;
632 return 0;
633 }
634 return -ENODEV;
635}
636
637/**
638 * Find the device type if query queue returned a device type of 0.
639 * @ap_dev: pointer to the AP device.
640 */
641static int ap_probe_device_type(struct ap_device *ap_dev)
642{
643 static unsigned char msg[] = {
644 0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
645 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
646 0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,
647 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
648 0x01,0x00,0x43,0x43,0x41,0x2d,0x41,0x50,
649 0x50,0x4c,0x20,0x20,0x20,0x01,0x01,0x01,
650 0x00,0x00,0x00,0x00,0x50,0x4b,0x00,0x00,
651 0x00,0x00,0x01,0x1c,0x00,0x00,0x00,0x00,
652 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
653 0x00,0x00,0x05,0xb8,0x00,0x00,0x00,0x00,
654 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
655 0x70,0x00,0x41,0x00,0x00,0x00,0x00,0x00,
656 0x00,0x00,0x54,0x32,0x01,0x00,0xa0,0x00,
657 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
658 0x00,0x00,0x00,0x00,0xb8,0x05,0x00,0x00,
659 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
660 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
661 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
662 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
663 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
664 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
665 0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,
666 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
667 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,
668 0x49,0x43,0x53,0x46,0x20,0x20,0x20,0x20,
669 0x50,0x4b,0x0a,0x00,0x50,0x4b,0x43,0x53,
670 0x2d,0x31,0x2e,0x32,0x37,0x00,0x11,0x22,
671 0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,
672 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,
673 0x99,0x00,0x11,0x22,0x33,0x44,0x55,0x66,
674 0x77,0x88,0x99,0x00,0x11,0x22,0x33,0x44,
675 0x55,0x66,0x77,0x88,0x99,0x00,0x11,0x22,
676 0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,
677 0x11,0x22,0x33,0x5d,0x00,0x5b,0x00,0x77,
678 0x88,0x1e,0x00,0x00,0x57,0x00,0x00,0x00,
679 0x00,0x04,0x00,0x00,0x4f,0x00,0x00,0x00,
680 0x03,0x02,0x00,0x00,0x40,0x01,0x00,0x01,
681 0xce,0x02,0x68,0x2d,0x5f,0xa9,0xde,0x0c,
682 0xf6,0xd2,0x7b,0x58,0x4b,0xf9,0x28,0x68,
683 0x3d,0xb4,0xf4,0xef,0x78,0xd5,0xbe,0x66,
684 0x63,0x42,0xef,0xf8,0xfd,0xa4,0xf8,0xb0,
685 0x8e,0x29,0xc2,0xc9,0x2e,0xd8,0x45,0xb8,
686 0x53,0x8c,0x6f,0x4e,0x72,0x8f,0x6c,0x04,
687 0x9c,0x88,0xfc,0x1e,0xc5,0x83,0x55,0x57,
688 0xf7,0xdd,0xfd,0x4f,0x11,0x36,0x95,0x5d,
689 };
690 struct ap_queue_status status;
691 unsigned long long psmid;
692 char *reply;
693 int rc, i;
694
695 reply = (void *) get_zeroed_page(GFP_KERNEL);
696 if (!reply) {
697 rc = -ENOMEM;
698 goto out;
699 }
700
701 status = __ap_send(ap_dev->qid, 0x0102030405060708ULL,
702 msg, sizeof(msg));
703 if (status.response_code != AP_RESPONSE_NORMAL) {
704 rc = -ENODEV;
705 goto out_free;
706 }
707
708 /* Wait for the test message to complete. */
709 for (i = 0; i < 6; i++) {
710 mdelay(300);
711 status = __ap_recv(ap_dev->qid, &psmid, reply, 4096);
712 if (status.response_code == AP_RESPONSE_NORMAL &&
713 psmid == 0x0102030405060708ULL)
714 break;
715 }
716 if (i < 6) {
717 /* Got an answer. */
718 if (reply[0] == 0x00 && reply[1] == 0x86)
719 ap_dev->device_type = AP_DEVICE_TYPE_PCICC;
720 else
721 ap_dev->device_type = AP_DEVICE_TYPE_PCICA;
722 rc = 0;
723 } else
724 rc = -ENODEV;
725
726out_free:
727 free_page((unsigned long) reply);
728out:
729 return rc;
730}
731
732/**
733 * Scan the ap bus for new devices.
734 */
735static int __ap_scan_bus(struct device *dev, void *data)
736{
737 return to_ap_dev(dev)->qid == (ap_qid_t)(unsigned long) data;
738}
739
740static void ap_device_release(struct device *dev)
741{
742 struct ap_device *ap_dev = to_ap_dev(dev);
743
744 kfree(ap_dev);
745}
746
Al Viro4927b3f2006-12-06 19:18:20 +0000747static void ap_scan_bus(struct work_struct *unused)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200748{
749 struct ap_device *ap_dev;
750 struct device *dev;
751 ap_qid_t qid;
752 int queue_depth, device_type;
753 int rc, i;
754
755 if (ap_select_domain() != 0)
756 return;
757 for (i = 0; i < AP_DEVICES; i++) {
758 qid = AP_MKQID(i, ap_domain_index);
759 dev = bus_find_device(&ap_bus_type, NULL,
760 (void *)(unsigned long)qid,
761 __ap_scan_bus);
Ralph Wuerthnerf3b017d2006-10-27 12:39:26 +0200762 rc = ap_query_queue(qid, &queue_depth, &device_type);
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +0200763 if (dev) {
764 ap_dev = to_ap_dev(dev);
765 spin_lock_bh(&ap_dev->lock);
766 if (rc || ap_dev->unregistered) {
767 spin_unlock_bh(&ap_dev->lock);
768 put_device(dev);
769 device_unregister(dev);
770 continue;
771 } else
772 spin_unlock_bh(&ap_dev->lock);
Ralph Wuerthnerf3b017d2006-10-27 12:39:26 +0200773 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200774 if (dev) {
775 put_device(dev);
776 continue;
777 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200778 if (rc)
779 continue;
780 rc = ap_init_queue(qid);
781 if (rc)
782 continue;
783 ap_dev = kzalloc(sizeof(*ap_dev), GFP_KERNEL);
784 if (!ap_dev)
785 break;
786 ap_dev->qid = qid;
787 ap_dev->queue_depth = queue_depth;
Ralph Wuerthner4e562962006-10-04 20:02:05 +0200788 ap_dev->unregistered = 1;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200789 spin_lock_init(&ap_dev->lock);
790 INIT_LIST_HEAD(&ap_dev->pendingq);
791 INIT_LIST_HEAD(&ap_dev->requestq);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +0100792 INIT_LIST_HEAD(&ap_dev->list);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200793 if (device_type == 0)
794 ap_probe_device_type(ap_dev);
795 else
796 ap_dev->device_type = device_type;
797
798 ap_dev->device.bus = &ap_bus_type;
799 ap_dev->device.parent = ap_root_device;
800 snprintf(ap_dev->device.bus_id, BUS_ID_SIZE, "card%02x",
801 AP_QID_DEVICE(ap_dev->qid));
802 ap_dev->device.release = ap_device_release;
803 rc = device_register(&ap_dev->device);
804 if (rc) {
805 kfree(ap_dev);
806 continue;
807 }
808 /* Add device attributes. */
809 rc = sysfs_create_group(&ap_dev->device.kobj,
810 &ap_dev_attr_group);
Ralph Wuerthner4e562962006-10-04 20:02:05 +0200811 if (!rc) {
812 spin_lock_bh(&ap_dev->lock);
813 ap_dev->unregistered = 0;
814 spin_unlock_bh(&ap_dev->lock);
815 }
816 else
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200817 device_unregister(&ap_dev->device);
818 }
819}
820
821static void
822ap_config_timeout(unsigned long ptr)
823{
824 queue_work(ap_work_queue, &ap_config_work);
825 ap_config_timer.expires = jiffies + ap_config_time * HZ;
826 add_timer(&ap_config_timer);
827}
828
829/**
830 * Set up the timer to run the poll tasklet
831 */
832static inline void ap_schedule_poll_timer(void)
833{
834 if (timer_pending(&ap_poll_timer))
835 return;
836 mod_timer(&ap_poll_timer, jiffies + AP_POLL_TIME);
837}
838
839/**
840 * Receive pending reply messages from an AP device.
841 * @ap_dev: pointer to the AP device
842 * @flags: pointer to control flags, bit 2^0 is set if another poll is
843 * required, bit 2^1 is set if the poll timer needs to get armed
844 * Returns 0 if the device is still present, -ENODEV if not.
845 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +0100846static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200847{
848 struct ap_queue_status status;
849 struct ap_message *ap_msg;
850
851 if (ap_dev->queue_count <= 0)
852 return 0;
853 status = __ap_recv(ap_dev->qid, &ap_dev->reply->psmid,
854 ap_dev->reply->message, ap_dev->reply->length);
855 switch (status.response_code) {
856 case AP_RESPONSE_NORMAL:
857 atomic_dec(&ap_poll_requests);
858 ap_dev->queue_count--;
859 list_for_each_entry(ap_msg, &ap_dev->pendingq, list) {
860 if (ap_msg->psmid != ap_dev->reply->psmid)
861 continue;
862 list_del_init(&ap_msg->list);
863 ap_dev->pendingq_count--;
864 ap_dev->drv->receive(ap_dev, ap_msg, ap_dev->reply);
865 break;
866 }
867 if (ap_dev->queue_count > 0)
868 *flags |= 1;
869 break;
870 case AP_RESPONSE_NO_PENDING_REPLY:
871 if (status.queue_empty) {
872 /* The card shouldn't forget requests but who knows. */
Ralph Wuerthnere675c0d2007-03-26 20:42:43 +0200873 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200874 ap_dev->queue_count = 0;
875 list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
876 ap_dev->requestq_count += ap_dev->pendingq_count;
877 ap_dev->pendingq_count = 0;
878 } else
879 *flags |= 2;
880 break;
881 default:
882 return -ENODEV;
883 }
884 return 0;
885}
886
887/**
888 * Send messages from the request queue to an AP device.
889 * @ap_dev: pointer to the AP device
890 * @flags: pointer to control flags, bit 2^0 is set if another poll is
891 * required, bit 2^1 is set if the poll timer needs to get armed
892 * Returns 0 if the device is still present, -ENODEV if not.
893 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +0100894static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200895{
896 struct ap_queue_status status;
897 struct ap_message *ap_msg;
898
899 if (ap_dev->requestq_count <= 0 ||
900 ap_dev->queue_count >= ap_dev->queue_depth)
901 return 0;
902 /* Start the next request on the queue. */
903 ap_msg = list_entry(ap_dev->requestq.next, struct ap_message, list);
904 status = __ap_send(ap_dev->qid, ap_msg->psmid,
905 ap_msg->message, ap_msg->length);
906 switch (status.response_code) {
907 case AP_RESPONSE_NORMAL:
908 atomic_inc(&ap_poll_requests);
909 ap_dev->queue_count++;
910 list_move_tail(&ap_msg->list, &ap_dev->pendingq);
911 ap_dev->requestq_count--;
912 ap_dev->pendingq_count++;
913 if (ap_dev->queue_count < ap_dev->queue_depth &&
914 ap_dev->requestq_count > 0)
915 *flags |= 1;
916 *flags |= 2;
917 break;
918 case AP_RESPONSE_Q_FULL:
919 *flags |= 2;
920 break;
921 case AP_RESPONSE_MESSAGE_TOO_BIG:
922 return -EINVAL;
923 default:
924 return -ENODEV;
925 }
926 return 0;
927}
928
929/**
930 * Poll AP device for pending replies and send new messages. If either
931 * ap_poll_read or ap_poll_write returns -ENODEV unregister the device.
932 * @ap_dev: pointer to the bus device
933 * @flags: pointer to control flags, bit 2^0 is set if another poll is
934 * required, bit 2^1 is set if the poll timer needs to get armed
935 * Returns 0.
936 */
937static inline int ap_poll_queue(struct ap_device *ap_dev, unsigned long *flags)
938{
939 int rc;
940
941 rc = ap_poll_read(ap_dev, flags);
942 if (rc)
943 return rc;
944 return ap_poll_write(ap_dev, flags);
945}
946
947/**
948 * Queue a message to a device.
949 * @ap_dev: pointer to the AP device
950 * @ap_msg: the message to be queued
951 */
952static int __ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
953{
954 struct ap_queue_status status;
955
956 if (list_empty(&ap_dev->requestq) &&
957 ap_dev->queue_count < ap_dev->queue_depth) {
958 status = __ap_send(ap_dev->qid, ap_msg->psmid,
959 ap_msg->message, ap_msg->length);
960 switch (status.response_code) {
961 case AP_RESPONSE_NORMAL:
962 list_add_tail(&ap_msg->list, &ap_dev->pendingq);
963 atomic_inc(&ap_poll_requests);
964 ap_dev->pendingq_count++;
965 ap_dev->queue_count++;
966 ap_dev->total_request_count++;
967 break;
968 case AP_RESPONSE_Q_FULL:
969 list_add_tail(&ap_msg->list, &ap_dev->requestq);
970 ap_dev->requestq_count++;
971 ap_dev->total_request_count++;
972 return -EBUSY;
973 case AP_RESPONSE_MESSAGE_TOO_BIG:
974 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL));
975 return -EINVAL;
976 default: /* Device is gone. */
977 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
978 return -ENODEV;
979 }
980 } else {
981 list_add_tail(&ap_msg->list, &ap_dev->requestq);
982 ap_dev->requestq_count++;
983 ap_dev->total_request_count++;
984 return -EBUSY;
985 }
986 ap_schedule_poll_timer();
987 return 0;
988}
989
990void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
991{
992 unsigned long flags;
993 int rc;
994
995 spin_lock_bh(&ap_dev->lock);
996 if (!ap_dev->unregistered) {
997 /* Make room on the queue by polling for finished requests. */
998 rc = ap_poll_queue(ap_dev, &flags);
999 if (!rc)
1000 rc = __ap_queue_message(ap_dev, ap_msg);
1001 if (!rc)
1002 wake_up(&ap_poll_wait);
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001003 if (rc == -ENODEV)
1004 ap_dev->unregistered = 1;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001005 } else {
1006 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001007 rc = -ENODEV;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001008 }
1009 spin_unlock_bh(&ap_dev->lock);
1010 if (rc == -ENODEV)
1011 device_unregister(&ap_dev->device);
1012}
1013EXPORT_SYMBOL(ap_queue_message);
1014
1015/**
1016 * Cancel a crypto request. This is done by removing the request
1017 * from the devive pendingq or requestq queue. Note that the
1018 * request stays on the AP queue. When it finishes the message
1019 * reply will be discarded because the psmid can't be found.
1020 * @ap_dev: AP device that has the message queued
1021 * @ap_msg: the message that is to be removed
1022 */
1023void ap_cancel_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
1024{
1025 struct ap_message *tmp;
1026
1027 spin_lock_bh(&ap_dev->lock);
1028 if (!list_empty(&ap_msg->list)) {
1029 list_for_each_entry(tmp, &ap_dev->pendingq, list)
1030 if (tmp->psmid == ap_msg->psmid) {
1031 ap_dev->pendingq_count--;
1032 goto found;
1033 }
1034 ap_dev->requestq_count--;
1035 found:
1036 list_del_init(&ap_msg->list);
1037 }
1038 spin_unlock_bh(&ap_dev->lock);
1039}
1040EXPORT_SYMBOL(ap_cancel_message);
1041
1042/**
1043 * AP receive polling for finished AP requests
1044 */
1045static void ap_poll_timeout(unsigned long unused)
1046{
1047 tasklet_schedule(&ap_tasklet);
1048}
1049
1050/**
1051 * Poll all AP devices on the bus in a round robin fashion. Continue
1052 * polling until bit 2^0 of the control flags is not set. If bit 2^1
1053 * of the control flags has been set arm the poll timer.
1054 */
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001055static int __ap_poll_all(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001056{
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001057 spin_lock(&ap_dev->lock);
1058 if (!ap_dev->unregistered) {
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001059 if (ap_poll_queue(ap_dev, flags))
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001060 ap_dev->unregistered = 1;
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001061 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001062 spin_unlock(&ap_dev->lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001063 return 0;
1064}
1065
1066static void ap_poll_all(unsigned long dummy)
1067{
1068 unsigned long flags;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001069 struct ap_device *ap_dev;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001070
1071 do {
1072 flags = 0;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001073 spin_lock(&ap_device_lock);
1074 list_for_each_entry(ap_dev, &ap_device_list, list) {
1075 __ap_poll_all(ap_dev, &flags);
1076 }
1077 spin_unlock(&ap_device_lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001078 } while (flags & 1);
1079 if (flags & 2)
1080 ap_schedule_poll_timer();
1081}
1082
1083/**
1084 * AP bus poll thread. The purpose of this thread is to poll for
1085 * finished requests in a loop if there is a "free" cpu - that is
1086 * a cpu that doesn't have anything better to do. The polling stops
1087 * as soon as there is another task or if all messages have been
1088 * delivered.
1089 */
1090static int ap_poll_thread(void *data)
1091{
1092 DECLARE_WAITQUEUE(wait, current);
1093 unsigned long flags;
1094 int requests;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001095 struct ap_device *ap_dev;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001096
Christian Borntraegerd83682b2006-10-06 16:38:22 +02001097 set_user_nice(current, 19);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001098 while (1) {
1099 if (need_resched()) {
1100 schedule();
1101 continue;
1102 }
1103 add_wait_queue(&ap_poll_wait, &wait);
1104 set_current_state(TASK_INTERRUPTIBLE);
1105 if (kthread_should_stop())
1106 break;
1107 requests = atomic_read(&ap_poll_requests);
1108 if (requests <= 0)
1109 schedule();
1110 set_current_state(TASK_RUNNING);
1111 remove_wait_queue(&ap_poll_wait, &wait);
1112
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001113 flags = 0;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001114 spin_lock_bh(&ap_device_lock);
1115 list_for_each_entry(ap_dev, &ap_device_list, list) {
1116 __ap_poll_all(ap_dev, &flags);
1117 }
1118 spin_unlock_bh(&ap_device_lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001119 }
1120 set_current_state(TASK_RUNNING);
1121 remove_wait_queue(&ap_poll_wait, &wait);
1122 return 0;
1123}
1124
1125static int ap_poll_thread_start(void)
1126{
1127 int rc;
1128
1129 mutex_lock(&ap_poll_thread_mutex);
1130 if (!ap_poll_kthread) {
1131 ap_poll_kthread = kthread_run(ap_poll_thread, NULL, "appoll");
1132 rc = IS_ERR(ap_poll_kthread) ? PTR_ERR(ap_poll_kthread) : 0;
1133 if (rc)
1134 ap_poll_kthread = NULL;
1135 }
1136 else
1137 rc = 0;
1138 mutex_unlock(&ap_poll_thread_mutex);
1139 return rc;
1140}
1141
1142static void ap_poll_thread_stop(void)
1143{
1144 mutex_lock(&ap_poll_thread_mutex);
1145 if (ap_poll_kthread) {
1146 kthread_stop(ap_poll_kthread);
1147 ap_poll_kthread = NULL;
1148 }
1149 mutex_unlock(&ap_poll_thread_mutex);
1150}
1151
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001152static void ap_reset_domain(void)
1153{
1154 int i;
1155
1156 for (i = 0; i < AP_DEVICES; i++)
1157 ap_reset_queue(AP_MKQID(i, ap_domain_index));
1158}
1159
1160static void ap_reset_all(void)
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001161{
1162 int i, j;
1163
1164 for (i = 0; i < AP_DOMAINS; i++)
1165 for (j = 0; j < AP_DEVICES; j++)
1166 ap_reset_queue(AP_MKQID(j, i));
1167}
1168
1169static struct reset_call ap_reset_call = {
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001170 .fn = ap_reset_all,
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001171};
1172
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001173/**
1174 * The module initialization code.
1175 */
1176int __init ap_module_init(void)
1177{
1178 int rc, i;
1179
1180 if (ap_domain_index < -1 || ap_domain_index >= AP_DOMAINS) {
1181 printk(KERN_WARNING "Invalid param: domain = %d. "
1182 " Not loading.\n", ap_domain_index);
1183 return -EINVAL;
1184 }
1185 if (ap_instructions_available() != 0) {
1186 printk(KERN_WARNING "AP instructions not installed.\n");
1187 return -ENODEV;
1188 }
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001189 register_reset_call(&ap_reset_call);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001190
1191 /* Create /sys/bus/ap. */
1192 rc = bus_register(&ap_bus_type);
1193 if (rc)
1194 goto out;
1195 for (i = 0; ap_bus_attrs[i]; i++) {
1196 rc = bus_create_file(&ap_bus_type, ap_bus_attrs[i]);
1197 if (rc)
1198 goto out_bus;
1199 }
1200
1201 /* Create /sys/devices/ap. */
1202 ap_root_device = s390_root_dev_register("ap");
1203 rc = IS_ERR(ap_root_device) ? PTR_ERR(ap_root_device) : 0;
1204 if (rc)
1205 goto out_bus;
1206
1207 ap_work_queue = create_singlethread_workqueue("kapwork");
1208 if (!ap_work_queue) {
1209 rc = -ENOMEM;
1210 goto out_root;
1211 }
1212
1213 if (ap_select_domain() == 0)
1214 ap_scan_bus(NULL);
1215
1216 /* Setup the ap bus rescan timer. */
1217 init_timer(&ap_config_timer);
1218 ap_config_timer.function = ap_config_timeout;
1219 ap_config_timer.data = 0;
1220 ap_config_timer.expires = jiffies + ap_config_time * HZ;
1221 add_timer(&ap_config_timer);
1222
1223 /* Start the low priority AP bus poll thread. */
1224 if (ap_thread_flag) {
1225 rc = ap_poll_thread_start();
1226 if (rc)
1227 goto out_work;
1228 }
1229
1230 return 0;
1231
1232out_work:
1233 del_timer_sync(&ap_config_timer);
1234 del_timer_sync(&ap_poll_timer);
1235 destroy_workqueue(ap_work_queue);
1236out_root:
1237 s390_root_dev_unregister(ap_root_device);
1238out_bus:
1239 while (i--)
1240 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
1241 bus_unregister(&ap_bus_type);
1242out:
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001243 unregister_reset_call(&ap_reset_call);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001244 return rc;
1245}
1246
1247static int __ap_match_all(struct device *dev, void *data)
1248{
1249 return 1;
1250}
1251
1252/**
1253 * The module termination code
1254 */
1255void ap_module_exit(void)
1256{
1257 int i;
1258 struct device *dev;
1259
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001260 ap_reset_domain();
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001261 ap_poll_thread_stop();
1262 del_timer_sync(&ap_config_timer);
1263 del_timer_sync(&ap_poll_timer);
1264 destroy_workqueue(ap_work_queue);
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001265 tasklet_kill(&ap_tasklet);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001266 s390_root_dev_unregister(ap_root_device);
1267 while ((dev = bus_find_device(&ap_bus_type, NULL, NULL,
1268 __ap_match_all)))
1269 {
1270 device_unregister(dev);
1271 put_device(dev);
1272 }
1273 for (i = 0; ap_bus_attrs[i]; i++)
1274 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
1275 bus_unregister(&ap_bus_type);
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001276 unregister_reset_call(&ap_reset_call);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001277}
1278
1279#ifndef CONFIG_ZCRYPT_MONOLITHIC
1280module_init(ap_module_init);
1281module_exit(ap_module_exit);
1282#endif