ap_queue.c 24.3 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*
 * Copyright IBM Corp. 2016
 * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
 *
 * Adjunct processor bus, queue related code.
 */

#define KMSG_COMPONENT "ap"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt

#include <linux/init.h>
#include <linux/slab.h>
#include <asm/facility.h>

#include "ap_bus.h"
17 18 19
#include "ap_debug.h"

static void __ap_flush_queue(struct ap_queue *aq);
20

21
/**
22
 * ap_queue_enable_irq(): Enable interrupt support on this AP queue.
23
 * @aq: The AP queue
24 25 26 27 28 29
 * @ind: the notification indicator byte
 *
 * Enables interruption on AP queue via ap_aqic(). Based on the return
 * value it waits a while and tests the AP queue if interrupts
 * have been switched on using ap_test_queue().
 */
30
static int ap_queue_enable_irq(struct ap_queue *aq, void *ind)
31
{
32
	union ap_qirq_ctrl qirqctrl = { .value = 0 };
33 34
	struct ap_queue_status status;

35 36
	qirqctrl.ir = 1;
	qirqctrl.isc = AP_ISC;
37
	status = ap_aqic(aq->qid, qirqctrl, virt_to_phys(ind));
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
	switch (status.response_code) {
	case AP_RESPONSE_NORMAL:
	case AP_RESPONSE_OTHERWISE_CHANGED:
		return 0;
	case AP_RESPONSE_Q_NOT_AVAIL:
	case AP_RESPONSE_DECONFIGURED:
	case AP_RESPONSE_CHECKSTOPPED:
	case AP_RESPONSE_INVALID_ADDRESS:
		pr_err("Registering adapter interrupts for AP device %02x.%04x failed\n",
		       AP_QID_CARD(aq->qid),
		       AP_QID_QUEUE(aq->qid));
		return -EOPNOTSUPP;
	case AP_RESPONSE_RESET_IN_PROGRESS:
	case AP_RESPONSE_BUSY:
	default:
		return -EBUSY;
	}
}

/**
 * __ap_send(): Send message to adjunct processor queue.
 * @qid: The AP queue number
 * @psmid: The program supplied message identifier
 * @msg: The message text
 * @length: The message length
 * @special: Special Bit
 *
 * Returns AP queue status structure.
 * Condition code 1 on NQAP can't happen because the L bit is 1.
 * Condition code 2 on NQAP also means the send is incomplete,
 * because a segment boundary was reached. The NQAP is repeated.
 */
static inline struct ap_queue_status
__ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length,
72
	  int special)
73
{
74
	if (special)
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
		qid |= 0x400000UL;
	return ap_nqap(qid, psmid, msg, length);
}

int ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length)
{
	struct ap_queue_status status;

	status = __ap_send(qid, psmid, msg, length, 0);
	switch (status.response_code) {
	case AP_RESPONSE_NORMAL:
		return 0;
	case AP_RESPONSE_Q_FULL:
	case AP_RESPONSE_RESET_IN_PROGRESS:
		return -EBUSY;
	case AP_RESPONSE_REQ_FAC_NOT_INST:
		return -EINVAL;
	default:	/* Device is gone. */
		return -ENODEV;
	}
}
EXPORT_SYMBOL(ap_send);

int ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length)
{
	struct ap_queue_status status;

H
Harald Freudenberger 已提交
102
	if (!msg)
103
		return -EINVAL;
104
	status = ap_dqap(qid, psmid, msg, length, NULL, NULL);
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
	switch (status.response_code) {
	case AP_RESPONSE_NORMAL:
		return 0;
	case AP_RESPONSE_NO_PENDING_REPLY:
		if (status.queue_empty)
			return -ENOENT;
		return -EBUSY;
	case AP_RESPONSE_RESET_IN_PROGRESS:
		return -EBUSY;
	default:
		return -ENODEV;
	}
}
EXPORT_SYMBOL(ap_recv);

/* State machine definitions and helpers */

122
static enum ap_sm_wait ap_sm_nop(struct ap_queue *aq)
123
{
124
	return AP_SM_WAIT_NONE;
125 126 127 128 129 130 131
}

/**
 * ap_sm_recv(): Receive pending reply messages from an AP queue but do
 *	not change the state of the device.
 * @aq: pointer to the AP queue
 *
132
 * Returns AP_SM_WAIT_NONE, AP_SM_WAIT_AGAIN, or AP_SM_WAIT_INTERRUPT
133 134 135 136 137
 */
static struct ap_queue_status ap_sm_recv(struct ap_queue *aq)
{
	struct ap_queue_status status;
	struct ap_message *ap_msg;
138
	bool found = false;
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
	size_t reslen;
	unsigned long resgr0 = 0;
	int parts = 0;

