blob: 326db1e827c4dbe41f70419a9af53b1a997a7e7a [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>
Felix Beckfe137232008-07-14 09:59:08 +020037#include <linux/hrtimer.h>
38#include <linux/ktime.h>
Martin Schwidefsky1534c382006-09-20 15:58:25 +020039
40#include "ap_bus.h"
41
42/* Some prototypes. */
Al Viro4927b3f2006-12-06 19:18:20 +000043static void ap_scan_bus(struct work_struct *);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020044static void ap_poll_all(unsigned long);
Felix Beckfe137232008-07-14 09:59:08 +020045static enum hrtimer_restart ap_poll_timeout(struct hrtimer *);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020046static int ap_poll_thread_start(void);
47static void ap_poll_thread_stop(void);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +020048static void ap_request_timeout(unsigned long);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020049
Felix Beck1749a812008-04-17 07:46:28 +020050/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +020051 * Module description.
52 */
53MODULE_AUTHOR("IBM Corporation");
54MODULE_DESCRIPTION("Adjunct Processor Bus driver, "
55 "Copyright 2006 IBM Corporation");
56MODULE_LICENSE("GPL");
57
Felix Beck1749a812008-04-17 07:46:28 +020058/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +020059 * Module parameter
60 */
61int ap_domain_index = -1; /* Adjunct Processor Domain Index */
62module_param_named(domain, ap_domain_index, int, 0000);
63MODULE_PARM_DESC(domain, "domain index for ap devices");
64EXPORT_SYMBOL(ap_domain_index);
65
Felix Beckb90b34c2008-02-09 18:24:30 +010066static int ap_thread_flag = 0;
Martin Schwidefsky1534c382006-09-20 15:58:25 +020067module_param_named(poll_thread, ap_thread_flag, int, 0000);
Felix Beckb90b34c2008-02-09 18:24:30 +010068MODULE_PARM_DESC(poll_thread, "Turn on/off poll thread, default is 0 (off).");
Martin Schwidefsky1534c382006-09-20 15:58:25 +020069
70static struct device *ap_root_device = NULL;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +010071static DEFINE_SPINLOCK(ap_device_lock);
72static LIST_HEAD(ap_device_list);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020073
Felix Beck1749a812008-04-17 07:46:28 +020074/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +020075 * Workqueue & timer for bus rescan.
76 */
77static struct workqueue_struct *ap_work_queue;
78static struct timer_list ap_config_timer;
79static int ap_config_time = AP_CONFIG_TIME;
Al Viro4927b3f2006-12-06 19:18:20 +000080static DECLARE_WORK(ap_config_work, ap_scan_bus);
Martin Schwidefsky1534c382006-09-20 15:58:25 +020081
Felix Beck1749a812008-04-17 07:46:28 +020082/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +020083 * Tasklet & timer for AP request polling.
84 */
Martin Schwidefsky1534c382006-09-20 15:58:25 +020085static DECLARE_TASKLET(ap_tasklet, ap_poll_all, 0);
86static atomic_t ap_poll_requests = ATOMIC_INIT(0);
87static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait);
88static struct task_struct *ap_poll_kthread = NULL;
89static DEFINE_MUTEX(ap_poll_thread_mutex);
Felix Beckfe137232008-07-14 09:59:08 +020090static struct hrtimer ap_poll_timer;
91/* In LPAR poll with 4kHz frequency. Poll every 250000 nanoseconds.
92 * If z/VM change to 1500000 nanoseconds to adjust to z/VM polling.*/
93static unsigned long long poll_timeout = 250000;
Martin Schwidefsky1534c382006-09-20 15:58:25 +020094
95/**
Felix Beck1749a812008-04-17 07:46:28 +020096 * ap_intructions_available() - Test if AP instructions are available.
Martin Schwidefsky1534c382006-09-20 15:58:25 +020097 *
Felix Beck1749a812008-04-17 07:46:28 +020098 * Returns 0 if the AP instructions are installed.
Martin Schwidefsky1534c382006-09-20 15:58:25 +020099 */
100static inline int ap_instructions_available(void)
101{
102 register unsigned long reg0 asm ("0") = AP_MKQID(0,0);
103 register unsigned long reg1 asm ("1") = -ENODEV;
104 register unsigned long reg2 asm ("2") = 0UL;
105
106 asm volatile(
107 " .long 0xb2af0000\n" /* PQAP(TAPQ) */
108 "0: la %1,0\n"
109 "1:\n"
110 EX_TABLE(0b, 1b)
111 : "+d" (reg0), "+d" (reg1), "+d" (reg2) : : "cc" );
112 return reg1;
113}
114
115/**
Felix Beck1749a812008-04-17 07:46:28 +0200116 * ap_test_queue(): Test adjunct processor queue.
117 * @qid: The AP queue number
118 * @queue_depth: Pointer to queue depth value
119 * @device_type: Pointer to device type value
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200120 *
Felix Beck1749a812008-04-17 07:46:28 +0200121 * Returns AP queue status structure.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200122 */
123static inline struct ap_queue_status
124ap_test_queue(ap_qid_t qid, int *queue_depth, int *device_type)
125{
126 register unsigned long reg0 asm ("0") = qid;
127 register struct ap_queue_status reg1 asm ("1");
128 register unsigned long reg2 asm ("2") = 0UL;
129
130 asm volatile(".long 0xb2af0000" /* PQAP(TAPQ) */
131 : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
132 *device_type = (int) (reg2 >> 24);
133 *queue_depth = (int) (reg2 & 0xff);
134 return reg1;
135}
136
137/**
Felix Beck1749a812008-04-17 07:46:28 +0200138 * ap_reset_queue(): Reset adjunct processor queue.
139 * @qid: The AP queue number
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200140 *
Felix Beck1749a812008-04-17 07:46:28 +0200141 * Returns AP queue status structure.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200142 */
143static inline struct ap_queue_status ap_reset_queue(ap_qid_t qid)
144{
145 register unsigned long reg0 asm ("0") = qid | 0x01000000UL;
146 register struct ap_queue_status reg1 asm ("1");
147 register unsigned long reg2 asm ("2") = 0UL;
148
149 asm volatile(
150 ".long 0xb2af0000" /* PQAP(RAPQ) */
151 : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
152 return reg1;
153}
154
155/**
Felix Beck1749a812008-04-17 07:46:28 +0200156 * __ap_send(): Send message to adjunct processor queue.
157 * @qid: The AP queue number
158 * @psmid: The program supplied message identifier
159 * @msg: The message text
160 * @length: The message length
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200161 *
Felix Beck1749a812008-04-17 07:46:28 +0200162 * Returns AP queue status structure.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200163 * Condition code 1 on NQAP can't happen because the L bit is 1.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200164 * Condition code 2 on NQAP also means the send is incomplete,
165 * because a segment boundary was reached. The NQAP is repeated.
166 */
167static inline struct ap_queue_status
168__ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length)
169{
170 typedef struct { char _[length]; } msgblock;
171 register unsigned long reg0 asm ("0") = qid | 0x40000000UL;
172 register struct ap_queue_status reg1 asm ("1");
173 register unsigned long reg2 asm ("2") = (unsigned long) msg;
174 register unsigned long reg3 asm ("3") = (unsigned long) length;
175 register unsigned long reg4 asm ("4") = (unsigned int) (psmid >> 32);
176 register unsigned long reg5 asm ("5") = (unsigned int) psmid;
177
178 asm volatile (
179 "0: .long 0xb2ad0042\n" /* DQAP */
180 " brc 2,0b"
181 : "+d" (reg0), "=d" (reg1), "+d" (reg2), "+d" (reg3)
182 : "d" (reg4), "d" (reg5), "m" (*(msgblock *) msg)
183 : "cc" );
184 return reg1;
185}
186
187int ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length)
188{
189 struct ap_queue_status status;
190
191 status = __ap_send(qid, psmid, msg, length);
192 switch (status.response_code) {
193 case AP_RESPONSE_NORMAL:
194 return 0;
195 case AP_RESPONSE_Q_FULL:
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200196 case AP_RESPONSE_RESET_IN_PROGRESS:
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200197 return -EBUSY;
198 default: /* Device is gone. */
199 return -ENODEV;
200 }
201}
202EXPORT_SYMBOL(ap_send);
203
Felix Beck1749a812008-04-17 07:46:28 +0200204/**
205 * __ap_recv(): Receive message from adjunct processor queue.
206 * @qid: The AP queue number
207 * @psmid: Pointer to program supplied message identifier
208 * @msg: The message text
209 * @length: The message length
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200210 *
Felix Beck1749a812008-04-17 07:46:28 +0200211 * Returns AP queue status structure.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200212 * Condition code 1 on DQAP means the receive has taken place
213 * but only partially. The response is incomplete, hence the
214 * DQAP is repeated.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200215 * Condition code 2 on DQAP also means the receive is incomplete,
216 * this time because a segment boundary was reached. Again, the
217 * DQAP is repeated.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200218 * 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/**
Felix Beck1749a812008-04-17 07:46:28 +0200266 * ap_query_queue(): Check if an AP queue is available.
267 * @qid: The AP queue number
268 * @queue_depth: Pointer to queue depth value
269 * @device_type: Pointer to device type value
270 *
271 * The test is repeated for AP_MAX_RESET times.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200272 */
273static int ap_query_queue(ap_qid_t qid, int *queue_depth, int *device_type)
274{
275 struct ap_queue_status status;
276 int t_depth, t_device_type, rc, i;
277
278 rc = -EBUSY;
279 for (i = 0; i < AP_MAX_RESET; i++) {
280 status = ap_test_queue(qid, &t_depth, &t_device_type);
281 switch (status.response_code) {
282 case AP_RESPONSE_NORMAL:
283 *queue_depth = t_depth + 1;
284 *device_type = t_device_type;
285 rc = 0;
286 break;
287 case AP_RESPONSE_Q_NOT_AVAIL:
288 rc = -ENODEV;
289 break;
290 case AP_RESPONSE_RESET_IN_PROGRESS:
291 break;
292 case AP_RESPONSE_DECONFIGURED:
293 rc = -ENODEV;
294 break;
295 case AP_RESPONSE_CHECKSTOPPED:
296 rc = -ENODEV;
297 break;
298 case AP_RESPONSE_BUSY:
299 break;
300 default:
301 BUG();
302 }
303 if (rc != -EBUSY)
304 break;
305 if (i < AP_MAX_RESET - 1)
306 udelay(5);
307 }
308 return rc;
309}
310
311/**
Felix Beck1749a812008-04-17 07:46:28 +0200312 * ap_init_queue(): Reset an AP queue.
313 * @qid: The AP queue number
314 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200315 * Reset an AP queue and wait for it to become available again.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200316 */
317static int ap_init_queue(ap_qid_t qid)
318{
319 struct ap_queue_status status;
320 int rc, dummy, i;
321
322 rc = -ENODEV;
323 status = ap_reset_queue(qid);
324 for (i = 0; i < AP_MAX_RESET; i++) {
325 switch (status.response_code) {
326 case AP_RESPONSE_NORMAL:
327 if (status.queue_empty)
328 rc = 0;
329 break;
330 case AP_RESPONSE_Q_NOT_AVAIL:
331 case AP_RESPONSE_DECONFIGURED:
332 case AP_RESPONSE_CHECKSTOPPED:
333 i = AP_MAX_RESET; /* return with -ENODEV */
334 break;
335 case AP_RESPONSE_RESET_IN_PROGRESS:
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200336 rc = -EBUSY;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200337 case AP_RESPONSE_BUSY:
338 default:
339 break;
340 }
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200341 if (rc != -ENODEV && rc != -EBUSY)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200342 break;
343 if (i < AP_MAX_RESET - 1) {
344 udelay(5);
345 status = ap_test_queue(qid, &dummy, &dummy);
346 }
347 }
348 return rc;
349}
350
351/**
Felix Beck1749a812008-04-17 07:46:28 +0200352 * ap_increase_queue_count(): Arm request timeout.
353 * @ap_dev: Pointer to an AP device.
354 *
355 * Arm request timeout if an AP device was idle and a new request is submitted.
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200356 */
357static void ap_increase_queue_count(struct ap_device *ap_dev)
358{
359 int timeout = ap_dev->drv->request_timeout;
360
361 ap_dev->queue_count++;
362 if (ap_dev->queue_count == 1) {
363 mod_timer(&ap_dev->timeout, jiffies + timeout);
364 ap_dev->reset = AP_RESET_ARMED;
365 }
366}
367
368/**
Felix Beck1749a812008-04-17 07:46:28 +0200369 * ap_decrease_queue_count(): Decrease queue count.
370 * @ap_dev: Pointer to an AP device.
371 *
372 * If AP device is still alive, re-schedule request timeout if there are still
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200373 * pending requests.
374 */
375static void ap_decrease_queue_count(struct ap_device *ap_dev)
376{
377 int timeout = ap_dev->drv->request_timeout;
378
379 ap_dev->queue_count--;
380 if (ap_dev->queue_count > 0)
381 mod_timer(&ap_dev->timeout, jiffies + timeout);
382 else
Felix Beck1749a812008-04-17 07:46:28 +0200383 /*
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200384 * The timeout timer should to be disabled now - since
385 * del_timer_sync() is very expensive, we just tell via the
386 * reset flag to ignore the pending timeout timer.
387 */
388 ap_dev->reset = AP_RESET_IGNORE;
389}
390
Felix Beck1749a812008-04-17 07:46:28 +0200391/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200392 * AP device related attributes.
393 */
394static ssize_t ap_hwtype_show(struct device *dev,
395 struct device_attribute *attr, char *buf)
396{
397 struct ap_device *ap_dev = to_ap_dev(dev);
398 return snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->device_type);
399}
400static DEVICE_ATTR(hwtype, 0444, ap_hwtype_show, NULL);
401
402static ssize_t ap_depth_show(struct device *dev, struct device_attribute *attr,
403 char *buf)
404{
405 struct ap_device *ap_dev = to_ap_dev(dev);
406 return snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->queue_depth);
407}
408static DEVICE_ATTR(depth, 0444, ap_depth_show, NULL);
409
410static ssize_t ap_request_count_show(struct device *dev,
411 struct device_attribute *attr,
412 char *buf)
413{
414 struct ap_device *ap_dev = to_ap_dev(dev);
415 int rc;
416
417 spin_lock_bh(&ap_dev->lock);
418 rc = snprintf(buf, PAGE_SIZE, "%d\n", ap_dev->total_request_count);
419 spin_unlock_bh(&ap_dev->lock);
420 return rc;
421}
422
423static DEVICE_ATTR(request_count, 0444, ap_request_count_show, NULL);
424
425static ssize_t ap_modalias_show(struct device *dev,
426 struct device_attribute *attr, char *buf)
427{
428 return sprintf(buf, "ap:t%02X", to_ap_dev(dev)->device_type);
429}
430
431static DEVICE_ATTR(modalias, 0444, ap_modalias_show, NULL);
432
433static struct attribute *ap_dev_attrs[] = {
434 &dev_attr_hwtype.attr,
435 &dev_attr_depth.attr,
436 &dev_attr_request_count.attr,
437 &dev_attr_modalias.attr,
438 NULL
439};
440static struct attribute_group ap_dev_attr_group = {
441 .attrs = ap_dev_attrs
442};
443
444/**
Felix Beck1749a812008-04-17 07:46:28 +0200445 * ap_bus_match()
446 * @dev: Pointer to device
447 * @drv: Pointer to device_driver
448 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200449 * AP bus driver registration/unregistration.
450 */
451static int ap_bus_match(struct device *dev, struct device_driver *drv)
452{
453 struct ap_device *ap_dev = to_ap_dev(dev);
454 struct ap_driver *ap_drv = to_ap_drv(drv);
455 struct ap_device_id *id;
456
Felix Beck1749a812008-04-17 07:46:28 +0200457 /*
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200458 * Compare device type of the device with the list of
459 * supported types of the device_driver.
460 */
461 for (id = ap_drv->ids; id->match_flags; id++) {
462 if ((id->match_flags & AP_DEVICE_ID_MATCH_DEVICE_TYPE) &&
463 (id->dev_type != ap_dev->device_type))
464 continue;
465 return 1;
466 }
467 return 0;
468}
469
470/**
Felix Beck1749a812008-04-17 07:46:28 +0200471 * ap_uevent(): Uevent function for AP devices.
472 * @dev: Pointer to device
473 * @env: Pointer to kobj_uevent_env
474 *
475 * It sets up a single environment variable DEV_TYPE which contains the
476 * hardware device type.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200477 */
Kay Sievers7eff2e72007-08-14 15:15:12 +0200478static int ap_uevent (struct device *dev, struct kobj_uevent_env *env)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200479{
480 struct ap_device *ap_dev = to_ap_dev(dev);
Kay Sievers7eff2e72007-08-14 15:15:12 +0200481 int retval = 0;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200482
483 if (!ap_dev)
484 return -ENODEV;
485
486 /* Set up DEV_TYPE environment variable. */
Kay Sievers7eff2e72007-08-14 15:15:12 +0200487 retval = add_uevent_var(env, "DEV_TYPE=%04X", ap_dev->device_type);
Eric Rannaudbf624562007-03-30 22:23:12 -0700488 if (retval)
489 return retval;
490
Cornelia Huck66a4263b2006-12-04 15:40:10 +0100491 /* Add MODALIAS= */
Kay Sievers7eff2e72007-08-14 15:15:12 +0200492 retval = add_uevent_var(env, "MODALIAS=ap:t%02X", ap_dev->device_type);
Eric Rannaudbf624562007-03-30 22:23:12 -0700493
Eric Rannaudbf624562007-03-30 22:23:12 -0700494 return retval;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200495}
496
497static struct bus_type ap_bus_type = {
498 .name = "ap",
499 .match = &ap_bus_match,
500 .uevent = &ap_uevent,
501};
502
503static int ap_device_probe(struct device *dev)
504{
505 struct ap_device *ap_dev = to_ap_dev(dev);
506 struct ap_driver *ap_drv = to_ap_drv(dev->driver);
507 int rc;
508
509 ap_dev->drv = ap_drv;
510 rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV;
Ralph Wuerthnerfaa582c2008-03-05 12:37:13 +0100511 if (!rc) {
512 spin_lock_bh(&ap_device_lock);
513 list_add(&ap_dev->list, &ap_device_list);
514 spin_unlock_bh(&ap_device_lock);
515 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200516 return rc;
517}
518
519/**
Felix Beck1749a812008-04-17 07:46:28 +0200520 * __ap_flush_queue(): Flush requests.
521 * @ap_dev: Pointer to the AP device
522 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200523 * Flush all requests from the request/pending queue of an AP device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200524 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +0100525static void __ap_flush_queue(struct ap_device *ap_dev)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200526{
527 struct ap_message *ap_msg, *next;
528
529 list_for_each_entry_safe(ap_msg, next, &ap_dev->pendingq, list) {
530 list_del_init(&ap_msg->list);
531 ap_dev->pendingq_count--;
532 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
533 }
534 list_for_each_entry_safe(ap_msg, next, &ap_dev->requestq, list) {
535 list_del_init(&ap_msg->list);
536 ap_dev->requestq_count--;
537 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
538 }
539}
540
541void ap_flush_queue(struct ap_device *ap_dev)
542{
543 spin_lock_bh(&ap_dev->lock);
544 __ap_flush_queue(ap_dev);
545 spin_unlock_bh(&ap_dev->lock);
546}
547EXPORT_SYMBOL(ap_flush_queue);
548
549static int ap_device_remove(struct device *dev)
550{
551 struct ap_device *ap_dev = to_ap_dev(dev);
552 struct ap_driver *ap_drv = ap_dev->drv;
553
Ralph Wuerthner4e562962006-10-04 20:02:05 +0200554 ap_flush_queue(ap_dev);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200555 del_timer_sync(&ap_dev->timeout);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +0100556 spin_lock_bh(&ap_device_lock);
557 list_del_init(&ap_dev->list);
558 spin_unlock_bh(&ap_device_lock);
Ralph Wuerthnerfaa582c2008-03-05 12:37:13 +0100559 if (ap_drv->remove)
560 ap_drv->remove(ap_dev);
Ralph Wuerthnere675c0d2007-03-26 20:42:43 +0200561 spin_lock_bh(&ap_dev->lock);
562 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
563 spin_unlock_bh(&ap_dev->lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200564 return 0;
565}
566
567int ap_driver_register(struct ap_driver *ap_drv, struct module *owner,
568 char *name)
569{
570 struct device_driver *drv = &ap_drv->driver;
571
572 drv->bus = &ap_bus_type;
573 drv->probe = ap_device_probe;
574 drv->remove = ap_device_remove;
575 drv->owner = owner;
576 drv->name = name;
577 return driver_register(drv);
578}
579EXPORT_SYMBOL(ap_driver_register);
580
581void ap_driver_unregister(struct ap_driver *ap_drv)
582{
583 driver_unregister(&ap_drv->driver);
584}
585EXPORT_SYMBOL(ap_driver_unregister);
586
Felix Beck1749a812008-04-17 07:46:28 +0200587/*
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200588 * AP bus attributes.
589 */
590static ssize_t ap_domain_show(struct bus_type *bus, char *buf)
591{
592 return snprintf(buf, PAGE_SIZE, "%d\n", ap_domain_index);
593}
594
595static BUS_ATTR(ap_domain, 0444, ap_domain_show, NULL);
596
597static ssize_t ap_config_time_show(struct bus_type *bus, char *buf)
598{
599 return snprintf(buf, PAGE_SIZE, "%d\n", ap_config_time);
600}
601
602static ssize_t ap_config_time_store(struct bus_type *bus,
603 const char *buf, size_t count)
604{
605 int time;
606
607 if (sscanf(buf, "%d\n", &time) != 1 || time < 5 || time > 120)
608 return -EINVAL;
609 ap_config_time = time;
610 if (!timer_pending(&ap_config_timer) ||
611 !mod_timer(&ap_config_timer, jiffies + ap_config_time * HZ)) {
612 ap_config_timer.expires = jiffies + ap_config_time * HZ;
613 add_timer(&ap_config_timer);
614 }
615 return count;
616}
617
618static BUS_ATTR(config_time, 0644, ap_config_time_show, ap_config_time_store);
619
620static ssize_t ap_poll_thread_show(struct bus_type *bus, char *buf)
621{
622 return snprintf(buf, PAGE_SIZE, "%d\n", ap_poll_kthread ? 1 : 0);
623}
624
625static ssize_t ap_poll_thread_store(struct bus_type *bus,
626 const char *buf, size_t count)
627{
628 int flag, rc;
629
630 if (sscanf(buf, "%d\n", &flag) != 1)
631 return -EINVAL;
632 if (flag) {
633 rc = ap_poll_thread_start();
634 if (rc)
635 return rc;
636 }
637 else
638 ap_poll_thread_stop();
639 return count;
640}
641
642static BUS_ATTR(poll_thread, 0644, ap_poll_thread_show, ap_poll_thread_store);
643
Felix Beckfe137232008-07-14 09:59:08 +0200644static ssize_t poll_timeout_show(struct bus_type *bus, char *buf)
645{
646 return snprintf(buf, PAGE_SIZE, "%llu\n", poll_timeout);
647}
648
649static ssize_t poll_timeout_store(struct bus_type *bus, const char *buf,
650 size_t count)
651{
652 unsigned long long time;
653 ktime_t hr_time;
654
655 /* 120 seconds = maximum poll interval */
656 if (sscanf(buf, "%llu\n", &time) != 1 || time < 1 || time > 120000000000)
657 return -EINVAL;
658 poll_timeout = time;
659 hr_time = ktime_set(0, poll_timeout);
660
661 if (!hrtimer_is_queued(&ap_poll_timer) ||
662 !hrtimer_forward(&ap_poll_timer, ap_poll_timer.expires, hr_time)) {
663 ap_poll_timer.expires = hr_time;
664 hrtimer_start(&ap_poll_timer, hr_time, HRTIMER_MODE_ABS);
665 }
666 return count;
667}
668
669static BUS_ATTR(poll_timeout, 0644, poll_timeout_show, poll_timeout_store);
670
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200671static struct bus_attribute *const ap_bus_attrs[] = {
672 &bus_attr_ap_domain,
673 &bus_attr_config_time,
674 &bus_attr_poll_thread,
Felix Beckfe137232008-07-14 09:59:08 +0200675 &bus_attr_poll_timeout,
676 NULL,
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200677};
678
679/**
Felix Beck1749a812008-04-17 07:46:28 +0200680 * ap_select_domain(): Select an AP domain.
681 *
682 * Pick one of the 16 AP domains.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200683 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +0100684static int ap_select_domain(void)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200685{
686 int queue_depth, device_type, count, max_count, best_domain;
687 int rc, i, j;
688
Felix Beck1749a812008-04-17 07:46:28 +0200689 /*
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200690 * We want to use a single domain. Either the one specified with
691 * the "domain=" parameter or the domain with the maximum number
692 * of devices.
693 */
694 if (ap_domain_index >= 0 && ap_domain_index < AP_DOMAINS)
695 /* Domain has already been selected. */
696 return 0;
697 best_domain = -1;
698 max_count = 0;
699 for (i = 0; i < AP_DOMAINS; i++) {
700 count = 0;
701 for (j = 0; j < AP_DEVICES; j++) {
702 ap_qid_t qid = AP_MKQID(j, i);
703 rc = ap_query_queue(qid, &queue_depth, &device_type);
704 if (rc)
705 continue;
706 count++;
707 }
708 if (count > max_count) {
709 max_count = count;
710 best_domain = i;
711 }
712 }
713 if (best_domain >= 0){
714 ap_domain_index = best_domain;
715 return 0;
716 }
717 return -ENODEV;
718}
719
720/**
Felix Beck1749a812008-04-17 07:46:28 +0200721 * ap_probe_device_type(): Find the device type of an AP.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200722 * @ap_dev: pointer to the AP device.
Felix Beck1749a812008-04-17 07:46:28 +0200723 *
724 * Find the device type if query queue returned a device type of 0.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200725 */
726static int ap_probe_device_type(struct ap_device *ap_dev)
727{
728 static unsigned char msg[] = {
729 0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
730 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
731 0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x00,
732 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
733 0x01,0x00,0x43,0x43,0x41,0x2d,0x41,0x50,
734 0x50,0x4c,0x20,0x20,0x20,0x01,0x01,0x01,
735 0x00,0x00,0x00,0x00,0x50,0x4b,0x00,0x00,
736 0x00,0x00,0x01,0x1c,0x00,0x00,0x00,0x00,
737 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
738 0x00,0x00,0x05,0xb8,0x00,0x00,0x00,0x00,
739 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
740 0x70,0x00,0x41,0x00,0x00,0x00,0x00,0x00,
741 0x00,0x00,0x54,0x32,0x01,0x00,0xa0,0x00,
742 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
743 0x00,0x00,0x00,0x00,0xb8,0x05,0x00,0x00,
744 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
745 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
746 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
747 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
748 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
749 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
750 0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,
751 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
752 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,
753 0x49,0x43,0x53,0x46,0x20,0x20,0x20,0x20,
754 0x50,0x4b,0x0a,0x00,0x50,0x4b,0x43,0x53,
755 0x2d,0x31,0x2e,0x32,0x37,0x00,0x11,0x22,
756 0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,
757 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,
758 0x99,0x00,0x11,0x22,0x33,0x44,0x55,0x66,
759 0x77,0x88,0x99,0x00,0x11,0x22,0x33,0x44,
760 0x55,0x66,0x77,0x88,0x99,0x00,0x11,0x22,
761 0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00,
762 0x11,0x22,0x33,0x5d,0x00,0x5b,0x00,0x77,
763 0x88,0x1e,0x00,0x00,0x57,0x00,0x00,0x00,
764 0x00,0x04,0x00,0x00,0x4f,0x00,0x00,0x00,
765 0x03,0x02,0x00,0x00,0x40,0x01,0x00,0x01,
766 0xce,0x02,0x68,0x2d,0x5f,0xa9,0xde,0x0c,
767 0xf6,0xd2,0x7b,0x58,0x4b,0xf9,0x28,0x68,
768 0x3d,0xb4,0xf4,0xef,0x78,0xd5,0xbe,0x66,
769 0x63,0x42,0xef,0xf8,0xfd,0xa4,0xf8,0xb0,
770 0x8e,0x29,0xc2,0xc9,0x2e,0xd8,0x45,0xb8,
771 0x53,0x8c,0x6f,0x4e,0x72,0x8f,0x6c,0x04,
772 0x9c,0x88,0xfc,0x1e,0xc5,0x83,0x55,0x57,
773 0xf7,0xdd,0xfd,0x4f,0x11,0x36,0x95,0x5d,
774 };
775 struct ap_queue_status status;
776 unsigned long long psmid;
777 char *reply;
778 int rc, i;
779
780 reply = (void *) get_zeroed_page(GFP_KERNEL);
781 if (!reply) {
782 rc = -ENOMEM;
783 goto out;
784 }
785
786 status = __ap_send(ap_dev->qid, 0x0102030405060708ULL,
787 msg, sizeof(msg));
788 if (status.response_code != AP_RESPONSE_NORMAL) {
789 rc = -ENODEV;
790 goto out_free;
791 }
792
793 /* Wait for the test message to complete. */
794 for (i = 0; i < 6; i++) {
795 mdelay(300);
796 status = __ap_recv(ap_dev->qid, &psmid, reply, 4096);
797 if (status.response_code == AP_RESPONSE_NORMAL &&
798 psmid == 0x0102030405060708ULL)
799 break;
800 }
801 if (i < 6) {
802 /* Got an answer. */
803 if (reply[0] == 0x00 && reply[1] == 0x86)
804 ap_dev->device_type = AP_DEVICE_TYPE_PCICC;
805 else
806 ap_dev->device_type = AP_DEVICE_TYPE_PCICA;
807 rc = 0;
808 } else
809 rc = -ENODEV;
810
811out_free:
812 free_page((unsigned long) reply);
813out:
814 return rc;
815}
816
817/**
Felix Beck1749a812008-04-17 07:46:28 +0200818 * __ap_scan_bus(): Scan the AP bus.
819 * @dev: Pointer to device
820 * @data: Pointer to data
821 *
822 * Scan the AP bus for new devices.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200823 */
824static int __ap_scan_bus(struct device *dev, void *data)
825{
826 return to_ap_dev(dev)->qid == (ap_qid_t)(unsigned long) data;
827}
828
829static void ap_device_release(struct device *dev)
830{
831 struct ap_device *ap_dev = to_ap_dev(dev);
832
833 kfree(ap_dev);
834}
835
Al Viro4927b3f2006-12-06 19:18:20 +0000836static void ap_scan_bus(struct work_struct *unused)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200837{
838 struct ap_device *ap_dev;
839 struct device *dev;
840 ap_qid_t qid;
841 int queue_depth, device_type;
842 int rc, i;
843
844 if (ap_select_domain() != 0)
845 return;
846 for (i = 0; i < AP_DEVICES; i++) {
847 qid = AP_MKQID(i, ap_domain_index);
848 dev = bus_find_device(&ap_bus_type, NULL,
849 (void *)(unsigned long)qid,
850 __ap_scan_bus);
Ralph Wuerthnerf3b017d2006-10-27 12:39:26 +0200851 rc = ap_query_queue(qid, &queue_depth, &device_type);
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +0200852 if (dev) {
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200853 if (rc == -EBUSY) {
854 set_current_state(TASK_UNINTERRUPTIBLE);
855 schedule_timeout(AP_RESET_TIMEOUT);
856 rc = ap_query_queue(qid, &queue_depth,
857 &device_type);
858 }
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +0200859 ap_dev = to_ap_dev(dev);
860 spin_lock_bh(&ap_dev->lock);
861 if (rc || ap_dev->unregistered) {
862 spin_unlock_bh(&ap_dev->lock);
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +0200863 device_unregister(dev);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200864 put_device(dev);
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +0200865 continue;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200866 }
867 spin_unlock_bh(&ap_dev->lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200868 put_device(dev);
869 continue;
870 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200871 if (rc)
872 continue;
873 rc = ap_init_queue(qid);
874 if (rc)
875 continue;
876 ap_dev = kzalloc(sizeof(*ap_dev), GFP_KERNEL);
877 if (!ap_dev)
878 break;
879 ap_dev->qid = qid;
880 ap_dev->queue_depth = queue_depth;
Ralph Wuerthner4e562962006-10-04 20:02:05 +0200881 ap_dev->unregistered = 1;
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200882 spin_lock_init(&ap_dev->lock);
883 INIT_LIST_HEAD(&ap_dev->pendingq);
884 INIT_LIST_HEAD(&ap_dev->requestq);
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +0100885 INIT_LIST_HEAD(&ap_dev->list);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200886 setup_timer(&ap_dev->timeout, ap_request_timeout,
887 (unsigned long) ap_dev);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200888 if (device_type == 0)
889 ap_probe_device_type(ap_dev);
890 else
891 ap_dev->device_type = device_type;
892
893 ap_dev->device.bus = &ap_bus_type;
894 ap_dev->device.parent = ap_root_device;
Cornelia Huck1bf5b282008-10-10 21:33:10 +0200895 dev_set_name(&ap_dev->device, "card%02x",
896 AP_QID_DEVICE(ap_dev->qid));
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200897 ap_dev->device.release = ap_device_release;
898 rc = device_register(&ap_dev->device);
899 if (rc) {
900 kfree(ap_dev);
901 continue;
902 }
903 /* Add device attributes. */
904 rc = sysfs_create_group(&ap_dev->device.kobj,
905 &ap_dev_attr_group);
Ralph Wuerthner4e562962006-10-04 20:02:05 +0200906 if (!rc) {
907 spin_lock_bh(&ap_dev->lock);
908 ap_dev->unregistered = 0;
909 spin_unlock_bh(&ap_dev->lock);
910 }
911 else
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200912 device_unregister(&ap_dev->device);
913 }
914}
915
916static void
917ap_config_timeout(unsigned long ptr)
918{
919 queue_work(ap_work_queue, &ap_config_work);
920 ap_config_timer.expires = jiffies + ap_config_time * HZ;
921 add_timer(&ap_config_timer);
922}
923
924/**
Felix Beck1749a812008-04-17 07:46:28 +0200925 * ap_schedule_poll_timer(): Schedule poll timer.
926 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200927 * Set up the timer to run the poll tasklet
928 */
929static inline void ap_schedule_poll_timer(void)
930{
Felix Beckfe137232008-07-14 09:59:08 +0200931 if (hrtimer_is_queued(&ap_poll_timer))
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200932 return;
Felix Beckfe137232008-07-14 09:59:08 +0200933 hrtimer_start(&ap_poll_timer, ktime_set(0, poll_timeout),
934 HRTIMER_MODE_ABS);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200935}
936
937/**
Felix Beck1749a812008-04-17 07:46:28 +0200938 * ap_poll_read(): Receive pending reply messages from an AP device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200939 * @ap_dev: pointer to the AP device
940 * @flags: pointer to control flags, bit 2^0 is set if another poll is
941 * required, bit 2^1 is set if the poll timer needs to get armed
Felix Beck1749a812008-04-17 07:46:28 +0200942 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200943 * Returns 0 if the device is still present, -ENODEV if not.
944 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +0100945static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200946{
947 struct ap_queue_status status;
948 struct ap_message *ap_msg;
949
950 if (ap_dev->queue_count <= 0)
951 return 0;
952 status = __ap_recv(ap_dev->qid, &ap_dev->reply->psmid,
953 ap_dev->reply->message, ap_dev->reply->length);
954 switch (status.response_code) {
955 case AP_RESPONSE_NORMAL:
956 atomic_dec(&ap_poll_requests);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +0200957 ap_decrease_queue_count(ap_dev);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200958 list_for_each_entry(ap_msg, &ap_dev->pendingq, list) {
959 if (ap_msg->psmid != ap_dev->reply->psmid)
960 continue;
961 list_del_init(&ap_msg->list);
962 ap_dev->pendingq_count--;
963 ap_dev->drv->receive(ap_dev, ap_msg, ap_dev->reply);
964 break;
965 }
966 if (ap_dev->queue_count > 0)
967 *flags |= 1;
968 break;
969 case AP_RESPONSE_NO_PENDING_REPLY:
970 if (status.queue_empty) {
971 /* The card shouldn't forget requests but who knows. */
Ralph Wuerthnere675c0d2007-03-26 20:42:43 +0200972 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200973 ap_dev->queue_count = 0;
974 list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
975 ap_dev->requestq_count += ap_dev->pendingq_count;
976 ap_dev->pendingq_count = 0;
977 } else
978 *flags |= 2;
979 break;
980 default:
981 return -ENODEV;
982 }
983 return 0;
984}
985
986/**
Felix Beck1749a812008-04-17 07:46:28 +0200987 * ap_poll_write(): Send messages from the request queue to an AP device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200988 * @ap_dev: pointer to the AP device
989 * @flags: pointer to control flags, bit 2^0 is set if another poll is
990 * required, bit 2^1 is set if the poll timer needs to get armed
Felix Beck1749a812008-04-17 07:46:28 +0200991 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200992 * Returns 0 if the device is still present, -ENODEV if not.
993 */
Heiko Carstens4d284ca2007-02-05 21:18:53 +0100994static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +0200995{
996 struct ap_queue_status status;
997 struct ap_message *ap_msg;
998
999 if (ap_dev->requestq_count <= 0 ||
1000 ap_dev->queue_count >= ap_dev->queue_depth)
1001 return 0;
1002 /* Start the next request on the queue. */
1003 ap_msg = list_entry(ap_dev->requestq.next, struct ap_message, list);
1004 status = __ap_send(ap_dev->qid, ap_msg->psmid,
1005 ap_msg->message, ap_msg->length);
1006 switch (status.response_code) {
1007 case AP_RESPONSE_NORMAL:
1008 atomic_inc(&ap_poll_requests);
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001009 ap_increase_queue_count(ap_dev);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001010 list_move_tail(&ap_msg->list, &ap_dev->pendingq);
1011 ap_dev->requestq_count--;
1012 ap_dev->pendingq_count++;
1013 if (ap_dev->queue_count < ap_dev->queue_depth &&
1014 ap_dev->requestq_count > 0)
1015 *flags |= 1;
1016 *flags |= 2;
1017 break;
1018 case AP_RESPONSE_Q_FULL:
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001019 case AP_RESPONSE_RESET_IN_PROGRESS:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001020 *flags |= 2;
1021 break;
1022 case AP_RESPONSE_MESSAGE_TOO_BIG:
1023 return -EINVAL;
1024 default:
1025 return -ENODEV;
1026 }
1027 return 0;
1028}
1029
1030/**
Felix Beck1749a812008-04-17 07:46:28 +02001031 * ap_poll_queue(): Poll AP device for pending replies and send new messages.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001032 * @ap_dev: pointer to the bus device
1033 * @flags: pointer to control flags, bit 2^0 is set if another poll is
1034 * required, bit 2^1 is set if the poll timer needs to get armed
Felix Beck1749a812008-04-17 07:46:28 +02001035 *
1036 * Poll AP device for pending replies and send new messages. If either
1037 * ap_poll_read or ap_poll_write returns -ENODEV unregister the device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001038 * Returns 0.
1039 */
1040static inline int ap_poll_queue(struct ap_device *ap_dev, unsigned long *flags)
1041{
1042 int rc;
1043
1044 rc = ap_poll_read(ap_dev, flags);
1045 if (rc)
1046 return rc;
1047 return ap_poll_write(ap_dev, flags);
1048}
1049
1050/**
Felix Beck1749a812008-04-17 07:46:28 +02001051 * __ap_queue_message(): Queue a message to a device.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001052 * @ap_dev: pointer to the AP device
1053 * @ap_msg: the message to be queued
Felix Beck1749a812008-04-17 07:46:28 +02001054 *
1055 * Queue a message to a device. Returns 0 if successful.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001056 */
1057static int __ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
1058{
1059 struct ap_queue_status status;
1060
1061 if (list_empty(&ap_dev->requestq) &&
1062 ap_dev->queue_count < ap_dev->queue_depth) {
1063 status = __ap_send(ap_dev->qid, ap_msg->psmid,
1064 ap_msg->message, ap_msg->length);
1065 switch (status.response_code) {
1066 case AP_RESPONSE_NORMAL:
1067 list_add_tail(&ap_msg->list, &ap_dev->pendingq);
1068 atomic_inc(&ap_poll_requests);
1069 ap_dev->pendingq_count++;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001070 ap_increase_queue_count(ap_dev);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001071 ap_dev->total_request_count++;
1072 break;
1073 case AP_RESPONSE_Q_FULL:
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001074 case AP_RESPONSE_RESET_IN_PROGRESS:
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001075 list_add_tail(&ap_msg->list, &ap_dev->requestq);
1076 ap_dev->requestq_count++;
1077 ap_dev->total_request_count++;
1078 return -EBUSY;
1079 case AP_RESPONSE_MESSAGE_TOO_BIG:
1080 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL));
1081 return -EINVAL;
1082 default: /* Device is gone. */
1083 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
1084 return -ENODEV;
1085 }
1086 } else {
1087 list_add_tail(&ap_msg->list, &ap_dev->requestq);
1088 ap_dev->requestq_count++;
1089 ap_dev->total_request_count++;
1090 return -EBUSY;
1091 }
1092 ap_schedule_poll_timer();
1093 return 0;
1094}
1095
1096void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
1097{
1098 unsigned long flags;
1099 int rc;
1100
1101 spin_lock_bh(&ap_dev->lock);
1102 if (!ap_dev->unregistered) {
1103 /* Make room on the queue by polling for finished requests. */
1104 rc = ap_poll_queue(ap_dev, &flags);
1105 if (!rc)
1106 rc = __ap_queue_message(ap_dev, ap_msg);
1107 if (!rc)
1108 wake_up(&ap_poll_wait);
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001109 if (rc == -ENODEV)
1110 ap_dev->unregistered = 1;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001111 } else {
1112 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001113 rc = -ENODEV;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001114 }
1115 spin_unlock_bh(&ap_dev->lock);
1116 if (rc == -ENODEV)
1117 device_unregister(&ap_dev->device);
1118}
1119EXPORT_SYMBOL(ap_queue_message);
1120
1121/**
Felix Beck1749a812008-04-17 07:46:28 +02001122 * ap_cancel_message(): Cancel a crypto request.
1123 * @ap_dev: The AP device that has the message queued
1124 * @ap_msg: The message that is to be removed
1125 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001126 * Cancel a crypto request. This is done by removing the request
Felix Beck1749a812008-04-17 07:46:28 +02001127 * from the device pending or request queue. Note that the
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001128 * request stays on the AP queue. When it finishes the message
1129 * reply will be discarded because the psmid can't be found.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001130 */
1131void ap_cancel_message(struct ap_device *ap_dev, struct ap_message *ap_msg)
1132{
1133 struct ap_message *tmp;
1134
1135 spin_lock_bh(&ap_dev->lock);
1136 if (!list_empty(&ap_msg->list)) {
1137 list_for_each_entry(tmp, &ap_dev->pendingq, list)
1138 if (tmp->psmid == ap_msg->psmid) {
1139 ap_dev->pendingq_count--;
1140 goto found;
1141 }
1142 ap_dev->requestq_count--;
1143 found:
1144 list_del_init(&ap_msg->list);
1145 }
1146 spin_unlock_bh(&ap_dev->lock);
1147}
1148EXPORT_SYMBOL(ap_cancel_message);
1149
1150/**
Felix Beck1749a812008-04-17 07:46:28 +02001151 * ap_poll_timeout(): AP receive polling for finished AP requests.
Felix Beckfe137232008-07-14 09:59:08 +02001152 * @unused: Unused pointer.
Felix Beck1749a812008-04-17 07:46:28 +02001153 *
Felix Beckfe137232008-07-14 09:59:08 +02001154 * Schedules the AP tasklet using a high resolution timer.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001155 */
Felix Beckfe137232008-07-14 09:59:08 +02001156static enum hrtimer_restart ap_poll_timeout(struct hrtimer *unused)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001157{
1158 tasklet_schedule(&ap_tasklet);
Felix Beckfe137232008-07-14 09:59:08 +02001159 return HRTIMER_NORESTART;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001160}
1161
1162/**
Felix Beck1749a812008-04-17 07:46:28 +02001163 * ap_reset(): Reset a not responding AP device.
1164 * @ap_dev: Pointer to the AP device
1165 *
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001166 * Reset a not responding AP device and move all requests from the
1167 * pending queue to the request queue.
1168 */
1169static void ap_reset(struct ap_device *ap_dev)
1170{
1171 int rc;
1172
1173 ap_dev->reset = AP_RESET_IGNORE;
1174 atomic_sub(ap_dev->queue_count, &ap_poll_requests);
1175 ap_dev->queue_count = 0;
1176 list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
1177 ap_dev->requestq_count += ap_dev->pendingq_count;
1178 ap_dev->pendingq_count = 0;
1179 rc = ap_init_queue(ap_dev->qid);
1180 if (rc == -ENODEV)
1181 ap_dev->unregistered = 1;
1182}
1183
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001184static int __ap_poll_all(struct ap_device *ap_dev, unsigned long *flags)
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001185{
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001186 spin_lock(&ap_dev->lock);
1187 if (!ap_dev->unregistered) {
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001188 if (ap_poll_queue(ap_dev, flags))
Ralph Wuerthner4e562962006-10-04 20:02:05 +02001189 ap_dev->unregistered = 1;
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001190 if (ap_dev->reset == AP_RESET_DO)
1191 ap_reset(ap_dev);
Ralph Wuerthnerc6a48262007-03-26 20:42:42 +02001192 }
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001193 spin_unlock(&ap_dev->lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001194 return 0;
1195}
1196
Felix Beck1749a812008-04-17 07:46:28 +02001197/**
1198 * ap_poll_all(): Poll all AP devices.
1199 * @dummy: Unused variable
1200 *
1201 * Poll all AP devices on the bus in a round robin fashion. Continue
1202 * polling until bit 2^0 of the control flags is not set. If bit 2^1
1203 * of the control flags has been set arm the poll timer.
1204 */
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001205static void ap_poll_all(unsigned long dummy)
1206{
1207 unsigned long flags;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001208 struct ap_device *ap_dev;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001209
1210 do {
1211 flags = 0;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001212 spin_lock(&ap_device_lock);
1213 list_for_each_entry(ap_dev, &ap_device_list, list) {
1214 __ap_poll_all(ap_dev, &flags);
1215 }
1216 spin_unlock(&ap_device_lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001217 } while (flags & 1);
1218 if (flags & 2)
1219 ap_schedule_poll_timer();
1220}
1221
1222/**
Felix Beck1749a812008-04-17 07:46:28 +02001223 * ap_poll_thread(): Thread that polls for finished requests.
1224 * @data: Unused pointer
1225 *
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001226 * AP bus poll thread. The purpose of this thread is to poll for
1227 * finished requests in a loop if there is a "free" cpu - that is
1228 * a cpu that doesn't have anything better to do. The polling stops
1229 * as soon as there is another task or if all messages have been
1230 * delivered.
1231 */
1232static int ap_poll_thread(void *data)
1233{
1234 DECLARE_WAITQUEUE(wait, current);
1235 unsigned long flags;
1236 int requests;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001237 struct ap_device *ap_dev;
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001238
Christian Borntraegerd83682b2006-10-06 16:38:22 +02001239 set_user_nice(current, 19);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001240 while (1) {
1241 if (need_resched()) {
1242 schedule();
1243 continue;
1244 }
1245 add_wait_queue(&ap_poll_wait, &wait);
1246 set_current_state(TASK_INTERRUPTIBLE);
1247 if (kthread_should_stop())
1248 break;
1249 requests = atomic_read(&ap_poll_requests);
1250 if (requests <= 0)
1251 schedule();
1252 set_current_state(TASK_RUNNING);
1253 remove_wait_queue(&ap_poll_wait, &wait);
1254
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001255 flags = 0;
Ralph Wuerthnercf352ce2007-03-19 13:19:14 +01001256 spin_lock_bh(&ap_device_lock);
1257 list_for_each_entry(ap_dev, &ap_device_list, list) {
1258 __ap_poll_all(ap_dev, &flags);
1259 }
1260 spin_unlock_bh(&ap_device_lock);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001261 }
1262 set_current_state(TASK_RUNNING);
1263 remove_wait_queue(&ap_poll_wait, &wait);
1264 return 0;
1265}
1266
1267static int ap_poll_thread_start(void)
1268{
1269 int rc;
1270
1271 mutex_lock(&ap_poll_thread_mutex);
1272 if (!ap_poll_kthread) {
1273 ap_poll_kthread = kthread_run(ap_poll_thread, NULL, "appoll");
1274 rc = IS_ERR(ap_poll_kthread) ? PTR_ERR(ap_poll_kthread) : 0;
1275 if (rc)
1276 ap_poll_kthread = NULL;
1277 }
1278 else
1279 rc = 0;
1280 mutex_unlock(&ap_poll_thread_mutex);
1281 return rc;
1282}
1283
1284static void ap_poll_thread_stop(void)
1285{
1286 mutex_lock(&ap_poll_thread_mutex);
1287 if (ap_poll_kthread) {
1288 kthread_stop(ap_poll_kthread);
1289 ap_poll_kthread = NULL;
1290 }
1291 mutex_unlock(&ap_poll_thread_mutex);
1292}
1293
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001294/**
Felix Beck1749a812008-04-17 07:46:28 +02001295 * ap_request_timeout(): Handling of request timeouts
1296 * @data: Holds the AP device.
1297 *
1298 * Handles request timeouts.
Ralph Wuerthneraf512ed02007-07-10 11:24:19 +02001299 */
1300static void ap_request_timeout(unsigned long data)
1301{
1302 struct ap_device *ap_dev = (struct ap_device *) data;
1303
1304 if (ap_dev->reset == AP_RESET_ARMED)
1305 ap_dev->reset = AP_RESET_DO;
1306}
1307
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001308static void ap_reset_domain(void)
1309{
1310 int i;
1311
Ralph Wuerthner39aa7cf2007-10-12 16:11:29 +02001312 if (ap_domain_index != -1)
1313 for (i = 0; i < AP_DEVICES; i++)
1314 ap_reset_queue(AP_MKQID(i, ap_domain_index));
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001315}
1316
1317static void ap_reset_all(void)
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001318{
1319 int i, j;
1320
1321 for (i = 0; i < AP_DOMAINS; i++)
1322 for (j = 0; j < AP_DEVICES; j++)
1323 ap_reset_queue(AP_MKQID(j, i));
1324}
1325
1326static struct reset_call ap_reset_call = {
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001327 .fn = ap_reset_all,
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001328};
1329
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001330/**
Felix Beck1749a812008-04-17 07:46:28 +02001331 * ap_module_init(): The module initialization code.
1332 *
1333 * Initializes the module.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001334 */
1335int __init ap_module_init(void)
1336{
1337 int rc, i;
1338
1339 if (ap_domain_index < -1 || ap_domain_index >= AP_DOMAINS) {
1340 printk(KERN_WARNING "Invalid param: domain = %d. "
1341 " Not loading.\n", ap_domain_index);
1342 return -EINVAL;
1343 }
1344 if (ap_instructions_available() != 0) {
1345 printk(KERN_WARNING "AP instructions not installed.\n");
1346 return -ENODEV;
1347 }
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001348 register_reset_call(&ap_reset_call);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001349
1350 /* Create /sys/bus/ap. */
1351 rc = bus_register(&ap_bus_type);
1352 if (rc)
1353 goto out;
1354 for (i = 0; ap_bus_attrs[i]; i++) {
1355 rc = bus_create_file(&ap_bus_type, ap_bus_attrs[i]);
1356 if (rc)
1357 goto out_bus;
1358 }
1359
1360 /* Create /sys/devices/ap. */
1361 ap_root_device = s390_root_dev_register("ap");
1362 rc = IS_ERR(ap_root_device) ? PTR_ERR(ap_root_device) : 0;
1363 if (rc)
1364 goto out_bus;
1365
1366 ap_work_queue = create_singlethread_workqueue("kapwork");
1367 if (!ap_work_queue) {
1368 rc = -ENOMEM;
1369 goto out_root;
1370 }
1371
1372 if (ap_select_domain() == 0)
1373 ap_scan_bus(NULL);
1374
Felix Beck1749a812008-04-17 07:46:28 +02001375 /* Setup the AP bus rescan timer. */
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001376 init_timer(&ap_config_timer);
1377 ap_config_timer.function = ap_config_timeout;
1378 ap_config_timer.data = 0;
1379 ap_config_timer.expires = jiffies + ap_config_time * HZ;
1380 add_timer(&ap_config_timer);
1381
Felix Beckfe137232008-07-14 09:59:08 +02001382 /* Setup the high resultion poll timer.
1383 * If we are running under z/VM adjust polling to z/VM polling rate.
1384 */
1385 if (MACHINE_IS_VM)
1386 poll_timeout = 1500000;
1387 hrtimer_init(&ap_poll_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
1388 ap_poll_timer.function = ap_poll_timeout;
1389
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001390 /* Start the low priority AP bus poll thread. */
1391 if (ap_thread_flag) {
1392 rc = ap_poll_thread_start();
1393 if (rc)
1394 goto out_work;
1395 }
1396
1397 return 0;
1398
1399out_work:
1400 del_timer_sync(&ap_config_timer);
Felix Beckfe137232008-07-14 09:59:08 +02001401 hrtimer_cancel(&ap_poll_timer);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001402 destroy_workqueue(ap_work_queue);
1403out_root:
1404 s390_root_dev_unregister(ap_root_device);
1405out_bus:
1406 while (i--)
1407 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
1408 bus_unregister(&ap_bus_type);
1409out:
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001410 unregister_reset_call(&ap_reset_call);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001411 return rc;
1412}
1413
1414static int __ap_match_all(struct device *dev, void *data)
1415{
1416 return 1;
1417}
1418
1419/**
Felix Beck1749a812008-04-17 07:46:28 +02001420 * ap_modules_exit(): The module termination code
1421 *
1422 * Terminates the module.
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001423 */
1424void ap_module_exit(void)
1425{
1426 int i;
1427 struct device *dev;
1428
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001429 ap_reset_domain();
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001430 ap_poll_thread_stop();
1431 del_timer_sync(&ap_config_timer);
Felix Beckfe137232008-07-14 09:59:08 +02001432 hrtimer_cancel(&ap_poll_timer);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001433 destroy_workqueue(ap_work_queue);
Ralph Wuerthner13e742b2006-12-15 17:18:17 +01001434 tasklet_kill(&ap_tasklet);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001435 s390_root_dev_unregister(ap_root_device);
1436 while ((dev = bus_find_device(&ap_bus_type, NULL, NULL,
1437 __ap_match_all)))
1438 {
1439 device_unregister(dev);
1440 put_device(dev);
1441 }
1442 for (i = 0; ap_bus_attrs[i]; i++)
1443 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
1444 bus_unregister(&ap_bus_type);
Ralph Wuerthner85eca852006-12-08 15:54:07 +01001445 unregister_reset_call(&ap_reset_call);
Martin Schwidefsky1534c382006-09-20 15:58:25 +02001446}
1447
1448#ifndef CONFIG_ZCRYPT_MONOLITHIC
1449module_init(ap_module_init);
1450module_exit(ap_module_exit);
1451#endif