blob: 5aac0ec3636848d60974230fcd132cd49ed110bb [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);
Eric Rannaudbf624562007-03-30 22:23:12 -0700426 int retval = 0, length = 0, i = 0;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200427
428 if (!ap_dev)
429 return -ENODEV;
430
431 /* Set up DEV_TYPE environment variable. */
Eric Rannaudbf624562007-03-30 22:23:12 -0700432 retval = add_uevent_var(envp, num_envp, &i,
433 buffer, buffer_size, &length,
434 "DEV_TYPE=%04X", ap_dev->device_type);
435 if (retval)
436 return retval;
437
Cornelia Huck66a4263b2006-12-04 15:40:10 +0100438 /* Add MODALIAS= */
Eric Rannaudbf624562007-03-30 22:23:12 -0700439 retval = add_uevent_var(envp, num_envp, &i,
440 buffer, buffer_size, &length,
441 "MODALIAS=ap:t%02X", ap_dev->device_type);
442
443 envp[i] = NULL;
444 return retval;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200445}
446
447static struct bus_type ap_bus_type = {
448 .name = "ap",
449 .match = &ap_bus_match,
450 .uevent = &ap_uevent,
451};
452
453static int ap_device_probe(struct device *dev)
454{
455 struct ap_device *ap_dev = to_ap_dev(dev);
456 struct ap_driver *ap_drv = to_ap_drv(dev->driver);
457 int rc;
458
459 ap_dev->drv = ap_drv;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +0100460 spin_lock_bh(&ap_device_lock);
461 list_add(&ap_dev->list, &ap_device_list);
462 spin_unlock_bh(&ap_device_lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200463 rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200464 return rc;
465}
466
467/**
468 * Flush all requests from the request/pending queue of an AP device.
469 * @ap_dev: pointer to the AP device.
470 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +0100471static void __ap_flush_queue(struct ap_device *ap_dev)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200472{
473 struct ap_message *ap_msg, *next;
474
475 list_for_each_entry_safe(ap_msg, next, &ap_dev->pendingq, list) {
476 list_del_init(&ap_msg->list);
477 ap_dev->pendingq_count--;
478 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
479 }
480 list_for_each_entry_safe(ap_msg, next, &ap_dev->requestq, list) {
481 list_del_init(&ap_msg->list);
482 ap_dev->requestq_count--;
483 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
484 }
485}
486
487void ap_flush_queue(struct ap_device *ap_dev)
488{
489 spin_lock_bh(&ap_dev->lock);
490 __ap_flush_queue(ap_dev);
491 spin_unlock_bh(&ap_dev->lock);
492}
493EXPORT_SYMBOL(ap_flush_queue);
494
495static int ap_device_remove(struct device *dev)
496{
497 struct ap_device *ap_dev = to_ap_dev(dev);
498 struct ap_driver *ap_drv = ap_dev->drv;
499
Ralph Wuerthner4e562962006-10-04 20:02:05 +0200500 ap_flush_queue(ap_dev);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200501 if (ap_drv->remove)
502 ap_drv->remove(ap_dev);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +0100503 spin_lock_bh(&ap_device_lock);
504 list_del_init(&ap_dev->list);
505 spin_unlock_bh(&ap_device_lock);
Ralph Wuerthnere675c0d2007-03-26 20:42:43 +0200506 spin_lock_bh(&ap_dev->lock);
507 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
508 spin_unlock_bh(&ap_dev->lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200509 return 0;
510}
511
512int ap_driver_register(struct ap_driver *ap_drv, struct module *owner,
513 char *name)
514{
515 struct device_driver *drv = &ap_drv->driver;
516
517 drv->bus = &ap_bus_type;
518 drv->probe = ap_device_probe;
519 drv->remove = ap_device_remove;
520 drv->owner = owner;
521 drv->name = name;
522 return driver_register(drv);
523}
524EXPORT_SYMBOL(ap_driver_register);
525
526void ap_driver_unregister(struct ap_driver *ap_drv)
527{
528 driver_unregister(&ap_drv->driver);
529}
530EXPORT_SYMBOL(ap_driver_unregister);
531
532/**
533 * AP bus attributes.
534 */
535static ssize_t ap_domain_show(struct bus_type *bus, char *buf)
536{
537 return snprintf(buf, PAGE_SIZE, "%d\n", ap_domain_index);
538}
539
540static BUS_ATTR(ap_domain, 0444, ap_domain_show, NULL);
541
542static ssize_t ap_config_time_show(struct bus_type *bus, char *buf)
543{
544 return snprintf(buf, PAGE_SIZE, "%d\n", ap_config_time);
545}
546
547static ssize_t ap_config_time_store(struct bus_type *bus,
548 const char *buf, size_t count)
549{
550 int time;
551
552 if (sscanf(buf, "%d\n", &time) != 1 || time < 5 || time > 120)
553 return -EINVAL;
554 ap_config_time = time;
555 if (!timer_pending(&ap_config_timer) ||
556 !mod_timer(&ap_config_timer, jiffies + ap_config_time * HZ)) {
557 ap_config_timer.expires = jiffies + ap_config_time * HZ;
558 add_timer(&ap_config_timer);
559 }
560 return count;
561}
562
563static BUS_ATTR(config_time, 0644, ap_config_time_show, ap_config_time_store);
564
565static ssize_t ap_poll_thread_show(struct bus_type *bus, char *buf)
566{
567 return snprintf(buf, PAGE_SIZE, "%d\n", ap_poll_kthread ? 1 : 0);
568}
569
570static ssize_t ap_poll_thread_store(struct bus_type *bus,
571 const char *buf, size_t count)
572{
573 int flag, rc;
574
575 if (sscanf(buf, "%d\n", &flag) != 1)
576 return -EINVAL;
577 if (flag) {
578 rc = ap_poll_thread_start();
579 if (rc)
580 return rc;
581 }
582 else
583 ap_poll_thread_stop();
584 return count;
585}
586
587static BUS_ATTR(poll_thread, 0644, ap_poll_thread_show, ap_poll_thread_store);
588
589static struct bus_attribute *const ap_bus_attrs[] = {
590 &bus_attr_ap_domain,
591 &bus_attr_config_time,
592 &bus_attr_poll_thread,
593 NULL
594};
595
596/**
597 * Pick one of the 16 ap domains.
598 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +0100599static int ap_select_domain(void)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200600{
601 int queue_depth, device_type, count, max_count, best_domain;
602 int rc, i, j;
603
604 /**
605 * We want to use a single domain. Either the one specified with
606 * the "domain=" parameter or the domain with the maximum number
607 * of devices.
608 */
609 if (ap_domain_index >= 0 && ap_domain_index < AP_DOMAINS)
610 /* Domain has already been selected. */
611 return 0;
612 best_domain = -1;
613 max_count = 0;
614 for (i = 0; i < AP_DOMAINS; i++) {
615 count = 0;
616 for (j = 0; j < AP_DEVICES; j++) {
617 ap_qid_t qid = AP_MKQID(j, i);
618 rc = ap_query_queue(qid, &queue_depth, &device_type);
619 if (rc)
620 continue;
621 count++;
622 }
623 if (count > max_count) {
624 max_count = count;
625 best_domain = i;
626 }
627 }
628 if (best_domain >= 0){
629 ap_domain_index = best_domain;
630 return 0;
631 }
632 return -ENODEV;
633}
634
635/**
636 * Find the device type if query queue returned a device type of 0.
637 * @ap_dev: pointer to the AP device.
638 */
639static int ap_probe_device_type(struct ap_device *ap_dev)
640{
641 static unsigned char msg[] = {
642 0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
643 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
644 0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,
645 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
646 0x01,0x00,0x43,0x43,0x41,0x2d,0x41,0x50,
647 0x50,0x4c,0x20,0x20,0x20,0x01,0x01,0x01,
648 0x00,0x00,0x00,0x00,0x50,0x4b,0x00,0x00,
649 0x00,0x00,0x01,0x1c,0x00,0x00,0x00,0x00,
650 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
651 0x00,0x00,0x05,0xb8,0x00,0x00,0x00,0x00,
652 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
653 0x70,0x00,0x41,0x00,0x00,0x00,0x00,0x00,
654 0x00,0x00,0x54,0x32,0x01,0x00,0xa0,0x00,
655 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
656 0x00,0x00,0x00,0x00,0xb8,0x05,0x00,0x00,
657 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
658 0x00,0x00,0x00,0x00,0x00,0x00,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,0x0a,0x00,0x00,0x00,0x00,0x00,
664 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
665 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,
666 0x49,0x43,0x53,0x46,0x20,0x20,0x20,0x20,
667 0x50,0x4b,0x0a,0x00,0x50,0x4b,0x43,0x53,
668 0x2d,0x31,0x2e,0x32,0x37,0x00,0x11,0x22,
669 0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,
670 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,
671 0x99,0x00,0x11,0x22,0x33,0x44,0x55,0x66,
672 0x77,0x88,0x99,0x00,0x11,0x22,0x33,0x44,
673 0x55,0x66,0x77,0x88,0x99,0x00,0x11,0x22,
674 0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,
675 0x11,0x22,0x33,0x5d,0x00,0x5b,0x00,0x77,
676 0x88,0x1e,0x00,0x00,0x57,0x00,0x00,0x00,
677 0x00,0x04,0x00,0x00,0x4f,0x00,0x00,0x00,
678 0x03,0x02,0x00,0x00,0x40,0x01,0x00,0x01,
679 0xce,0x02,0x68,0x2d,0x5f,0xa9,0xde,0x0c,
680 0xf6,0xd2,0x7b,0x58,0x4b,0xf9,0x28,0x68,
681 0x3d,0xb4,0xf4,0xef,0x78,0xd5,0xbe,0x66,
682 0x63,0x42,0xef,0xf8,0xfd,0xa4,0xf8,0xb0,
683 0x8e,0x29,0xc2,0xc9,0x2e,0xd8,0x45,0xb8,
684 0x53,0x8c,0x6f,0x4e,0x72,0x8f,0x6c,0x04,
685 0x9c,0x88,0xfc,0x1e,0xc5,0x83,0x55,0x57,
686 0xf7,0xdd,0xfd,0x4f,0x11,0x36,0x95,0x5d,
687 };
688 struct ap_queue_status status;
689 unsigned long long psmid;
690 char *reply;
691 int rc, i;
692
693 reply = (void *) get_zeroed_page(GFP_KERNEL);
694 if (!reply) {
695 rc = -ENOMEM;
696 goto out;
697 }
698
699 status = __ap_send(ap_dev->qid, 0x0102030405060708ULL,
700 msg, sizeof(msg));
701 if (status.response_code != AP_RESPONSE_NORMAL) {
702 rc = -ENODEV;
703 goto out_free;
704 }
705
706 /* Wait for the test message to complete. */
707 for (i = 0; i < 6; i++) {
708 mdelay(300);
709 status = __ap_recv(ap_dev->qid, &psmid, reply, 4096);
710 if (status.response_code == AP_RESPONSE_NORMAL &&
711 psmid == 0x0102030405060708ULL)
712 break;
713 }
714 if (i < 6) {
715 /* Got an answer. */
716 if (reply[0] == 0x00 && reply[1] == 0x86)
717 ap_dev->device_type = AP_DEVICE_TYPE_PCICC;
718 else
719 ap_dev->device_type = AP_DEVICE_TYPE_PCICA;
720 rc = 0;
721 } else
722 rc = -ENODEV;
723
724out_free:
725 free_page((unsigned long) reply);
726out:
727 return rc;
728}
729
730/**
731 * Scan the ap bus for new devices.
732 */
733static int __ap_scan_bus(struct device *dev, void *data)
734{
735 return to_ap_dev(dev)->qid == (ap_qid_t)(unsigned long) data;
736}
737
738static void ap_device_release(struct device *dev)
739{
740 struct ap_device *ap_dev = to_ap_dev(dev);
741
742 kfree(ap_dev);
743}
744
Al Viro4927b3f2006-12-06 19:18:20 +0000745static void ap_scan_bus(struct work_struct *unused)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200746{
747 struct ap_device *ap_dev;
748 struct device *dev;
749 ap_qid_t qid;
750 int queue_depth, device_type;
751 int rc, i;
752
753 if (ap_select_domain() != 0)
754 return;
755 for (i = 0; i < AP_DEVICES; i++) {
756 qid = AP_MKQID(i, ap_domain_index);
757 dev = bus_find_device(&ap_bus_type, NULL,
758 (void *)(unsigned long)qid,
759 __ap_scan_bus);
Ralph Wuerthnerf3b017d2006-10-27 12:39:26 +0200760 rc = ap_query_queue(qid, &queue_depth, &device_type);
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +0200761 if (dev) {
762 ap_dev = to_ap_dev(dev);
763 spin_lock_bh(&ap_dev->lock);
764 if (rc || ap_dev->unregistered) {
765 spin_unlock_bh(&ap_dev->lock);
766 put_device(dev);
767 device_unregister(dev);
768 continue;
769 } else
770 spin_unlock_bh(&ap_dev->lock);
Ralph Wuerthnerf3b017d2006-10-27 12:39:26 +0200771 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200772 if (dev) {
773 put_device(dev);
774 continue;
775 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200776 if (rc)
777 continue;
778 rc = ap_init_queue(qid);
779 if (rc)
780 continue;
781 ap_dev = kzalloc(sizeof(*ap_dev), GFP_KERNEL);
782 if (!ap_dev)
783 break;
784 ap_dev->qid = qid;
785 ap_dev->queue_depth = queue_depth;
Ralph Wuerthner4e562962006-10-04 20:02:05 +0200786 ap_dev->unregistered = 1;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200787 spin_lock_init(&ap_dev->lock);
788 INIT_LIST_HEAD(&ap_dev->pendingq);
789 INIT_LIST_HEAD(&ap_dev->requestq);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +0100790 INIT_LIST_HEAD(&ap_dev->list);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200791 if (device_type == 0)
792 ap_probe_device_type(ap_dev);
793 else
794 ap_dev->device_type = device_type;
795
796 ap_dev->device.bus = &ap_bus_type;
797 ap_dev->device.parent = ap_root_device;
798 snprintf(ap_dev->device.bus_id, BUS_ID_SIZE, "card%02x",
799 AP_QID_DEVICE(ap_dev->qid));
800 ap_dev->device.release = ap_device_release;
801 rc = device_register(&ap_dev->device);
802 if (rc) {
803 kfree(ap_dev);
804 continue;
805 }
806 /* Add device attributes. */
807 rc = sysfs_create_group(&ap_dev->device.kobj,
808 &ap_dev_attr_group);
Ralph Wuerthner4e562962006-10-04 20:02:05 +0200809 if (!rc) {
810 spin_lock_bh(&ap_dev->lock);
811 ap_dev->unregistered = 0;
812 spin_unlock_bh(&ap_dev->lock);
813 }
814 else
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200815 device_unregister(&ap_dev->device);
816 }
817}
818
819static void
820ap_config_timeout(unsigned long ptr)
821{
822 queue_work(ap_work_queue, &ap_config_work);
823 ap_config_timer.expires = jiffies + ap_config_time * HZ;
824 add_timer(&ap_config_timer);
825}
826
827/**
828 * Set up the timer to run the poll tasklet
829 */
830static inline void ap_schedule_poll_timer(void)
831{
832 if (timer_pending(&ap_poll_timer))
833 return;
834 mod_timer(&ap_poll_timer, jiffies + AP_POLL_TIME);
835}
836
837/**
838 * Receive pending reply messages from an AP device.
839 * @ap_dev: pointer to the AP device
840 * @flags: pointer to control flags, bit 2^0 is set if another poll is
841 * required, bit 2^1 is set if the poll timer needs to get armed
842 * Returns 0 if the device is still present, -ENODEV if not.
843 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +0100844static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200845{
846 struct ap_queue_status status;
847 struct ap_message *ap_msg;
848
849 if (ap_dev->queue_count <= 0)
850 return 0;
851 status = __ap_recv(ap_dev->qid, &ap_dev->reply->psmid,
852 ap_dev->reply->message, ap_dev->reply->length);
853 switch (status.response_code) {
854 case AP_RESPONSE_NORMAL:
855 atomic_dec(&ap_poll_requests);
856 ap_dev->queue_count--;
857 list_for_each_entry(ap_msg, &ap_dev->pendingq, list) {
858 if (ap_msg->psmid != ap_dev->reply->psmid)
859 continue;
860 list_del_init(&ap_msg->list);
861 ap_dev->pendingq_count--;
862 ap_dev->drv->receive(ap_dev, ap_msg, ap_dev->reply);
863 break;
864 }
865 if (ap_dev->queue_count > 0)
866 *flags |= 1;
867 break;
868 case AP_RESPONSE_NO_PENDING_REPLY:
869 if (status.queue_empty) {
870 /* The card shouldn't forget requests but who knows. */
Ralph Wuerthnere675c0d2007-03-26 20:42:43 +0200871 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200872 ap_dev->queue_count = 0;
873 list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
874 ap_dev->requestq_count += ap_dev->pendingq_count;
875 ap_dev->pendingq_count = 0;
876 } else
877 *flags |= 2;
878 break;
879 default:
880 return -ENODEV;
881 }
882 return 0;
883}
884
885/**
886 * Send messages from the request queue to an AP device.
887 * @ap_dev: pointer to the AP device
888 * @flags: pointer to control flags, bit 2^0 is set if another poll is
889 * required, bit 2^1 is set if the poll timer needs to get armed
890 * Returns 0 if the device is still present, -ENODEV if not.
891 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +0100892static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200893{
894 struct ap_queue_status status;
895 struct ap_message *ap_msg;
896
897 if (ap_dev->requestq_count <= 0 ||
898 ap_dev->queue_count >= ap_dev->queue_depth)
899 return 0;
900 /* Start the next request on the queue. */
901 ap_msg = list_entry(ap_dev->requestq.next, struct ap_message, list);
902 status = __ap_send(ap_dev->qid, ap_msg->psmid,
903 ap_msg->message, ap_msg->length);
904 switch (status.response_code) {
905 case AP_RESPONSE_NORMAL:
906 atomic_inc(&ap_poll_requests);
907 ap_dev->queue_count++;
908 list_move_tail(&ap_msg->list, &ap_dev->pendingq);
909 ap_dev->requestq_count--;
910 ap_dev->pendingq_count++;
911 if (ap_dev->queue_count < ap_dev->queue_depth &&
912 ap_dev->requestq_count > 0)
913 *flags |= 1;
914 *flags |= 2;
915 break;
916 case AP_RESPONSE_Q_FULL:
917 *flags |= 2;
918 break;
919 case AP_RESPONSE_MESSAGE_TOO_BIG:
920 return -EINVAL;
921 default:
922 return -ENODEV;
923 }
924 return 0;
925}
926
927/**
928 * Poll AP device for pending replies and send new messages. If either
929 * ap_poll_read or ap_poll_write returns -ENODEV unregister the device.
930 * @ap_dev: pointer to the bus device
931 * @flags: pointer to control flags, bit 2^0 is set if another poll is
932 * required, bit 2^1 is set if the poll timer needs to get armed
933 * Returns 0.
934 */
935static inline int ap_poll_queue(struct ap_device *ap_dev, unsigned long *flags)
936{
937 int rc;
938
939 rc = ap_poll_read(ap_dev, flags);
940 if (rc)
941 return rc;
942 return ap_poll_write(ap_dev, flags);
943}
944
945/**
946 * Queue a message to a device.
947 * @ap_dev: pointer to the AP device
948 * @ap_msg: the message to be queued
949 */
950static int __ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
951{
952 struct ap_queue_status status;
953
954 if (list_empty(&ap_dev->requestq) &&
955 ap_dev->queue_count < ap_dev->queue_depth) {
956 status = __ap_send(ap_dev->qid, ap_msg->psmid,
957 ap_msg->message, ap_msg->length);
958 switch (status.response_code) {
959 case AP_RESPONSE_NORMAL:
960 list_add_tail(&ap_msg->list, &ap_dev->pendingq);
961 atomic_inc(&ap_poll_requests);
962 ap_dev->pendingq_count++;
963 ap_dev->queue_count++;
964 ap_dev->total_request_count++;
965 break;
966 case AP_RESPONSE_Q_FULL:
967 list_add_tail(&ap_msg->list, &ap_dev->requestq);
968 ap_dev->requestq_count++;
969 ap_dev->total_request_count++;
970 return -EBUSY;
971 case AP_RESPONSE_MESSAGE_TOO_BIG:
972 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL));
973 return -EINVAL;
974 default: /* Device is gone. */
975 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
976 return -ENODEV;
977 }
978 } else {
979 list_add_tail(&ap_msg->list, &ap_dev->requestq);
980 ap_dev->requestq_count++;
981 ap_dev->total_request_count++;
982 return -EBUSY;
983 }
984 ap_schedule_poll_timer();
985 return 0;
986}
987
988void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
989{
990 unsigned long flags;
991 int rc;
992
993 spin_lock_bh(&ap_dev->lock);
994 if (!ap_dev->unregistered) {
995 /* Make room on the queue by polling for finished requests. */
996 rc = ap_poll_queue(ap_dev, &flags);
997 if (!rc)
998 rc = __ap_queue_message(ap_dev, ap_msg);
999 if (!rc)
1000 wake_up(&ap_poll_wait);
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001001 if (rc == -ENODEV)
1002 ap_dev->unregistered = 1;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001003 } else {
1004 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001005 rc = -ENODEV;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001006 }
1007 spin_unlock_bh(&ap_dev->lock);
1008 if (rc == -ENODEV)
1009 device_unregister(&ap_dev->device);
1010}
1011EXPORT_SYMBOL(ap_queue_message);
1012
1013/**
1014 * Cancel a crypto request. This is done by removing the request
1015 * from the devive pendingq or requestq queue. Note that the
1016 * request stays on the AP queue. When it finishes the message
1017 * reply will be discarded because the psmid can't be found.
1018 * @ap_dev: AP device that has the message queued
1019 * @ap_msg: the message that is to be removed
1020 */
1021void ap_cancel_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
1022{
1023 struct ap_message *tmp;
1024
1025 spin_lock_bh(&ap_dev->lock);
1026 if (!list_empty(&ap_msg->list)) {
1027 list_for_each_entry(tmp, &ap_dev->pendingq, list)
1028 if (tmp->psmid == ap_msg->psmid) {
1029 ap_dev->pendingq_count--;
1030 goto found;
1031 }
1032 ap_dev->requestq_count--;
1033 found:
1034 list_del_init(&ap_msg->list);
1035 }
1036 spin_unlock_bh(&ap_dev->lock);
1037}
1038EXPORT_SYMBOL(ap_cancel_message);
1039
1040/**
1041 * AP receive polling for finished AP requests
1042 */
1043static void ap_poll_timeout(unsigned long unused)
1044{
1045 tasklet_schedule(&ap_tasklet);
1046}
1047
1048/**
1049 * Poll all AP devices on the bus in a round robin fashion. Continue
1050 * polling until bit 2^0 of the control flags is not set. If bit 2^1
1051 * of the control flags has been set arm the poll timer.
1052 */
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001053static int __ap_poll_all(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001054{
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001055 spin_lock(&ap_dev->lock);
1056 if (!ap_dev->unregistered) {
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001057 if (ap_poll_queue(ap_dev, flags))
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001058 ap_dev->unregistered = 1;
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001059 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001060 spin_unlock(&ap_dev->lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001061 return 0;
1062}
1063
1064static void ap_poll_all(unsigned long dummy)
1065{
1066 unsigned long flags;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001067 struct ap_device *ap_dev;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001068
1069 do {
1070 flags = 0;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001071 spin_lock(&ap_device_lock);
1072 list_for_each_entry(ap_dev, &ap_device_list, list) {
1073 __ap_poll_all(ap_dev, &flags);
1074 }
1075 spin_unlock(&ap_device_lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001076 } while (flags & 1);
1077 if (flags & 2)
1078 ap_schedule_poll_timer();
1079}
1080
1081/**
1082 * AP bus poll thread. The purpose of this thread is to poll for
1083 * finished requests in a loop if there is a "free" cpu - that is
1084 * a cpu that doesn't have anything better to do. The polling stops
1085 * as soon as there is another task or if all messages have been
1086 * delivered.
1087 */
1088static int ap_poll_thread(void *data)
1089{
1090 DECLARE_WAITQUEUE(wait, current);
1091 unsigned long flags;
1092 int requests;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001093 struct ap_device *ap_dev;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001094
Christian Borntraegerd83682b2006-10-06 16:38:22 +02001095 set_user_nice(current, 19);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001096 while (1) {
1097 if (need_resched()) {
1098 schedule();
1099 continue;
1100 }
1101 add_wait_queue(&ap_poll_wait, &wait);
1102 set_current_state(TASK_INTERRUPTIBLE);
1103 if (kthread_should_stop())
1104 break;
1105 requests = atomic_read(&ap_poll_requests);
1106 if (requests <= 0)
1107 schedule();
1108 set_current_state(TASK_RUNNING);
1109 remove_wait_queue(&ap_poll_wait, &wait);
1110
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001111 flags = 0;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001112 spin_lock_bh(&ap_device_lock);
1113 list_for_each_entry(ap_dev, &ap_device_list, list) {
1114 __ap_poll_all(ap_dev, &flags);
1115 }
1116 spin_unlock_bh(&ap_device_lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001117 }
1118 set_current_state(TASK_RUNNING);
1119 remove_wait_queue(&ap_poll_wait, &wait);
1120 return 0;
1121}
1122
1123static int ap_poll_thread_start(void)
1124{
1125 int rc;
1126
1127 mutex_lock(&ap_poll_thread_mutex);
1128 if (!ap_poll_kthread) {
1129 ap_poll_kthread = kthread_run(ap_poll_thread, NULL, "appoll");
1130 rc = IS_ERR(ap_poll_kthread) ? PTR_ERR(ap_poll_kthread) : 0;
1131 if (rc)
1132 ap_poll_kthread = NULL;
1133 }
1134 else
1135 rc = 0;
1136 mutex_unlock(&ap_poll_thread_mutex);
1137 return rc;
1138}
1139
1140static void ap_poll_thread_stop(void)
1141{
1142 mutex_lock(&ap_poll_thread_mutex);
1143 if (ap_poll_kthread) {
1144 kthread_stop(ap_poll_kthread);
1145 ap_poll_kthread = NULL;
1146 }
1147 mutex_unlock(&ap_poll_thread_mutex);
1148}
1149
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001150static void ap_reset_domain(void)
1151{
1152 int i;
1153
1154 for (i = 0; i < AP_DEVICES; i++)
1155 ap_reset_queue(AP_MKQID(i, ap_domain_index));
1156}
1157
1158static void ap_reset_all(void)
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001159{
1160 int i, j;
1161
1162 for (i = 0; i < AP_DOMAINS; i++)
1163 for (j = 0; j < AP_DEVICES; j++)
1164 ap_reset_queue(AP_MKQID(j, i));
1165}
1166
1167static struct reset_call ap_reset_call = {
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001168 .fn = ap_reset_all,
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001169};
1170
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001171/**
1172 * The module initialization code.
1173 */
1174int __init ap_module_init(void)
1175{
1176 int rc, i;
1177
1178 if (ap_domain_index < -1 || ap_domain_index >= AP_DOMAINS) {
1179 printk(KERN_WARNING "Invalid param: domain = %d. "
1180 " Not loading.\n", ap_domain_index);
1181 return -EINVAL;
1182 }
1183 if (ap_instructions_available() != 0) {
1184 printk(KERN_WARNING "AP instructions not installed.\n");
1185 return -ENODEV;
1186 }
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001187 register_reset_call(&ap_reset_call);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001188
1189 /* Create /sys/bus/ap. */
1190 rc = bus_register(&ap_bus_type);
1191 if (rc)
1192 goto out;
1193 for (i = 0; ap_bus_attrs[i]; i++) {
1194 rc = bus_create_file(&ap_bus_type, ap_bus_attrs[i]);
1195 if (rc)
1196 goto out_bus;
1197 }
1198
1199 /* Create /sys/devices/ap. */
1200 ap_root_device = s390_root_dev_register("ap");
1201 rc = IS_ERR(ap_root_device) ? PTR_ERR(ap_root_device) : 0;
1202 if (rc)
1203 goto out_bus;
1204
1205 ap_work_queue = create_singlethread_workqueue("kapwork");
1206 if (!ap_work_queue) {
1207 rc = -ENOMEM;
1208 goto out_root;
1209 }
1210
1211 if (ap_select_domain() == 0)
1212 ap_scan_bus(NULL);
1213
1214 /* Setup the ap bus rescan timer. */
1215 init_timer(&ap_config_timer);
1216 ap_config_timer.function = ap_config_timeout;
1217 ap_config_timer.data = 0;
1218 ap_config_timer.expires = jiffies + ap_config_time * HZ;
1219 add_timer(&ap_config_timer);
1220
1221 /* Start the low priority AP bus poll thread. */
1222 if (ap_thread_flag) {
1223 rc = ap_poll_thread_start();
1224 if (rc)
1225 goto out_work;
1226 }
1227
1228 return 0;
1229
1230out_work:
1231 del_timer_sync(&ap_config_timer);
1232 del_timer_sync(&ap_poll_timer);
1233 destroy_workqueue(ap_work_queue);
1234out_root:
1235 s390_root_dev_unregister(ap_root_device);
1236out_bus:
1237 while (i--)
1238 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
1239 bus_unregister(&ap_bus_type);
1240out:
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001241 unregister_reset_call(&ap_reset_call);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001242 return rc;
1243}
1244
1245static int __ap_match_all(struct device *dev, void *data)
1246{
1247 return 1;
1248}
1249
1250/**
1251 * The module termination code
1252 */
1253void ap_module_exit(void)
1254{
1255 int i;
1256 struct device *dev;
1257
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001258 ap_reset_domain();
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001259 ap_poll_thread_stop();
1260 del_timer_sync(&ap_config_timer);
1261 del_timer_sync(&ap_poll_timer);
1262 destroy_workqueue(ap_work_queue);
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001263 tasklet_kill(&ap_tasklet);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001264 s390_root_dev_unregister(ap_root_device);
1265 while ((dev = bus_find_device(&ap_bus_type, NULL, NULL,
1266 __ap_match_all)))
1267 {
1268 device_unregister(dev);
1269 put_device(dev);
1270 }
1271 for (i = 0; ap_bus_attrs[i]; i++)
1272 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
1273 bus_unregister(&ap_bus_type);
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001274 unregister_reset_call(&ap_reset_call);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001275}
1276
1277#ifndef CONFIG_ZCRYPT_MONOLITHIC
1278module_init(ap_module_init);
1279module_exit(ap_module_exit);
1280#endif