	/*
	 * DQAP loop until response code and resgr0 indicate that
	 * the msg is totally received. As we use the very same buffer
	 * the msg is overwritten with each invocation. That's intended
	 * and the receiver of the msg is informed with a msg rc code
	 * of EMSGSIZE in such a case.
	 */
	do {
		status = ap_dqap(aq->qid, &aq->reply->psmid,
				 aq->reply->msg, aq->reply->bufsize,
				 &reslen, &resgr0);
		parts++;
	} while (status.response_code == 0xFF && resgr0 != 0);
156 157 158

	switch (status.response_code) {
	case AP_RESPONSE_NORMAL:
159
		aq->queue_count = max_t(int, 0, aq->queue_count - 1);
160 161
		if (!status.queue_empty && !aq->queue_count)
			aq->queue_count++;
162 163 164 165 166 167 168 169
		if (aq->queue_count > 0)
			mod_timer(&aq->timeout,
				  jiffies + aq->request_timeout);
		list_for_each_entry(ap_msg, &aq->pendingq, list) {
			if (ap_msg->psmid != aq->reply->psmid)
				continue;
			list_del_init(&ap_msg->list);
			aq->pendingq_count--;
170 171 172 173 174 175
			if (parts > 1) {
				ap_msg->rc = -EMSGSIZE;
				ap_msg->receive(aq, ap_msg, NULL);
			} else {
				ap_msg->receive(aq, ap_msg, aq->reply);
			}
176
			found = true;
177 178
			break;
		}
179 180 181 182 183
		if (!found) {
			AP_DBF_WARN("%s unassociated reply psmid=0x%016llx on 0x%02x.%04x\n",
				    __func__, aq->reply->psmid,
				    AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid));
		}
J
Joe Perches 已提交
184
		fallthrough;
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
	case AP_RESPONSE_NO_PENDING_REPLY:
		if (!status.queue_empty || aq->queue_count <= 0)
			break;
		/* The card shouldn't forget requests but who knows. */
		aq->queue_count = 0;
		list_splice_init(&aq->pendingq, &aq->requestq);
		aq->requestq_count += aq->pendingq_count;
		aq->pendingq_count = 0;
		break;
	default:
		break;
	}
	return status;
}

/**
 * ap_sm_read(): Receive pending reply messages from an AP queue.
 * @aq: pointer to the AP queue
 *
204
 * Returns AP_SM_WAIT_NONE, AP_SM_WAIT_AGAIN, or AP_SM_WAIT_INTERRUPT
205
 */
206
static enum ap_sm_wait ap_sm_read(struct ap_queue *aq)
207 208 209 210
{
	struct ap_queue_status status;

	if (!aq->reply)
211
		return AP_SM_WAIT_NONE;
212 213 214 215
	status = ap_sm_recv(aq);
	switch (status.response_code) {
	case AP_RESPONSE_NORMAL:
		if (aq->queue_count > 0) {
216 217
			aq->sm_state = AP_SM_STATE_WORKING;
			return AP_SM_WAIT_AGAIN;
218
		}
219 220
		aq->sm_state = AP_SM_STATE_IDLE;
		return AP_SM_WAIT_NONE;
221 222
	case AP_RESPONSE_NO_PENDING_REPLY:
		if (aq->queue_count > 0)
223 224
			return aq->interrupt ?
				AP_SM_WAIT_INTERRUPT : AP_SM_WAIT_TIMEOUT;
225 226
		aq->sm_state = AP_SM_STATE_IDLE;
		return AP_SM_WAIT_NONE;
227
	default:
228
		aq->dev_state = AP_DEV_STATE_ERROR;
229
		aq->last_err_rc = status.response_code;
230
		AP_DBF_WARN("%s RC 0x%02x on 0x%02x.%04x -> AP_DEV_STATE_ERROR\n",
231 232
			    __func__, status.response_code,
			    AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid));
233
		return AP_SM_WAIT_NONE;
234 235 236 237 238 239 240
	}
}

/**
 * ap_sm_write(): Send messages from the request queue to an AP queue.
 * @aq: pointer to the AP queue
 *
241
 * Returns AP_SM_WAIT_NONE, AP_SM_WAIT_AGAIN, or AP_SM_WAIT_INTERRUPT
242
 */
243
static enum ap_sm_wait ap_sm_write(struct ap_queue *aq)
244 245 246
{
	struct ap_queue_status status;
	struct ap_message *ap_msg;
247
	ap_qid_t qid = aq->qid;
248 249

	if (aq->requestq_count <= 0)
250
		return AP_SM_WAIT_NONE;
251

252 253
	/* Start the next request on the queue. */
	ap_msg = list_entry(aq->requestq.next, struct ap_message, list);
254 255 256 257 258 259 260 261
#ifdef CONFIG_ZCRYPT_DEBUG
	if (ap_msg->fi.action == AP_FI_ACTION_NQAP_QID_INVAL) {
		AP_DBF_WARN("%s fi cmd 0x%04x: forcing invalid qid 0xFF00\n",
			    __func__, ap_msg->fi.cmd);
		qid = 0xFF00;
	}
#endif
	status = __ap_send(qid, ap_msg->psmid,
262 263
			   ap_msg->msg, ap_msg->len,
			   ap_msg->flags & AP_MSG_FLAG_SPECIAL);
264 265
	switch (status.response_code) {
	case AP_RESPONSE_NORMAL:
266
		aq->queue_count = max_t(int, 1, aq->queue_count + 1);
267 268 269 270 271 272
		if (aq->queue_count == 1)
			mod_timer(&aq->timeout, jiffies + aq->request_timeout);
		list_move_tail(&ap_msg->list, &aq->pendingq);
		aq->requestq_count--;
		aq->pendingq_count++;
		if (aq->queue_count < aq->card->queue_depth) {
273 274
			aq->sm_state = AP_SM_STATE_WORKING;
			return AP_SM_WAIT_AGAIN;
275
		}
J
Joe Perches 已提交
276
		fallthrough;
277
	case AP_RESPONSE_Q_FULL:
278
		aq->sm_state = AP_SM_STATE_QUEUE_FULL;
279 280
		return aq->interrupt ?
			AP_SM_WAIT_INTERRUPT : AP_SM_WAIT_TIMEOUT;
281
	case AP_RESPONSE_RESET_IN_PROGRESS:
282 283
		aq->sm_state = AP_SM_STATE_RESET_WAIT;
		return AP_SM_WAIT_TIMEOUT;
284
	case AP_RESPONSE_INVALID_DOMAIN:
285
		AP_DBF_WARN("%s RESPONSE_INVALID_DOMAIN on NQAP\n", __func__);
286
		fallthrough;
287 288 289 290 291 292
	case AP_RESPONSE_MESSAGE_TOO_BIG:
	case AP_RESPONSE_REQ_FAC_NOT_INST:
		list_del_init(&ap_msg->list);
		aq->requestq_count--;
		ap_msg->rc = -EINVAL;
		ap_msg->receive(aq, ap_msg, NULL);
293
		return AP_SM_WAIT_AGAIN;
294
	default:
295
		aq->dev_state = AP_DEV_STATE_ERROR;
296
		aq->last_err_rc = status.response_code;
297
		AP_DBF_WARN("%s RC 0x%02x on 0x%02x.%04x -> AP_DEV_STATE_ERROR\n",
298 299
			    __func__, status.response_code,
			    AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid));
300
		return AP_SM_WAIT_NONE;
301 302 303 304 305 306 307
	}
}

/**
 * ap_sm_read_write(): Send and receive messages to/from an AP queue.
 * @aq: pointer to the AP queue
 *
308
 * Returns AP_SM_WAIT_NONE, AP_SM_WAIT_AGAIN, or AP_SM_WAIT_INTERRUPT
309
 */
310
static enum ap_sm_wait ap_sm_read_write(struct ap_queue *aq)
311 312 313 314 315 316
{
	return min(ap_sm_read(aq), ap_sm_write(aq));
}

/**
 * ap_sm_reset(): Reset an AP queue.
317
 * @aq: The AP queue
318 319 320
 *
 * Submit the Reset command to an AP queue.
 */
321
static enum ap_sm_wait ap_sm_reset(struct ap_queue *aq)
322 323 324 325 326 327 328
{
	struct ap_queue_status status;

	status = ap_rapq(aq->qid);
	switch (status.response_code) {
	case AP_RESPONSE_NORMAL:
	case AP_RESPONSE_RESET_IN_PROGRESS:
329
		aq->sm_state = AP_SM_STATE_RESET_WAIT;
330
		aq->interrupt = false;
331
		return AP_SM_WAIT_TIMEOUT;
332
	default:
333
		aq->dev_state = AP_DEV_STATE_ERROR;
334
		aq->last_err_rc = status.response_code;
335
		AP_DBF_WARN("%s RC 0x%02x on 0x%02x.%04x -> AP_DEV_STATE_ERROR\n",
336 337
			    __func__, status.response_code,
			    AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid));
338
		return AP_SM_WAIT_NONE;
339 340 341 342 343 344 345 346 347
	}
}

/**
 * ap_sm_reset_wait(): Test queue for completion of the reset operation
 * @aq: pointer to the AP queue
 *
 * Returns AP_POLL_IMMEDIATELY, AP_POLL_AFTER_TIMEROUT or 0.
 */
348
static enum ap_sm_wait ap_sm_reset_wait(struct ap_queue *aq)
349 350 351 352 353 354 355 356 357 358 359 360 361 362
{
	struct ap_queue_status status;
	void *lsi_ptr;

	if (aq->queue_count > 0 && aq->reply)
		/* Try to read a completed message and get the status */
		status = ap_sm_recv(aq);
	else
		/* Get the status with TAPQ */
		status = ap_tapq(aq->qid, NULL);

	switch (status.response_code) {
	case AP_RESPONSE_NORMAL:
		lsi_ptr = ap_airq_ptr();
363
		if (lsi_ptr && ap_queue_enable_irq(aq, lsi_ptr) == 0)
364
			aq->sm_state = AP_SM_STATE_SETIRQ_WAIT;
365
		else
366 367 368
			aq->sm_state = (aq->queue_count > 0) ?
				AP_SM_STATE_WORKING : AP_SM_STATE_IDLE;
		return AP_SM_WAIT_AGAIN;
369 370
	case AP_RESPONSE_BUSY:
	case AP_RESPONSE_RESET_IN_PROGRESS:
371
		return AP_SM_WAIT_TIMEOUT;
372 373 374 375
	case AP_RESPONSE_Q_NOT_AVAIL:
	case AP_RESPONSE_DECONFIGURED:
	case AP_RESPONSE_CHECKSTOPPED:
	default:
376
		aq->dev_state = AP_DEV_STATE_ERROR;
377
		aq->last_err_rc = status.response_code;
378
		AP_DBF_WARN("%s RC 0x%02x on 0x%02x.%04x -> AP_DEV_STATE_ERROR\n",
379 380
			    __func__, status.response_code,
			    AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid));
381
		return AP_SM_WAIT_NONE;
382 383 384 385 386 387 388 389 390
	}
}

/**
 * ap_sm_setirq_wait(): Test queue for completion of the irq enablement
 * @aq: pointer to the AP queue
 *
 * Returns AP_POLL_IMMEDIATELY, AP_POLL_AFTER_TIMEROUT or 0.
 */
391
static enum ap_sm_wait ap_sm_setirq_wait(struct ap_queue *aq)
392 393 394 395 396 397 398 399 400 401
{
	struct ap_queue_status status;

	if (aq->queue_count > 0 && aq->reply)
		/* Try to read a completed message and get the status */
		status = ap_sm_recv(aq);
	else
		/* Get the status with TAPQ */
		status = ap_tapq(aq->qid, NULL);

402
	if (status.irq_enabled == 1) {
403
		/* Irqs are now enabled */
404
		aq->interrupt = true;
405 406
		aq->sm_state = (aq->queue_count > 0) ?
			AP_SM_STATE_WORKING : AP_SM_STATE_IDLE;
407 408 409 410 411
	}

	switch (status.response_code) {
	case AP_RESPONSE_NORMAL:
		if (aq->queue_count > 0)
412
			return AP_SM_WAIT_AGAIN;
J
Joe Perches 已提交
413
		fallthrough;
414
	case AP_RESPONSE_NO_PENDING_REPLY:
415
		return AP_SM_WAIT_TIMEOUT;
416
	default:
417
		aq->dev_state = AP_DEV_STATE_ERROR;
418
		aq->last_err_rc = status.response_code;
419
		AP_DBF_WARN("%s RC 0x%02x on 0x%02x.%04x -> AP_DEV_STATE_ERROR\n",
420 421
			    __func__, status.response_code,
			    AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid));
422
		return AP_SM_WAIT_NONE;
423 424 425 426 427 428
	}
}

/*
 * AP state machine jump table
 */
429 430 431 432
static ap_func_t *ap_jumptable[NR_AP_SM_STATES][NR_AP_SM_EVENTS] = {
	[AP_SM_STATE_RESET_START] = {
		[AP_SM_EVENT_POLL] = ap_sm_reset,
		[AP_SM_EVENT_TIMEOUT] = ap_sm_nop,
433
	},
434 435 436
	[AP_SM_STATE_RESET_WAIT] = {
		[AP_SM_EVENT_POLL] = ap_sm_reset_wait,
		[AP_SM_EVENT_TIMEOUT] = ap_sm_nop,
437
	},
438 439 440
	[AP_SM_STATE_SETIRQ_WAIT] = {
		[AP_SM_EVENT_POLL] = ap_sm_setirq_wait,
		[AP_SM_EVENT_TIMEOUT] = ap_sm_nop,
441
	},
442 443 444
	[AP_SM_STATE_IDLE] = {
		[AP_SM_EVENT_POLL] = ap_sm_write,
		[AP_SM_EVENT_TIMEOUT] = ap_sm_nop,
445
	},
446 447 448
	[AP_SM_STATE_WORKING] = {
		[AP_SM_EVENT_POLL] = ap_sm_read_write,
		[AP_SM_EVENT_TIMEOUT] = ap_sm_reset,
449
	},
450 451 452
	[AP_SM_STATE_QUEUE_FULL] = {
		[AP_SM_EVENT_POLL] = ap_sm_read,
		[AP_SM_EVENT_TIMEOUT] = ap_sm_reset,
453 454 455
	},
};

456
enum ap_sm_wait ap_sm_event(struct ap_queue *aq, enum ap_sm_event event)
457
{
458 459
	if (aq->config && !aq->chkstop &&
	    aq->dev_state > AP_DEV_STATE_UNINITIATED)
460 461 462
		return ap_jumptable[aq->sm_state][event](aq);
	else
		return AP_SM_WAIT_NONE;
463 464
}

465
enum ap_sm_wait ap_sm_event_loop(struct ap_queue *aq, enum ap_sm_event event)
466
{
467
	enum ap_sm_wait wait;
468

469
	while ((wait = ap_sm_event(aq, event)) == AP_SM_WAIT_AGAIN)
470 471 472 473 474 475 476
		;
	return wait;
}

/*
 * AP queue related attributes.
 */
477 478 479
static ssize_t request_count_show(struct device *dev,
				  struct device_attribute *attr,
				  char *buf)
480 481
{
	struct ap_queue *aq = to_ap_queue(dev);
482
	bool valid = false;
483
	u64 req_cnt;
484 485

	spin_lock_bh(&aq->lock);
486 487 488 489
	if (aq->dev_state > AP_DEV_STATE_UNINITIATED) {
		req_cnt = aq->total_request_count;
		valid = true;
	}
490
	spin_unlock_bh(&aq->lock);
491 492 493 494 495

	if (valid)
		return scnprintf(buf, PAGE_SIZE, "%llu\n", req_cnt);
	else
		return scnprintf(buf, PAGE_SIZE, "-\n");
496 497
}

498 499 500
static ssize_t request_count_store(struct device *dev,
				   struct device_attribute *attr,
				   const char *buf, size_t count)
501 502 503 504 505 506 507 508 509 510
{
	struct ap_queue *aq = to_ap_queue(dev);

	spin_lock_bh(&aq->lock);
	aq->total_request_count = 0;
	spin_unlock_bh(&aq->lock);

	return count;
}

511
static DEVICE_ATTR_RW(request_count);
512

513 514
static ssize_t requestq_count_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
515 516 517 518 519
{
	struct ap_queue *aq = to_ap_queue(dev);
	unsigned int reqq_cnt = 0;

	spin_lock_bh(&aq->lock);
520 521
	if (aq->dev_state > AP_DEV_STATE_UNINITIATED)
		reqq_cnt = aq->requestq_count;
522
	spin_unlock_bh(&aq->lock);
523
	return scnprintf(buf, PAGE_SIZE, "%d\n", reqq_cnt);
524 525
}

526
static DEVICE_ATTR_RO(requestq_count);
527

528 529
static ssize_t pendingq_count_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
530 531 532 533 534
{
	struct ap_queue *aq = to_ap_queue(dev);
	unsigned int penq_cnt = 0;

	spin_lock_bh(&aq->lock);
535 536
	if (aq->dev_state > AP_DEV_STATE_UNINITIATED)
		penq_cnt = aq->pendingq_count;
537
	spin_unlock_bh(&aq->lock);
538
	return scnprintf(buf, PAGE_SIZE, "%d\n", penq_cnt);
539 540
}

541
static DEVICE_ATTR_RO(pendingq_count);
542

543 544
static ssize_t reset_show(struct device *dev,
			  struct device_attribute *attr, char *buf)
545 546 547 548 549
{
	struct ap_queue *aq = to_ap_queue(dev);
	int rc = 0;

	spin_lock_bh(&aq->lock);
550 551 552
	switch (aq->sm_state) {
	case AP_SM_STATE_RESET_START:
	case AP_SM_STATE_RESET_WAIT:
553
		rc = scnprintf(buf, PAGE_SIZE, "Reset in progress.\n");
554
		break;
555 556
	case AP_SM_STATE_WORKING:
	case AP_SM_STATE_QUEUE_FULL:
557
		rc = scnprintf(buf, PAGE_SIZE, "Reset Timer armed.\n");
558 559
		break;
	default:
560
		rc = scnprintf(buf, PAGE_SIZE, "No Reset Timer set.\n");
561 562 563 564 565
	}
	spin_unlock_bh(&aq->lock);
	return rc;
}

566 567 568 569 570 571 572 573
static ssize_t reset_store(struct device *dev,
			   struct device_attribute *attr,
			   const char *buf, size_t count)
{
	struct ap_queue *aq = to_ap_queue(dev);

	spin_lock_bh(&aq->lock);
	__ap_flush_queue(aq);
574 575
	aq->sm_state = AP_SM_STATE_RESET_START;
	ap_wait(ap_sm_event(aq, AP_SM_EVENT_POLL));
576 577
	spin_unlock_bh(&aq->lock);

578 579
	AP_DBF_INFO("%s reset queue=%02x.%04x triggered by user\n",
		    __func__, AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid));
580 581 582 583 584

	return count;
}

static DEVICE_ATTR_RW(reset);
585

586 587
static ssize_t interrupt_show(struct device *dev,
			      struct device_attribute *attr, char *buf)
588 589 590 591 592
{
	struct ap_queue *aq = to_ap_queue(dev);
	int rc = 0;

	spin_lock_bh(&aq->lock);
593
	if (aq->sm_state == AP_SM_STATE_SETIRQ_WAIT)
594
		rc = scnprintf(buf, PAGE_SIZE, "Enable Interrupt pending.\n");
595
	else if (aq->interrupt)
596
		rc = scnprintf(buf, PAGE_SIZE, "Interrupts enabled.\n");
597
	else
598
		rc = scnprintf(buf, PAGE_SIZE, "Interrupts disabled.\n");
599 600 601 602
	spin_unlock_bh(&aq->lock);
	return rc;
}

603
static DEVICE_ATTR_RO(interrupt);
604

605
static ssize_t config_show(struct device *dev,
H
Harald Freudenberger 已提交
606
			   struct device_attribute *attr, char *buf)
607 608 609 610 611 612 613 614 615 616 617 618
{
	struct ap_queue *aq = to_ap_queue(dev);
	int rc;

	spin_lock_bh(&aq->lock);
	rc = scnprintf(buf, PAGE_SIZE, "%d\n", aq->config ? 1 : 0);
	spin_unlock_bh(&aq->lock);
	return rc;
}

static DEVICE_ATTR_RO(config);

619 620 621 622 623 624 625 626 627 628 629 630 631 632
static ssize_t chkstop_show(struct device *dev,
			    struct device_attribute *attr, char *buf)
{
	struct ap_queue *aq = to_ap_queue(dev);
	int rc;

	spin_lock_bh(&aq->lock);
	rc = scnprintf(buf, PAGE_SIZE, "%d\n", aq->chkstop ? 1 : 0);
	spin_unlock_bh(&aq->lock);
	return rc;
}

static DEVICE_ATTR_RO(chkstop);

633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694
#ifdef CONFIG_ZCRYPT_DEBUG
static ssize_t states_show(struct device *dev,
			   struct device_attribute *attr, char *buf)
{
	struct ap_queue *aq = to_ap_queue(dev);
	int rc = 0;

	spin_lock_bh(&aq->lock);
	/* queue device state */
	switch (aq->dev_state) {
	case AP_DEV_STATE_UNINITIATED:
		rc = scnprintf(buf, PAGE_SIZE, "UNINITIATED\n");
		break;
	case AP_DEV_STATE_OPERATING:
		rc = scnprintf(buf, PAGE_SIZE, "OPERATING");
		break;
	case AP_DEV_STATE_SHUTDOWN:
		rc = scnprintf(buf, PAGE_SIZE, "SHUTDOWN");
		break;
	case AP_DEV_STATE_ERROR:
		rc = scnprintf(buf, PAGE_SIZE, "ERROR");
		break;
	default:
		rc = scnprintf(buf, PAGE_SIZE, "UNKNOWN");
	}
	/* state machine state */
	if (aq->dev_state) {
		switch (aq->sm_state) {
		case AP_SM_STATE_RESET_START:
			rc += scnprintf(buf + rc, PAGE_SIZE - rc,
					" [RESET_START]\n");
			break;
		case AP_SM_STATE_RESET_WAIT:
			rc += scnprintf(buf + rc, PAGE_SIZE - rc,
					" [RESET_WAIT]\n");
			break;
		case AP_SM_STATE_SETIRQ_WAIT:
			rc += scnprintf(buf + rc, PAGE_SIZE - rc,
					" [SETIRQ_WAIT]\n");
			break;
		case AP_SM_STATE_IDLE:
			rc += scnprintf(buf + rc, PAGE_SIZE - rc,
					" [IDLE]\n");
			break;
		case AP_SM_STATE_WORKING:
			rc += scnprintf(buf + rc, PAGE_SIZE - rc,
					" [WORKING]\n");
			break;
		case AP_SM_STATE_QUEUE_FULL:
			rc += scnprintf(buf + rc, PAGE_SIZE - rc,
					" [FULL]\n");
			break;
		default:
			rc += scnprintf(buf + rc, PAGE_SIZE - rc,
					" [UNKNOWN]\n");
		}
	}
	spin_unlock_bh(&aq->lock);

	return rc;
}
static DEVICE_ATTR_RO(states);
695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737

static ssize_t last_err_rc_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	struct ap_queue *aq = to_ap_queue(dev);
	int rc;

	spin_lock_bh(&aq->lock);
	rc = aq->last_err_rc;
	spin_unlock_bh(&aq->lock);

	switch (rc) {
	case AP_RESPONSE_NORMAL:
		return scnprintf(buf, PAGE_SIZE, "NORMAL\n");
	case AP_RESPONSE_Q_NOT_AVAIL:
		return scnprintf(buf, PAGE_SIZE, "Q_NOT_AVAIL\n");
	case AP_RESPONSE_RESET_IN_PROGRESS:
		return scnprintf(buf, PAGE_SIZE, "RESET_IN_PROGRESS\n");
	case AP_RESPONSE_DECONFIGURED:
		return scnprintf(buf, PAGE_SIZE, "DECONFIGURED\n");
	case AP_RESPONSE_CHECKSTOPPED:
		return scnprintf(buf, PAGE_SIZE, "CHECKSTOPPED\n");
	case AP_RESPONSE_BUSY:
		return scnprintf(buf, PAGE_SIZE, "BUSY\n");
	case AP_RESPONSE_INVALID_ADDRESS:
		return scnprintf(buf, PAGE_SIZE, "INVALID_ADDRESS\n");
	case AP_RESPONSE_OTHERWISE_CHANGED:
		return scnprintf(buf, PAGE_SIZE, "OTHERWISE_CHANGED\n");
	case AP_RESPONSE_Q_FULL:
		return scnprintf(buf, PAGE_SIZE, "Q_FULL/NO_PENDING_REPLY\n");
	case AP_RESPONSE_INDEX_TOO_BIG:
		return scnprintf(buf, PAGE_SIZE, "INDEX_TOO_BIG\n");
	case AP_RESPONSE_NO_FIRST_PART:
		return scnprintf(buf, PAGE_SIZE, "NO_FIRST_PART\n");
	case AP_RESPONSE_MESSAGE_TOO_BIG:
		return scnprintf(buf, PAGE_SIZE, "MESSAGE_TOO_BIG\n");
	case AP_RESPONSE_REQ_FAC_NOT_INST:
		return scnprintf(buf, PAGE_SIZE, "REQ_FAC_NOT_INST\n");
	default:
		return scnprintf(buf, PAGE_SIZE, "response code %d\n", rc);
	}
}
static DEVICE_ATTR_RO(last_err_rc);
738 739
#endif

740 741 742 743 744 745
static struct attribute *ap_queue_dev_attrs[] = {
	&dev_attr_request_count.attr,
	&dev_attr_requestq_count.attr,
	&dev_attr_pendingq_count.attr,
	&dev_attr_reset.attr,
	&dev_attr_interrupt.attr,
746
	&dev_attr_config.attr,
747
	&dev_attr_chkstop.attr,
748 749
#ifdef CONFIG_ZCRYPT_DEBUG
	&dev_attr_states.attr,
750
	&dev_attr_last_err_rc.attr,
751
#endif
752 753 754 755 756 757 758 759 760 761 762 763
	NULL
};

static struct attribute_group ap_queue_dev_attr_group = {
	.attrs = ap_queue_dev_attrs
};

static const struct attribute_group *ap_queue_dev_attr_groups[] = {
	&ap_queue_dev_attr_group,
	NULL
};

764
static struct device_type ap_queue_type = {
765 766 767 768 769 770
	.name = "ap_queue",
	.groups = ap_queue_dev_attr_groups,
};

static void ap_queue_device_release(struct device *dev)
{
771 772
	struct ap_queue *aq = to_ap_queue(dev);

773 774 775 776
	spin_lock_bh(&ap_queues_lock);
	hash_del(&aq->hnode);
	spin_unlock_bh(&ap_queues_lock);

777
	kfree(aq);
778 779 780 781 782 783 784 785 786 787 788 789 790
}

struct ap_queue *ap_queue_create(ap_qid_t qid, int device_type)
{
	struct ap_queue *aq;

	aq = kzalloc(sizeof(*aq), GFP_KERNEL);
	if (!aq)
		return NULL;
	aq->ap_dev.device.release = ap_queue_device_release;
	aq->ap_dev.device.type = &ap_queue_type;
	aq->ap_dev.device_type = device_type;
	aq->qid = qid;
791
	aq->interrupt = false;
792 793 794
	spin_lock_init(&aq->lock);
	INIT_LIST_HEAD(&aq->pendingq);
	INIT_LIST_HEAD(&aq->requestq);
795
	timer_setup(&aq->timeout, ap_request_timeout, 0);
796 797 798 799 800 801 802 803 804

	return aq;
}

void ap_queue_init_reply(struct ap_queue *aq, struct ap_message *reply)
{
	aq->reply = reply;

	spin_lock_bh(&aq->lock);
805
	ap_wait(ap_sm_event(aq, AP_SM_EVENT_POLL));
806 807 808 809 810 811 812 813 814
	spin_unlock_bh(&aq->lock);
}
EXPORT_SYMBOL(ap_queue_init_reply);

/**
 * ap_queue_message(): Queue a request to an AP device.
 * @aq: The AP device to queue the message to
 * @ap_msg: The message that is to be added
 */
815
int ap_queue_message(struct ap_queue *aq, struct ap_message *ap_msg)
816
{
817 818 819
	int rc = 0;

	/* msg needs to have a valid receive-callback */
820 821 822
	BUG_ON(!ap_msg->receive);

	spin_lock_bh(&aq->lock);
823 824 825 826 827 828 829

	/* only allow to queue new messages if device state is ok */
	if (aq->dev_state == AP_DEV_STATE_OPERATING) {
		list_add_tail(&ap_msg->list, &aq->requestq);
		aq->requestq_count++;
		aq->total_request_count++;
		atomic64_inc(&aq->card->total_request_count);
H
Harald Freudenberger 已提交
830
	} else {
831
		rc = -ENODEV;
H
Harald Freudenberger 已提交
832
	}
833

834
	/* Send/receive as many request from the queue as possible. */
835
	ap_wait(ap_sm_event_loop(aq, AP_SM_EVENT_POLL));
836

837
	spin_unlock_bh(&aq->lock);
838 839

	return rc;
840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893
}
EXPORT_SYMBOL(ap_queue_message);

/**
 * ap_cancel_message(): Cancel a crypto request.
 * @aq: The AP device that has the message queued
 * @ap_msg: The message that is to be removed
 *
 * Cancel a crypto request. This is done by removing the request
 * from the device pending or request queue. Note that the
 * request stays on the AP queue. When it finishes the message
 * reply will be discarded because the psmid can't be found.
 */
void ap_cancel_message(struct ap_queue *aq, struct ap_message *ap_msg)
{
	struct ap_message *tmp;

	spin_lock_bh(&aq->lock);
	if (!list_empty(&ap_msg->list)) {
		list_for_each_entry(tmp, &aq->pendingq, list)
			if (tmp->psmid == ap_msg->psmid) {
				aq->pendingq_count--;
				goto found;
			}
		aq->requestq_count--;
found:
		list_del_init(&ap_msg->list);
	}
	spin_unlock_bh(&aq->lock);
}
EXPORT_SYMBOL(ap_cancel_message);

/**
 * __ap_flush_queue(): Flush requests.
 * @aq: Pointer to the AP queue
 *
 * Flush all requests from the request/pending queue of an AP device.
 */
static void __ap_flush_queue(struct ap_queue *aq)
{
	struct ap_message *ap_msg, *next;

	list_for_each_entry_safe(ap_msg, next, &aq->pendingq, list) {
		list_del_init(&ap_msg->list);
		aq->pendingq_count--;
		ap_msg->rc = -EAGAIN;
		ap_msg->receive(aq, ap_msg, NULL);
	}
	list_for_each_entry_safe(ap_msg, next, &aq->requestq, list) {
		list_del_init(&ap_msg->list);
		aq->requestq_count--;
		ap_msg->rc = -EAGAIN;
		ap_msg->receive(aq, ap_msg, NULL);
	}
894
	aq->queue_count = 0;
895 896 897 898 899 900 901 902 903 904
}

void ap_flush_queue(struct ap_queue *aq)
{
	spin_lock_bh(&aq->lock);
	__ap_flush_queue(aq);
	spin_unlock_bh(&aq->lock);
}
EXPORT_SYMBOL(ap_flush_queue);

905
void ap_queue_prepare_remove(struct ap_queue *aq)
906
{
907 908 909
	spin_lock_bh(&aq->lock);
	/* flush queue */
	__ap_flush_queue(aq);
910 911
	/* move queue device state to SHUTDOWN in progress */
	aq->dev_state = AP_DEV_STATE_SHUTDOWN;
912
	spin_unlock_bh(&aq->lock);
913
	del_timer_sync(&aq->timeout);
914
}
915

916 917 918
void ap_queue_remove(struct ap_queue *aq)
{
	/*
919 920 921 922
	 * all messages have been flushed and the device state
	 * is SHUTDOWN. Now reset with zero which also clears
	 * the irq registration and move the device state
	 * to the initial value AP_DEV_STATE_UNINITIATED.
923
	 */
924 925
	spin_lock_bh(&aq->lock);
	ap_zapq(aq->qid);
926
	aq->dev_state = AP_DEV_STATE_UNINITIATED;
927
	spin_unlock_bh(&aq->lock);
928
}
929

930
void ap_queue_init_state(struct ap_queue *aq)
931 932
{
	spin_lock_bh(&aq->lock);
933
	aq->dev_state = AP_DEV_STATE_OPERATING;
934
	aq->sm_state = AP_SM_STATE_RESET_START;
935
	aq->last_err_rc = 0;
936
	ap_wait(ap_sm_event(aq, AP_SM_EVENT_POLL));
937 938
	spin_unlock_bh(&aq->lock);
}
939
EXPORT_SYMBOL(ap_queue_init_state);