qdio_main.c 45.9 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
Jan Glauber's avatar
Jan Glauber committed
2 3 4
/*
 * Linux for s390 qdio support, buffer handling, qdio API and module support.
 *
5
 * Copyright IBM Corp. 2000, 2008
Jan Glauber's avatar
Jan Glauber committed
6 7 8 9 10 11 12 13 14
 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>
 *	      Jan Glauber <jang@linux.vnet.ibm.com>
 * 2.6 cio integration by Cornelia Huck <cornelia.huck@de.ibm.com>
 */
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/delay.h>
15
#include <linux/gfp.h>
16
#include <linux/io.h>
Arun Sharma's avatar
Arun Sharma committed
17
#include <linux/atomic.h>
Jan Glauber's avatar
Jan Glauber committed
18 19
#include <asm/debug.h>
#include <asm/qdio.h>
20
#include <asm/ipl.h>
Jan Glauber's avatar
Jan Glauber committed
21 22 23 24 25 26 27 28 29 30 31 32

#include "cio.h"
#include "css.h"
#include "device.h"
#include "qdio.h"
#include "qdio_debug.h"

MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>,"\
	"Jan Glauber <jang@linux.vnet.ibm.com>");
MODULE_DESCRIPTION("QDIO base support");
MODULE_LICENSE("GPL");

33 34 35
static inline int do_siga_sync(unsigned long schid,
			       unsigned int out_mask, unsigned int in_mask,
			       unsigned int fc)
Jan Glauber's avatar
Jan Glauber committed
36
{
37 38
	register unsigned long __fc asm ("0") = fc;
	register unsigned long __schid asm ("1") = schid;
Jan Glauber's avatar
Jan Glauber committed
39 40 41 42 43 44 45 46 47 48 49 50 51
	register unsigned long out asm ("2") = out_mask;
	register unsigned long in asm ("3") = in_mask;
	int cc;

	asm volatile(
		"	siga	0\n"
		"	ipm	%0\n"
		"	srl	%0,28\n"
		: "=d" (cc)
		: "d" (__fc), "d" (__schid), "d" (out), "d" (in) : "cc");
	return cc;
}

52 53
static inline int do_siga_input(unsigned long schid, unsigned int mask,
				unsigned int fc)
Jan Glauber's avatar
Jan Glauber committed
54
{
55 56
	register unsigned long __fc asm ("0") = fc;
	register unsigned long __schid asm ("1") = schid;
Jan Glauber's avatar
Jan Glauber committed
57 58 59 60 61 62 63 64
	register unsigned long __mask asm ("2") = mask;
	int cc;

	asm volatile(
		"	siga	0\n"
		"	ipm	%0\n"
		"	srl	%0,28\n"
		: "=d" (cc)
65
		: "d" (__fc), "d" (__schid), "d" (__mask) : "cc");
Jan Glauber's avatar
Jan Glauber committed
66 67 68 69 70 71 72 73 74
	return cc;
}

/**
 * do_siga_output - perform SIGA-w/wt function
 * @schid: subchannel id or in case of QEBSM the subchannel token
 * @mask: which output queues to process
 * @bb: busy bit indicator, set only if SIGA-w/wt could not access a buffer
 * @fc: function code to perform
75
 * @aob: asynchronous operation block
Jan Glauber's avatar
Jan Glauber committed
76
 *
77
 * Returns condition code.
Jan Glauber's avatar
Jan Glauber committed
78 79 80
 * Note: For IQDC unicast queues only the highest priority queue is processed.
 */
static inline int do_siga_output(unsigned long schid, unsigned long mask,
81 82
				 unsigned int *bb, unsigned int fc,
				 unsigned long aob)
Jan Glauber's avatar
Jan Glauber committed
83 84 85 86
{
	register unsigned long __fc asm("0") = fc;
	register unsigned long __schid asm("1") = schid;
	register unsigned long __mask asm("2") = mask;
87
	register unsigned long __aob asm("3") = aob;
88
	int cc;
Jan Glauber's avatar
Jan Glauber committed
89 90 91

	asm volatile(
		"	siga	0\n"
92
		"	ipm	%0\n"
Jan Glauber's avatar
Jan Glauber committed
93
		"	srl	%0,28\n"
94 95 96 97
		: "=d" (cc), "+d" (__fc), "+d" (__aob)
		: "d" (__schid), "d" (__mask)
		: "cc");
	*bb = __fc >> 31;
Jan Glauber's avatar
Jan Glauber committed
98 99 100 101 102 103 104 105 106
	return cc;
}

/**
 * qdio_do_eqbs - extract buffer states for QEBSM
 * @q: queue to manipulate
 * @state: state of the extracted buffers
 * @start: buffer number to start at
 * @count: count of buffers to examine
107
 * @auto_ack: automatically acknowledge buffers
Jan Glauber's avatar
Jan Glauber committed
108
 *
Coly Li's avatar
Coly Li committed
109
 * Returns the number of successfully extracted equal buffer states.
Jan Glauber's avatar
Jan Glauber committed
110 111 112
 * Stops processing if a state is different from the last buffers state.
 */
static int qdio_do_eqbs(struct qdio_q *q, unsigned char *state,
113
			int start, int count, int auto_ack)
Jan Glauber's avatar
Jan Glauber committed
114
{
115
	int tmp_count = count, tmp_start = start, nr = q->nr;
Jan Glauber's avatar
Jan Glauber committed
116 117
	unsigned int ccq = 0;

118
	qperf_inc(q, eqbs);
Jan Glauber's avatar
Jan Glauber committed
119 120 121 122

	if (!q->is_input_q)
		nr += q->irq_ptr->nr_input_qs;
again:
123 124
	ccq = do_eqbs(q->irq_ptr->sch_token, state, nr, &tmp_start, &tmp_count,
		      auto_ack);
125

126 127 128 129 130 131 132
	switch (ccq) {
	case 0:
	case 32:
		/* all done, or next buffer state different */
		return count - tmp_count;
	case 96:
		/* not all buffers processed */
133
		qperf_inc(q, eqbs_partial);
134
		DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "EQBS part:%02x",
135
			tmp_count);
136
		return count - tmp_count;
137 138 139 140 141 142 143 144 145 146 147
	case 97:
		/* no buffer processed */
		DBF_DEV_EVENT(DBF_WARN, q->irq_ptr, "EQBS again:%2d", ccq);
		goto again;
	default:
		DBF_ERROR("%4x ccq:%3d", SCH_NO(q), ccq);
		DBF_ERROR("%4x EQBS ERROR", SCH_NO(q));
		DBF_ERROR("%3d%3d%2d", count, tmp_count, nr);
		q->handler(q->irq_ptr->cdev, QDIO_ERROR_GET_BUF_STATE, q->nr,
			   q->first_to_kick, count, q->irq_ptr->int_parm);
		return 0;
Jan Glauber's avatar
Jan Glauber committed
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
	}
}

/**
 * qdio_do_sqbs - set buffer states for QEBSM
 * @q: queue to manipulate
 * @state: new state of the buffers
 * @start: first buffer number to change
 * @count: how many buffers to change
 *
 * Returns the number of successfully changed buffers.
 * Does retrying until the specified count of buffer states is set or an
 * error occurs.
 */
static int qdio_do_sqbs(struct qdio_q *q, unsigned char state, int start,
			int count)
{
	unsigned int ccq = 0;
	int tmp_count = count, tmp_start = start;
	int nr = q->nr;

169 170
	if (!count)
		return 0;
171
	qperf_inc(q, sqbs);
Jan Glauber's avatar
Jan Glauber committed
172 173 174 175 176

	if (!q->is_input_q)
		nr += q->irq_ptr->nr_input_qs;
again:
	ccq = do_sqbs(q->irq_ptr->sch_token, state, nr, &tmp_start, &tmp_count);
177 178 179 180 181

	switch (ccq) {
	case 0:
	case 32:
		/* all done, or active buffer adapter-owned */
182
		WARN_ON_ONCE(tmp_count);
183
		return count - tmp_count;
184 185
	case 96:
		/* not all buffers processed */
186
		DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "SQBS again:%2d", ccq);
187
		qperf_inc(q, sqbs_partial);
Jan Glauber's avatar
Jan Glauber committed
188
		goto again;
189 190 191 192 193 194 195
	default:
		DBF_ERROR("%4x ccq:%3d", SCH_NO(q), ccq);
		DBF_ERROR("%4x SQBS ERROR", SCH_NO(q));
		DBF_ERROR("%3d%3d%2d", count, tmp_count, nr);
		q->handler(q->irq_ptr->cdev, QDIO_ERROR_SET_BUF_STATE, q->nr,
			   q->first_to_kick, count, q->irq_ptr->int_parm);
		return 0;
Jan Glauber's avatar
Jan Glauber committed
196 197 198
	}
}

199 200 201 202
/*
 * Returns number of examined buffers and their common state in *state.
 * Requested number of buffers-to-examine must be > 0.
 */
Jan Glauber's avatar
Jan Glauber committed
203
static inline int get_buf_states(struct qdio_q *q, unsigned int bufnr,
204
				 unsigned char *state, unsigned int count,
205
				 int auto_ack, int merge_pending)
Jan Glauber's avatar
Jan Glauber committed
206 207
{
	unsigned char __state = 0;
208
	int i = 1;
Jan Glauber's avatar
Jan Glauber committed
209 210

	if (is_qebsm(q))
211
		return qdio_do_eqbs(q, state, bufnr, count, auto_ack);
Jan Glauber's avatar
Jan Glauber committed
212

213 214
	/* get initial state: */
	__state = q->slsb.val[bufnr];
215 216 217 218 219

	/* Bail out early if there is no work on the queue: */
	if (__state & SLSB_OWNER_CU)
		goto out;

220 221 222
	if (merge_pending && __state == SLSB_P_OUTPUT_PENDING)
		__state = SLSB_P_OUTPUT_EMPTY;

223
	for (; i < count; i++) {
Jan Glauber's avatar
Jan Glauber committed
224
		bufnr = next_buf(bufnr);
225 226 227 228 229 230 231 232 233 234

		/* merge PENDING into EMPTY: */
		if (merge_pending &&
		    q->slsb.val[bufnr] == SLSB_P_OUTPUT_PENDING &&
		    __state == SLSB_P_OUTPUT_EMPTY)
			continue;

		/* stop if next state differs from initial state: */
		if (q->slsb.val[bufnr] != __state)
			break;
Jan Glauber's avatar
Jan Glauber committed
235
	}
236 237

out:
Jan Glauber's avatar
Jan Glauber committed
238 239 240 241
	*state = __state;
	return i;
}

242 243
static inline int get_buf_state(struct qdio_q *q, unsigned int bufnr,
				unsigned char *state, int auto_ack)
Jan Glauber's avatar
Jan Glauber committed
244
{
245
	return get_buf_states(q, bufnr, state, 1, auto_ack, 0);
Jan Glauber's avatar
Jan Glauber committed
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
}

/* wrap-around safe setting of slsb states, returns number of changed buffers */
static inline int set_buf_states(struct qdio_q *q, int bufnr,
				 unsigned char state, int count)
{
	int i;

	if (is_qebsm(q))
		return qdio_do_sqbs(q, state, bufnr, count);

	for (i = 0; i < count; i++) {
		xchg(&q->slsb.val[bufnr], state);
		bufnr = next_buf(bufnr);
	}
	return count;
}

static inline int set_buf_state(struct qdio_q *q, int bufnr,
				unsigned char state)
{
	return set_buf_states(q, bufnr, state, 1);
}

/* set slsb states to initial state */
271
static void qdio_init_buf_states(struct qdio_irq *irq_ptr)
Jan Glauber's avatar
Jan Glauber committed
272 273 274 275 276 277 278 279 280 281 282 283
{
	struct qdio_q *q;
	int i;

	for_each_input_queue(irq_ptr, q, i)
		set_buf_states(q, 0, SLSB_P_INPUT_NOT_INIT,
			       QDIO_MAX_BUFFERS_PER_Q);
	for_each_output_queue(irq_ptr, q, i)
		set_buf_states(q, 0, SLSB_P_OUTPUT_NOT_INIT,
			       QDIO_MAX_BUFFERS_PER_Q);
}

284
static inline int qdio_siga_sync(struct qdio_q *q, unsigned int output,
Jan Glauber's avatar
Jan Glauber committed
285 286
			  unsigned int input)
{
287 288
	unsigned long schid = *((u32 *) &q->irq_ptr->schid);
	unsigned int fc = QDIO_SIGA_SYNC;
Jan Glauber's avatar
Jan Glauber committed
289 290
	int cc;

291
	DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-s:%1d", q->nr);
292
	qperf_inc(q, siga_sync);
Jan Glauber's avatar
Jan Glauber committed
293

294 295 296 297 298 299
	if (is_qebsm(q)) {
		schid = q->irq_ptr->sch_token;
		fc |= QDIO_SIGA_QEBSM_FLAG;
	}

	cc = do_siga_sync(schid, output, input, fc);
300
	if (unlikely(cc))
301
		DBF_ERROR("%4x SIGA-S:%2d", SCH_NO(q), cc);
302
	return (cc) ? -EIO : 0;
Jan Glauber's avatar
Jan Glauber committed
303 304
}

305
static inline int qdio_siga_sync_q(struct qdio_q *q)
Jan Glauber's avatar
Jan Glauber committed
306 307 308 309 310 311 312
{
	if (q->is_input_q)
		return qdio_siga_sync(q, 0, q->mask);
	else
		return qdio_siga_sync(q, q->mask, 0);
}

313 314
static int qdio_siga_output(struct qdio_q *q, unsigned int count,
			    unsigned int *busy_bit, unsigned long aob)
Jan Glauber's avatar
Jan Glauber committed
315
{
316 317
	unsigned long schid = *((u32 *) &q->irq_ptr->schid);
	unsigned int fc = QDIO_SIGA_WRITE;
318
	u64 start_time = 0;
319
	int retries = 0, cc;
320

321 322 323 324 325
	if (queue_type(q) == QDIO_IQDIO_QFMT && !multicast_outbound(q)) {
		if (count > 1)
			fc = QDIO_SIGA_WRITEM;
		else if (aob)
			fc = QDIO_SIGA_WRITEQ;
326
	}
Jan Glauber's avatar
Jan Glauber committed
327

328
	if (is_qebsm(q)) {
Jan Glauber's avatar
Jan Glauber committed
329
		schid = q->irq_ptr->sch_token;
330
		fc |= QDIO_SIGA_QEBSM_FLAG;
Jan Glauber's avatar
Jan Glauber committed
331 332
	}
again:
333
	cc = do_siga_output(schid, q->mask, busy_bit, fc, aob);
334 335

	/* hipersocket busy condition */
336
	if (unlikely(*busy_bit)) {
337
		retries++;
338

339
		if (!start_time) {
340
			start_time = get_tod_clock_fast();
341 342
			goto again;
		}
343
		if (get_tod_clock_fast() - start_time < QDIO_BUSY_BIT_PATIENCE)
Jan Glauber's avatar
Jan Glauber committed
344 345
			goto again;
	}
346 347 348 349 350
	if (retries) {
		DBF_DEV_EVENT(DBF_WARN, q->irq_ptr,
			      "%4x cc2 BB1:%1d", SCH_NO(q), q->nr);
		DBF_DEV_EVENT(DBF_WARN, q->irq_ptr, "count:%u", retries);
	}
Jan Glauber's avatar
Jan Glauber committed
351 352 353 354 355
	return cc;
}

static inline int qdio_siga_input(struct qdio_q *q)
{
356 357
	unsigned long schid = *((u32 *) &q->irq_ptr->schid);
	unsigned int fc = QDIO_SIGA_READ;
Jan Glauber's avatar
Jan Glauber committed
358 359
	int cc;

360
	DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-r:%1d", q->nr);
361
	qperf_inc(q, siga_read);
Jan Glauber's avatar
Jan Glauber committed
362

363 364 365 366 367 368
	if (is_qebsm(q)) {
		schid = q->irq_ptr->sch_token;
		fc |= QDIO_SIGA_QEBSM_FLAG;
	}

	cc = do_siga_input(schid, q->mask, fc);
369
	if (unlikely(cc))
370
		DBF_ERROR("%4x SIGA-R:%2d", SCH_NO(q), cc);
371
	return (cc) ? -EIO : 0;
Jan Glauber's avatar
Jan Glauber committed
372 373
}

Jan Glauber's avatar
Jan Glauber committed
374 375 376 377
#define qdio_siga_sync_out(q) qdio_siga_sync(q, ~0U, 0)
#define qdio_siga_sync_all(q) qdio_siga_sync(q, ~0U, ~0U)

static inline void qdio_sync_queues(struct qdio_q *q)
Jan Glauber's avatar
Jan Glauber committed
378
{
Jan Glauber's avatar
Jan Glauber committed
379
	/* PCI capable outbound queues will also be scanned so sync them too */
380
	if (pci_out_supported(q->irq_ptr))
Jan Glauber's avatar
Jan Glauber committed
381 382
		qdio_siga_sync_all(q);
	else
Jan Glauber's avatar
Jan Glauber committed
383 384 385
		qdio_siga_sync_q(q);
}

386 387 388
int debug_get_buf_state(struct qdio_q *q, unsigned int bufnr,
			unsigned char *state)
{
Jan Glauber's avatar
Jan Glauber committed
389 390
	if (need_siga_sync(q))
		qdio_siga_sync_q(q);
391
	return get_buf_state(q, bufnr, state, 0);
392 393 394
}

static inline void qdio_stop_polling(struct qdio_q *q)
Jan Glauber's avatar
Jan Glauber committed
395
{
396
	if (!q->u.in.ack_count)
Jan Glauber's avatar
Jan Glauber committed
397
		return;
398

399
	qperf_inc(q, stop_polling);
Jan Glauber's avatar
Jan Glauber committed
400 401

	/* show the card that we are not polling anymore */
402 403 404
	set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT,
		       q->u.in.ack_count);
	q->u.in.ack_count = 0;
Jan Glauber's avatar
Jan Glauber committed
405 406
}

407
static inline void account_sbals(struct qdio_q *q, unsigned int count)
408
{
409
	int pos;
410 411 412 413 414 415

	q->q_stats.nr_sbal_total += count;
	if (count == QDIO_MAX_BUFFERS_MASK) {
		q->q_stats.nr_sbals[7]++;
		return;
	}
416
	pos = ilog2(count);
417 418 419
	q->q_stats.nr_sbals[pos]++;
}

420 421
static void process_buffer_error(struct qdio_q *q, unsigned int start,
				 int count)
Jan Glauber's avatar
Jan Glauber committed
422
{
423
	q->qdio_error = QDIO_ERROR_SLSB_STATE;
424 425

	/* special handling for no target buffer empty */
426
	if (queue_type(q) == QDIO_IQDIO_QFMT && !q->is_input_q &&
427
	    q->sbal[start]->element[15].sflags == 0x10) {
428
		qperf_inc(q, target_full);
429
		DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "OUTFULL FTC:%02x", start);
430
		return;
431 432
	}

433 434
	DBF_ERROR("%4x BUF ERROR", SCH_NO(q));
	DBF_ERROR((q->is_input_q) ? "IN:%2d" : "OUT:%2d", q->nr);
435
	DBF_ERROR("FTC:%3d C:%3d", start, count);
436
	DBF_ERROR("F14:%2x F15:%2x",
437 438
		  q->sbal[start]->element[14].sflags,
		  q->sbal[start]->element[15].sflags);
439
}
Jan Glauber's avatar
Jan Glauber committed
440

441 442
static inline void inbound_primed(struct qdio_q *q, unsigned int start,
				  int count)
443 444 445
{
	int new;

446
	DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in prim:%1d %02x", q->nr, count);
447 448 449

	/* for QEBSM the ACK was already set by EQBS */
	if (is_qebsm(q)) {
450
		if (!q->u.in.ack_count) {
451
			q->u.in.ack_count = count;
452
			q->u.in.ack_start = start;
453 454 455 456
			return;
		}

		/* delete the previous ACK's */
457
		set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT,
458 459
			       q->u.in.ack_count);
		q->u.in.ack_count = count;
460
		q->u.in.ack_start = start;
461 462 463 464 465 466 467
		return;
	}

	/*
	 * ACK the newest buffer. The ACK will be removed in qdio_stop_polling
	 * or by the next inbound run.
	 */
468
	new = add_buf(start, count - 1);
469
	if (q->u.in.ack_count) {
470 471
		/* reset the previous ACK but first set the new one */
		set_buf_state(q, new, SLSB_P_INPUT_ACK);
472
		set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT);
473
	} else {
474
		q->u.in.ack_count = 1;
475
		set_buf_state(q, new, SLSB_P_INPUT_ACK);
476 477
	}

478
	q->u.in.ack_start = new;
479 480 481
	count--;
	if (!count)
		return;
482
	/* need to change ALL buffers to get more interrupts */
483
	set_buf_states(q, start, SLSB_P_INPUT_NOT_INIT, count);
Jan Glauber's avatar
Jan Glauber committed
484 485
}

486
static int get_inbound_buffer_frontier(struct qdio_q *q, unsigned int start)
Jan Glauber's avatar
Jan Glauber committed
487
{
488
	unsigned char state = 0;
489
	int count;
Jan Glauber's avatar
Jan Glauber committed
490

491
	q->timestamp = get_tod_clock_fast();
492

Jan Glauber's avatar
Jan Glauber committed
493 494 495 496 497
	/*
	 * Don't check 128 buffers, as otherwise qdio_inbound_q_moved
	 * would return 0.
	 */
	count = min(atomic_read(&q->nr_buf_used), QDIO_MAX_BUFFERS_MASK);
498
	if (!count)
499
		return 0;
Jan Glauber's avatar
Jan Glauber committed
500

501 502 503 504
	/*
	 * No siga sync here, as a PCI or we after a thin interrupt
	 * already sync'ed the queues.
	 */
505
	count = get_buf_states(q, start, &state, count, 1, 0);
Jan Glauber's avatar
Jan Glauber committed
506
	if (!count)
507
		return 0;
Jan Glauber's avatar
Jan Glauber committed
508 509 510

	switch (state) {
	case SLSB_P_INPUT_PRIMED:
511
		inbound_primed(q, start, count);
512
		if (atomic_sub_return(count, &q->nr_buf_used) == 0)
513
			qperf_inc(q, inbound_queue_full);
514 515
		if (q->irq_ptr->perf_stat_enabled)
			account_sbals(q, count);
516
		return count;
Jan Glauber's avatar
Jan Glauber committed
517
	case SLSB_P_INPUT_ERROR:
518
		process_buffer_error(q, start, count);
519 520 521 522 523
		/*
		 * Interrupts may be avoided as long as the error is present
		 * so change the buffer state immediately to avoid starvation.
		 */
		set_buf_states(q, start, SLSB_P_INPUT_NOT_INIT, count);
524 525
		if (atomic_sub_return(count, &q->nr_buf_used) == 0)
			qperf_inc(q, inbound_queue_full);
526 527
		if (q->irq_ptr->perf_stat_enabled)
			account_sbals_error(q, count);
528
		return count;
Jan Glauber's avatar
Jan Glauber committed
529 530 531
	case SLSB_CU_INPUT_EMPTY:
	case SLSB_P_INPUT_NOT_INIT:
	case SLSB_P_INPUT_ACK:
532 533
		if (q->irq_ptr->perf_stat_enabled)
			q->q_stats.nr_sbal_nop++;
534
		DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in nop:%1d %#02x",
535
			      q->nr, start);
536
		return 0;
Jan Glauber's avatar
Jan Glauber committed
537
	default:
538
		WARN_ON_ONCE(1);
539
		return 0;
Jan Glauber's avatar
Jan Glauber committed
540 541 542
	}
}

543
static int qdio_inbound_q_moved(struct qdio_q *q, unsigned int start)
Jan Glauber's avatar
Jan Glauber committed
544
{
545
	int count;
Jan Glauber's avatar
Jan Glauber committed
546

547
	count = get_inbound_buffer_frontier(q, start);
Jan Glauber's avatar
Jan Glauber committed
548

549 550
	if (count && !is_thinint_irq(q->irq_ptr) && MACHINE_IS_LPAR)
		q->u.in.timestamp = get_tod_clock();
551 552

	return count;
Jan Glauber's avatar
Jan Glauber committed
553 554
}

555
static inline int qdio_inbound_q_done(struct qdio_q *q, unsigned int start)
Jan Glauber's avatar
Jan Glauber committed
556
{
557
	unsigned char state = 0;
Jan Glauber's avatar
Jan Glauber committed
558 559 560 561

	if (!atomic_read(&q->nr_buf_used))
		return 1;

Jan Glauber's avatar
Jan Glauber committed
562 563
	if (need_siga_sync(q))
		qdio_siga_sync_q(q);
564
	get_buf_state(q, start, &state, 0);
565

566
	if (state == SLSB_P_INPUT_PRIMED || state == SLSB_P_INPUT_ERROR)
567
		/* more work coming */
Jan Glauber's avatar
Jan Glauber committed
568 569
		return 0;

570 571 572 573 574
	if (is_thinint_irq(q->irq_ptr))
		return 1;

	/* don't poll under z/VM */
	if (MACHINE_IS_VM)
Jan Glauber's avatar
Jan Glauber committed
575 576 577 578 579 580
		return 1;

	/*
	 * At this point we know, that inbound first_to_check
	 * has (probably) not moved (see qdio_inbound_processing).
	 */
581
	if (get_tod_clock_fast() > q->u.in.timestamp + QDIO_INPUT_THRESHOLD) {
582
		DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in done:%02x", start);
Jan Glauber's avatar
Jan Glauber committed
583
		return 1;
584
	} else
585 586 587
		return 0;
}

588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619
static inline void qdio_handle_aobs(struct qdio_q *q, int start, int count)
{
	unsigned char state = 0;
	int j, b = start;

	for (j = 0; j < count; ++j) {
		get_buf_state(q, b, &state, 0);
		if (state == SLSB_P_OUTPUT_PENDING) {
			struct qaob *aob = q->u.out.aobs[b];
			if (aob == NULL)
				continue;

			q->u.out.sbal_state[b].flags |=
				QDIO_OUTBUF_STATE_FLAG_PENDING;
			q->u.out.aobs[b] = NULL;
		}
		b = next_buf(b);
	}
}

static inline unsigned long qdio_aob_for_buffer(struct qdio_output_q *q,
					int bufnr)
{
	unsigned long phys_aob = 0;

	if (!q->aobs[bufnr]) {
		struct qaob *aob = qdio_allocate_aob();
		q->aobs[bufnr] = aob;
	}
	if (q->aobs[bufnr]) {
		q->aobs[bufnr]->user1 = (u64) q->sbal_state[bufnr].user;
		phys_aob = virt_to_phys(q->aobs[bufnr]);
620
		WARN_ON_ONCE(phys_aob & 0xFF);
621 622
	}

623
	q->sbal_state[bufnr].flags = 0;
624 625 626
	return phys_aob;
}

627
static void qdio_kick_handler(struct qdio_q *q, unsigned int count)
Jan Glauber's avatar
Jan Glauber committed
628
{
629
	int start = q->first_to_kick;
Jan Glauber's avatar
Jan Glauber committed
630 631 632 633

	if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE))
		return;

634
	if (q->is_input_q) {
635
		qperf_inc(q, inbound_handler);
636
		DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%02x c:%02x", start, count);
637
	} else {
638
		qperf_inc(q, outbound_handler);
639 640
		DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: s:%02x c:%02x",
			      start, count);
641
	}
642 643 644

	q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count,
		   q->irq_ptr->int_parm);
Jan Glauber's avatar
Jan Glauber committed
645 646

	/* for the next time */
647
	q->first_to_kick = add_buf(start, count);
Jan Glauber's avatar
Jan Glauber committed
648 649 650
	q->qdio_error = 0;
}

651 652 653 654 655 656 657 658 659
static inline int qdio_tasklet_schedule(struct qdio_q *q)
{
	if (likely(q->irq_ptr->state == QDIO_IRQ_STATE_ACTIVE)) {
		tasklet_schedule(&q->tasklet);
		return 0;
	}
	return -EPERM;
}

Jan Glauber's avatar
Jan Glauber committed
660 661
static void __qdio_inbound_processing(struct qdio_q *q)
{
662
	unsigned int start = q->first_to_check;
663 664
	int count;

665
	qperf_inc(q, tasklet_inbound);
666

667
	count = qdio_inbound_q_moved(q, start);
668
	if (count == 0)
Jan Glauber's avatar
Jan Glauber committed
669 670
		return;

671 672
	start = add_buf(start, count);
	q->first_to_check = start;
673
	qdio_kick_handler(q, count);
Jan Glauber's avatar
Jan Glauber committed
674

675
	if (!qdio_inbound_q_done(q, start)) {
Jan Glauber's avatar
Jan Glauber committed
676
		/* means poll time is not yet over */
677
		qperf_inc(q, tasklet_inbound_resched);
678
		if (!qdio_tasklet_schedule(q))
679
			return;
680
	}
Jan Glauber's avatar
Jan Glauber committed
681 682 683 684 685 686

	qdio_stop_polling(q);
	/*
	 * We need to check again to not lose initiative after
	 * resetting the ACK state.
	 */
687
	if (!qdio_inbound_q_done(q, start)) {
688
		qperf_inc(q, tasklet_inbound_resched2);
689
		qdio_tasklet_schedule(q);
690
	}
Jan Glauber's avatar
Jan Glauber committed
691 692 693 694 695 696 697 698
}

void qdio_inbound_processing(unsigned long data)
{
	struct qdio_q *q = (struct qdio_q *)data;
	__qdio_inbound_processing(q);
}

699
static int get_outbound_buffer_frontier(struct qdio_q *q, unsigned int start)
Jan Glauber's avatar
Jan Glauber committed
700
{
701
	unsigned char state = 0;
702
	int count;
Jan Glauber's avatar
Jan Glauber committed
703

704
	q->timestamp = get_tod_clock_fast();
705

Jan Glauber's avatar
Jan Glauber committed
706 707
	if (need_siga_sync(q))
		if (((queue_type(q) != QDIO_IQDIO_QFMT) &&
708
		    !pci_out_supported(q->irq_ptr)) ||
Jan Glauber's avatar
Jan Glauber committed
709 710 711
		    (queue_type(q) == QDIO_IQDIO_QFMT &&
		    multicast_outbound(q)))
			qdio_siga_sync_q(q);
Jan Glauber's avatar
Jan Glauber committed
712

713
	count = atomic_read(&q->nr_buf_used);
714
	if (!count)
715
		return 0;
Jan Glauber's avatar
Jan Glauber committed
716

717
	count = get_buf_states(q, start, &state, count, 0, q->u.out.use_cq);
Jan Glauber's avatar
Jan Glauber committed
718
	if (!count)
719
		return 0;
Jan Glauber's avatar
Jan Glauber committed
720 721 722

	switch (state) {
	case SLSB_P_OUTPUT_EMPTY:
723
	case SLSB_P_OUTPUT_PENDING:
Jan Glauber's avatar
Jan Glauber committed
724
		/* the adapter got it */
725 726
		DBF_DEV_EVENT(DBF_INFO, q->irq_ptr,
			"out empty:%1d %02x", q->nr, count);
Jan Glauber's avatar
Jan Glauber committed
727 728

		atomic_sub(count, &q->nr_buf_used);
729 730
		if (q->irq_ptr->perf_stat_enabled)
			account_sbals(q, count);
731
		return count;
Jan Glauber's avatar
Jan Glauber committed
732
	case SLSB_P_OUTPUT_ERROR:
733
		process_buffer_error(q, start, count);
Jan Glauber's avatar
Jan Glauber committed
734
		atomic_sub(count, &q->nr_buf_used);
735 736
		if (q->irq_ptr->perf_stat_enabled)
			account_sbals_error(q, count);
737
		return count;
Jan Glauber's avatar
Jan Glauber committed
738 739
	case SLSB_CU_OUTPUT_PRIMED:
		/* the adapter has not fetched the output yet */
740 741
		if (q->irq_ptr->perf_stat_enabled)
			q->q_stats.nr_sbal_nop++;
742 743
		DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out primed:%1d",
			      q->nr);
744
		return 0;
Jan Glauber's avatar
Jan Glauber committed
745 746
	case SLSB_P_OUTPUT_NOT_INIT:
	case SLSB_P_OUTPUT_HALTED:
747
		return 0;
Jan Glauber's avatar
Jan Glauber committed
748
	default:
749
		WARN_ON_ONCE(1);
750
		return 0;
Jan Glauber's avatar
Jan Glauber committed
751 752 753 754 755 756 757 758 759
	}
}

/* all buffers processed? */
static inline int qdio_outbound_q_done(struct qdio_q *q)
{
	return atomic_read(&q->nr_buf_used) == 0;
}

760
static inline int qdio_outbound_q_moved(struct qdio_q *q, unsigned int start)
Jan Glauber's avatar
Jan Glauber committed
761
{
762
	int count;
Jan Glauber's avatar
Jan Glauber committed
763

764
	count = get_outbound_buffer_frontier(q, start);
Jan Glauber's avatar
Jan Glauber committed
765

766
	if (count) {
767
		DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out moved:%1d", q->nr);
768 769 770
		if (q->u.out.use_cq)
			qdio_handle_aobs(q, start, count);
	}
771 772

	return count;
Jan Glauber's avatar
Jan Glauber committed
773 774
}

775 776
static int qdio_kick_outbound_q(struct qdio_q *q, unsigned int count,
				unsigned long aob)
Jan Glauber's avatar
Jan Glauber committed
777
{
778
	int retries = 0, cc;
779
	unsigned int busy_bit;
Jan Glauber's avatar
Jan Glauber committed
780 781

	if (!need_siga_out(q))
782
		return 0;
Jan Glauber's avatar
Jan Glauber committed
783

784
	DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w:%1d", q->nr);
785
retry:
786
	qperf_inc(q, siga_write);
787

788
	cc = qdio_siga_output(q, count, &busy_bit, aob);
789
	switch (cc) {
Jan Glauber's avatar
Jan Glauber committed
790 791
	case 0:
		break;
792 793
	case 2:
		if (busy_bit) {
794 795 796 797 798
			while (++retries < QDIO_BUSY_BIT_RETRIES) {
				mdelay(QDIO_BUSY_BIT_RETRY_DELAY);
				goto retry;
			}
			DBF_ERROR("%4x cc2 BBC:%1d", SCH_NO(q), q->nr);
799 800
			cc = -EBUSY;
		} else {
801
			DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w cc2:%1d", q->nr);
802 803
			cc = -ENOBUFS;
		}
804 805 806 807
		break;
	case 1:
	case 3:
		DBF_ERROR("%4x SIGA-W:%1d", SCH_NO(q), cc);
808
		cc = -EIO;
809
		break;
Jan Glauber's avatar
Jan Glauber committed
810
	}
811 812 813 814
	if (retries) {
		DBF_ERROR("%4x cc2 BB2:%1d", SCH_NO(q), q->nr);
		DBF_ERROR("count:%u", retries);
	}
815
	return cc;
Jan Glauber's avatar
Jan Glauber committed
816 817 818 819
}

static void __qdio_outbound_processing(struct qdio_q *q)
{
820
	unsigned int start = q->first_to_check;
821 822
	int count;

823
	qperf_inc(q, tasklet_outbound);
824
	WARN_ON_ONCE(atomic_read(&q->nr_buf_used) < 0);
Jan Glauber's avatar
Jan Glauber committed
825

826 827 828
	count = qdio_outbound_q_moved(q, start);
	if (count) {
		q->first_to_check = add_buf(start, count);
829
		qdio_kick_handler(q, count);
830
	}
Jan Glauber's avatar
Jan Glauber committed
831

832 833 834
	if (queue_type(q) == QDIO_ZFCP_QFMT && !pci_out_supported(q->irq_ptr) &&
	    !qdio_outbound_q_done(q))
		goto sched;
Jan Glauber's avatar
Jan Glauber committed
835 836 837 838 839 840

	if (q->u.out.pci_out_enabled)
		return;

	/*
	 * Now we know that queue type is either qeth without pci enabled
841 842
	 * or HiperSockets. Make sure buffer switch from PRIMED to EMPTY
	 * is noticed and outbound_handler is called after some time.
Jan Glauber's avatar
Jan Glauber committed
843 844
	 */
	if (qdio_outbound_q_done(q))
845
		del_timer_sync(&q->u.out.timer);
846
	else
847 848
		if (!timer_pending(&q->u.out.timer) &&
		    likely(q->irq_ptr->state == QDIO_IRQ_STATE_ACTIVE))
Jan Glauber's avatar
Jan Glauber committed
849
			mod_timer(&q->u.out.timer, jiffies + 10 * HZ);
850 851 852
	return;

sched:
853
	qdio_tasklet_schedule(q);
Jan Glauber's avatar
Jan Glauber committed
854 855 856 857 858 859 860 861 862
}

/* outbound tasklet */
void qdio_outbound_processing(unsigned long data)
{
	struct qdio_q *q = (struct qdio_q *)data;
	__qdio_outbound_processing(q);
}

863
void qdio_outbound_timer(struct timer_list *t)
Jan Glauber's avatar
Jan Glauber committed
864
{
865
	struct qdio_q *q = from_timer(q, t, u.out.timer);
866

867
	qdio_tasklet_schedule(q);
Jan Glauber's avatar
Jan Glauber committed
868 869
}

870
static inline void qdio_check_outbound_pci_queues(struct qdio_irq *irq)
Jan Glauber's avatar
Jan Glauber committed
871 872 873 874
{
	struct qdio_q *out;
	int i;

875
	if (!pci_out_supported(irq) || !irq->scan_threshold)
Jan Glauber's avatar
Jan Glauber committed
876 877
		return;

878
	for_each_output_queue(irq, out, i)
Jan Glauber's avatar
Jan Glauber committed
879
		if (!qdio_outbound_q_done(out))
880
			qdio_tasklet_schedule(out);
Jan Glauber's avatar
Jan Glauber committed
881 882
}

883 884
static void __tiqdio_inbound_processing(struct qdio_q *q)
{
885
	unsigned int start = q->first_to_check;
886 887
	int count;

888
	qperf_inc(q, tasklet_inbound);
Jan Glauber's avatar
Jan Glauber committed
889 890
	if (need_siga_sync(q) && need_siga_sync_after_ai(q))
		qdio_sync_queues(q);
891

892 893
	/* The interrupt could be caused by a PCI request: */
	qdio_check_outbound_pci_queues(q->irq_ptr);
894

895
	count = qdio_inbound_q_moved(q, start);
896
	if (count == 0)
897 898
		return;

899 900
	start = add_buf(start, count);
	q->first_to_check = start;
901
	qdio_kick_handler(q, count);
902

903
	if (!qdio_inbound_q_done(q, start)) {
904
		qperf_inc(q, tasklet_inbound_resched);
905
		if (!qdio_tasklet_schedule(q))
906
			return;
907 908 909 910 911 912 913
	}

	qdio_stop_polling(q);
	/*
	 * We need to check again to not lose initiative after
	 * resetting the ACK state.
	 */
914
	if (!qdio_inbound_q_done(q, start)) {
915
		qperf_inc(q, tasklet_inbound_resched2);
916
		qdio_tasklet_schedule(q);
917 918 919 920 921 922 923 924 925
	}
}

void tiqdio_inbound_processing(unsigned long data)
{
	struct qdio_q *q = (struct qdio_q *)data;
	__tiqdio_inbound_processing(q);
}

Jan Glauber's avatar
Jan Glauber committed
926 927 928
static inline void qdio_set_state(struct qdio_irq *irq_ptr,
				  enum qdio_irq_states state)
{
929
	DBF_DEV_EVENT(DBF_INFO, irq_ptr, "newstate: %1d", state);
Jan Glauber's avatar
Jan Glauber committed
930 931 932 933 934

	irq_ptr->state = state;
	mb();
}

935
static void qdio_irq_check_sense(struct qdio_irq *irq_ptr, struct irb *irb)
Jan Glauber's avatar
Jan Glauber committed
936 937
{
	if (irb->esw.esw0.erw.cons) {
938 939 940
		DBF_ERROR("%4x sense:", irq_ptr->schid.sch_no);
		DBF_ERROR_HEX(irb, 64);
		DBF_ERROR_HEX(irb->ecw, 64);
Jan Glauber's avatar
Jan Glauber committed
941 942 943 944 945 946 947 948 949
	}
}

/* PCI interrupt handler */
static void qdio_int_handler_pci(struct qdio_irq *irq_ptr)
{
	int i;
	struct qdio_q *q;

950
	if (unlikely(irq_ptr->state != QDIO_IRQ_STATE_ACTIVE))
951 952
		return;

953 954 955 956 957 958 959
	if (irq_ptr->irq_poll) {
		if (!test_and_set_bit(QDIO_IRQ_DISABLED, &irq_ptr->poll_state))
			irq_ptr->irq_poll(irq_ptr->cdev, irq_ptr->int_parm);
		else
			QDIO_PERF_STAT_INC(irq_ptr, int_discarded);
	} else {
		for_each_input_queue(irq_ptr, q, i)
960 961
			tasklet_schedule(&q->tasklet);
	}
Jan Glauber's avatar
Jan Glauber committed
962

963
	if (!pci_out_supported(irq_ptr) || !irq_ptr->scan_threshold)
Jan Glauber's avatar
Jan Glauber committed
964 965 966 967 968
		return;

	for_each_output_queue(irq_ptr, q, i) {
		if (qdio_outbound_q_done(q))
			continue;
Jan Glauber's avatar
Jan Glauber committed
969
		if (need_siga_sync(q) && need_siga_sync_out_after_pci(q))
Jan Glauber's avatar
Jan Glauber committed
970
			qdio_siga_sync_q(q);
971
		qdio_tasklet_schedule(q);
Jan Glauber's avatar
Jan Glauber committed
972 973 974 975 976 977 978 979
	}
}

static void qdio_handle_activate_check(struct ccw_device *cdev,
				unsigned long intparm, int cstat, int dstat)
{
	struct qdio_irq *irq_ptr = cdev->private->qdio_data;
	struct qdio_q *q;
980
	int count;
Jan Glauber's avatar
Jan Glauber committed
981

982 983 984
	DBF_ERROR("%4x ACT CHECK", irq_ptr->schid.sch_no);
	DBF_ERROR("intp :%lx", intparm);
	DBF_ERROR("ds: %2x cs:%2x", dstat, cstat);
Jan Glauber's avatar
Jan Glauber committed
985 986 987 988 989 990 991 992 993

	if (irq_ptr->nr_input_qs) {
		q = irq_ptr->input_qs[0];
	} else if (irq_ptr->nr_output_qs) {
		q = irq_ptr->output_qs[0];
	} else {
		dump_stack();
		goto no_handler;
	}
994 995

	count = sub_buf(q->first_to_check, q->first_to_kick);
996
	q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE,
997
		   q->nr, q->first_to_kick, count, irq_ptr->int_parm);
Jan Glauber's avatar
Jan Glauber committed
998 999
no_handler:
	qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);
1000 1001 1002 1003 1004
	/*
	 * In case of z/VM LGR (Live Guest Migration) QDIO recovery will happen.
	 * Therefore we call the LGR detection function here.
	 */
	lgr_info_log();
Jan Glauber's avatar
Jan Glauber committed
1005 1006
}

1007 1008
static void qdio_establish_handle_irq(struct ccw_device *cdev, int cstat,
				      int dstat)
Jan Glauber's avatar
Jan Glauber committed
1009 1010 1011
{
	struct qdio_irq *irq_ptr = cdev->private->qdio_data;

1012
	DBF_DEV_EVENT(DBF_INFO, irq_ptr, "qest irq");
Jan Glauber's avatar
Jan Glauber committed
1013

1014
	if (cstat)
Jan Glauber's avatar
Jan Glauber committed
1015
		goto error;
1016
	if (dstat & ~(DEV_STAT_DEV_END | DEV_STAT_CHN_END))
Jan Glauber's avatar
Jan Glauber committed
1017
		goto error;
1018 1019 1020 1021 1022
	if (!(dstat & DEV_STAT_DEV_END))
		goto error;
	qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ESTABLISHED);
	return;

Jan Glauber's avatar
Jan Glauber committed
1023
error:
1024 1025
	DBF_ERROR("%4x EQ:error", irq_ptr->schid.sch_no);
	DBF_ERROR("ds: %2x cs:%2x", dstat, cstat);
Jan Glauber's avatar
Jan Glauber committed
1026 1027 1028 1029 1030 1031 1032 1033
	qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR);
}

/* qdio interrupt handler */
void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm,
		      struct irb *irb)
{
	struct qdio_irq *irq_ptr = cdev->private->qdio_data;
1034
	struct subchannel_id schid;
Jan Glauber's avatar
Jan Glauber committed
1035 1036 1037
	int cstat, dstat;

	if (!intparm || !irq_ptr) {
1038 1039
		ccw_device_get_schid(cdev, &schid);
		DBF_ERROR("qint:%4x", schid.sch_no);
Jan Glauber's avatar
Jan Glauber committed
1040 1041 1042
		return;
	}

1043 1044 1045
	if (irq_ptr->perf_stat_enabled)
		irq_ptr->perf_stat.qdio_int++;

Jan Glauber's avatar
Jan Glauber committed
1046
	if (IS_ERR(irb)) {
1047 1048 1049 1050
		DBF_ERROR("%4x IO error", irq_ptr->schid.sch_no);
		qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR);
		wake_up(&cdev->private->wait_q);
		return;
Jan Glauber's avatar
Jan Glauber committed
1051
	}
1052
	qdio_irq_check_sense(irq_ptr, irb);
Jan Glauber's avatar
Jan Glauber committed
1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068
	cstat = irb->scsw.cmd.cstat;
	dstat = irb->scsw.cmd.dstat;

	switch (irq_ptr->state) {
	case QDIO_IRQ_STATE_INACTIVE:
		qdio_establish_handle_irq(cdev, cstat, dstat);
		break;
	case QDIO_IRQ_STATE_CLEANUP:
		qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
		break;
	case QDIO_IRQ_STATE_ESTABLISHED:
	case QDIO_IRQ_STATE_ACTIVE:
		if (cstat & SCHN_STAT_PCI) {
			qdio_int_handler_pci(irq_ptr);
			return;
		}
1069
		if (cstat || dstat)
Jan Glauber's avatar
Jan Glauber committed
1070 1071
			qdio_handle_activate_check(cdev, intparm, cstat,
						   dstat);
1072
		break;
1073 1074
	case QDIO_IRQ_STATE_STOPPED:
		break;
Jan Glauber's avatar
Jan Glauber committed
1075
	default:
1076
		WARN_ON_ONCE(1);
Jan Glauber's avatar
Jan Glauber committed
1077 1078 1079 1080 1081 1082 1083
	}
	wake_up(&cdev->private->wait_q);
}

/**
 * qdio_get_ssqd_desc - get qdio subchannel description
 * @cdev: ccw device to get description for
1084
 * @data: where to store the ssqd
Jan Glauber's avatar
Jan Glauber committed
1085
 *
1086 1087
 * Returns 0 or an error code. The results of the chsc are stored in the
 * specified structure.
Jan Glauber's avatar
Jan Glauber committed
1088
 */
1089 1090
int qdio_get_ssqd_desc(struct ccw_device *cdev,
		       struct qdio_ssqd_desc *data)
Jan Glauber's avatar
Jan Glauber committed
1091
{
1092
	struct subchannel_id schid;
Jan Glauber's avatar
Jan Glauber committed
1093

1094 1095 1096
	if (!cdev || !cdev->private)
		return -EINVAL;

1097 1098 1099
	ccw_device_get_schid(cdev, &schid);
	DBF_EVENT("get ssqd:%4x", schid.sch_no);
	return qdio_setup_get_ssqd(NULL, &schid, data);
Jan Glauber's avatar
Jan Glauber committed
1100 1101 1102
}
EXPORT_SYMBOL_GPL(qdio_get_ssqd_desc);

1103
static void qdio_shutdown_queues(struct qdio_irq *irq_ptr)
Jan Glauber's avatar
Jan Glauber committed
1104 1105 1106 1107 1108
{
	struct qdio_q *q;
	int i;

	for_each_input_queue(irq_ptr, q, i)
1109
		tasklet_kill(&q->tasklet);
Jan Glauber's avatar
Jan Glauber committed
1110 1111

	for_each_output_queue(irq_ptr, q, i) {
1112
		del_timer_sync(&q->u.out.timer);
1113
		tasklet_kill(&q->tasklet);
Jan Glauber's avatar
Jan Glauber committed
1114 1115 1116 1117 1118 1119 1120 1121 1122 1123
	}
}

/**
 * qdio_shutdown - shut down a qdio subchannel
 * @cdev: associated ccw device
 * @how: use halt or clear to shutdown
 */
int qdio_shutdown(struct ccw_device *cdev, int how)
{
1124
	struct qdio_irq *irq_ptr = cdev->private->qdio_data;
1125
	struct subchannel_id schid;
Jan Glauber's avatar
Jan Glauber committed
1126 1127 1128 1129 1130
	int rc;

	if (!irq_ptr)
		return -ENODEV;

1131
	WARN_ON_ONCE(irqs_disabled());
1132 1133
	ccw_device_get_schid(cdev, &schid);
	DBF_EVENT("qshutdown:%4x", schid.sch_no);
1134

Jan Glauber's avatar
Jan Glauber committed
1135 1136 1137 1138 1139 1140 1141 1142 1143 1144
	mutex_lock(&irq_ptr->setup_mutex);
	/*
	 * Subchannel was already shot down. We cannot prevent being called
	 * twice since cio may trigger a shutdown asynchronously.
	 */
	if (irq_ptr->state == QDIO_IRQ_STATE_INACTIVE) {
		mutex_unlock(&irq_ptr->setup_mutex);
		return 0;
	}

1145 1146 1147 1148 1149 1150
	/*
	 * Indicate that the device is going down. Scheduling the queue
	 * tasklets is forbidden from here on.
	 */
	qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);

1151
	tiqdio_remove_device(irq_ptr);
1152
	qdio_shutdown_queues(irq_ptr);
1153
	qdio_shutdown_debug_entries(irq_ptr);
Jan Glauber's avatar
Jan Glauber committed
1154 1155

	/* cleanup subchannel */
1156
	spin_lock_irq(get_ccwdev_lock(cdev));
1157
	qdio_set_state(irq_ptr, QDIO_IRQ_STATE_CLEANUP);
Jan Glauber's avatar
Jan Glauber committed
1158 1159 1160 1161 1162
	if (how & QDIO_FLAG_CLEANUP_USING_CLEAR)
		rc = ccw_device_clear(cdev, QDIO_DOING_CLEANUP);
	else
		/* default behaviour is halt */
		rc = ccw_device_halt(cdev, QDIO_DOING_CLEANUP);
1163
	spin_unlock_irq(get_ccwdev_lock(cdev));
Jan Glauber's avatar
Jan Glauber committed
1164
	if (rc) {
1165 1166
		DBF_ERROR("%4x SHUTD ERR", irq_ptr->schid.sch_no);
		DBF_ERROR("rc:%4d", rc);
Jan Glauber's avatar
Jan Glauber committed
1167 1168 1169 1170 1171 1172 1173 1174 1175 1176
		goto no_cleanup;
	}

	wait_event_interruptible_timeout(cdev->private->wait_q,
		irq_ptr->state == QDIO_IRQ_STATE_INACTIVE ||
		irq_ptr->state == QDIO_IRQ_STATE_ERR,
		10 * HZ);

no_cleanup:
	qdio_shutdown_thinint(irq_ptr);
1177
	qdio_shutdown_irq(irq_ptr);
Jan Glauber's avatar
Jan Glauber committed
1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192

	qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
	mutex_unlock(&irq_ptr->setup_mutex);
	if (rc)
		return rc;
	return 0;
}
EXPORT_SYMBOL_GPL(qdio_shutdown);

/**
 * qdio_free - free data structures for a qdio subchannel
 * @cdev: associated ccw device
 */
int qdio_free(struct ccw_device *cdev)
{
1193
	struct qdio_irq *irq_ptr = cdev->private->qdio_data;
1194
	struct subchannel_id schid;
1195

Jan Glauber's avatar
Jan Glauber committed
1196 1197 1198
	if (!irq_ptr)
		return -ENODEV;

1199 1200
	ccw_device_get_schid(cdev, &schid);
	DBF_EVENT("qfree:%4x", schid.sch_no);
1201
	DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf abandoned");
Jan Glauber's avatar
Jan Glauber committed
1202
	mutex_lock(&irq_ptr->setup_mutex);
1203

1204
	irq_ptr->debug_area = NULL;
Jan Glauber's avatar
Jan Glauber committed
1205 1206 1207 1208 1209 1210 1211 1212 1213 1214
	cdev->private->qdio_data = NULL;
	mutex_unlock(&irq_ptr->setup_mutex);

	qdio_release_memory(irq_ptr);
	return 0;
}
EXPORT_SYMBOL_GPL(qdio_free);

/**
 * qdio_allocate - allocate qdio queues and associated data
1215 1216 1217
 * @cdev: associated ccw device
 * @no_input_qs: allocate this number of Input Queues
 * @no_output_qs: allocate this number of Output Queues
Jan Glauber's avatar
Jan Glauber committed
1218
 */
1219 1220
int qdio_allocate(struct ccw_device *cdev, unsigned int no_input_qs,
		  unsigned int no_output_qs)
Jan Glauber's avatar
Jan Glauber committed
1221
{
1222
	struct subchannel_id schid;
Jan Glauber's avatar
Jan Glauber committed
1223 1224
	struct qdio_irq *irq_ptr;

1225
	ccw_device_get_schid(cdev, &schid);
1226
	DBF_EVENT("qallocate:%4x", schid.sch_no);
Jan Glauber's avatar
Jan Glauber committed
1227

1228 1229
	if (no_input_qs > QDIO_MAX_QUEUES_PER_IRQ ||
	    no_output_qs > QDIO_MAX_QUEUES_PER_IRQ)
Jan Glauber's avatar
Jan Glauber committed
1230 1231 1232 1233 1234 1235 1236
		return -EINVAL;

	/* irq_ptr must be in GFP_DMA since it contains ccw1.cda */
	irq_ptr = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
	if (!irq_ptr)
		goto out_err;

1237
	irq_ptr->cdev = cdev;
Jan Glauber's avatar
Jan Glauber committed
1238
	mutex_init(&irq_ptr->setup_mutex);
1239
	if (qdio_allocate_dbf(irq_ptr))
1240
		goto out_rel;
Jan Glauber's avatar
Jan Glauber committed
1241

1242 1243 1244
	DBF_DEV_EVENT(DBF_ERR, irq_ptr, "alloc niq:%1u noq:%1u", no_input_qs,
		      no_output_qs);

Jan Glauber's avatar
Jan Glauber committed
1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255
	/*
	 * Allocate a page for the chsc calls in qdio_establish.
	 * Must be pre-allocated since a zfcp recovery will call
	 * qdio_establish. In case of low memory and swap on a zfcp disk
	 * we may not be able to allocate memory otherwise.
	 */
	irq_ptr->chsc_page = get_zeroed_page(GFP_KERNEL);
	if (!irq_ptr->chsc_page)
		goto out_rel;

	/* qdr is used in ccw1.cda which is u32 */
1256
	irq_ptr->qdr = (struct qdr *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
Jan Glauber's avatar
Jan Glauber committed
1257 1258 1259
	if (!irq_ptr->qdr)
		goto out_rel;

1260
	if (qdio_allocate_qs(irq_ptr, no_input_qs, no_output_qs))
Jan Glauber's avatar
Jan Glauber committed
1261 1262
		goto out_rel;

1263
	INIT_LIST_HEAD(&irq_ptr->entry);
1264
	cdev->private->qdio_data = irq_ptr;
Jan Glauber's avatar
Jan Glauber committed
1265 1266 1267 1268 1269 1270 1271 1272 1273
	qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
	return 0;
out_rel:
	qdio_release_memory(irq_ptr);
out_err:
	return -ENOMEM;
}
EXPORT_SYMBOL_GPL(qdio_allocate);

1274 1275 1276 1277 1278 1279 1280 1281 1282 1283
static void qdio_detect_hsicq(struct qdio_irq *irq_ptr)
{
	struct qdio_q *q = irq_ptr->input_qs[0];
	int i, use_cq = 0;

	if (irq_ptr->nr_input_qs > 1 && queue_type(q) == QDIO_IQDIO_QFMT)
		use_cq = 1;

	for_each_output_queue(irq_ptr, q, i) {
		if (use_cq) {
1284 1285
			if (multicast_outbound(q))
				continue;
1286 1287 1288 1289 1290 1291 1292 1293 1294 1295
			if (qdio_enable_async_operation(&q->u.out) < 0) {
				use_cq = 0;
				continue;
			}
		} else
			qdio_disable_async_operation(&q->u.out);
	}
	DBF_EVENT("use_cq:%d", use_cq);
}

1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314
static void qdio_trace_init_data(struct qdio_irq *irq,
				 struct qdio_initialize *data)
{
	DBF_DEV_EVENT(DBF_ERR, irq, "qfmt:%1u", data->q_format);
	DBF_DEV_HEX(irq, data->adapter_name, 8, DBF_ERR);
	DBF_DEV_EVENT(DBF_ERR, irq, "qpff%4x", data->qib_param_field_format);
	DBF_DEV_HEX(irq, &data->qib_param_field, sizeof(void *), DBF_ERR);
	DBF_DEV_HEX(irq, &data->input_slib_elements, sizeof(void *), DBF_ERR);
	DBF_DEV_HEX(irq, &data->output_slib_elements, sizeof(void *), DBF_ERR);
	DBF_DEV_EVENT(DBF_ERR, irq, "niq:%1u noq:%1u", data->no_input_qs,
		      data->no_output_qs);
	DBF_DEV_HEX(irq, &data->input_handler, sizeof(void *), DBF_ERR);
	DBF_DEV_HEX(irq, &data->output_handler, sizeof(void *), DBF_ERR);
	DBF_DEV_HEX(irq, &data->int_parm, sizeof(long), DBF_ERR);
	DBF_DEV_HEX(irq, &data->input_sbal_addr_array, sizeof(void *), DBF_ERR);
	DBF_DEV_HEX(irq, &data->output_sbal_addr_array, sizeof(void *),
		    DBF_ERR);
}

Jan Glauber's avatar
Jan Glauber committed
1315 1316
/**
 * qdio_establish - establish queues on a qdio subchannel
1317
 * @cdev: associated ccw device
Jan Glauber's avatar
Jan Glauber committed
1318 1319
 * @init_data: initialization data
 */
1320 1321
int qdio_establish(struct ccw_device *cdev,
		   struct qdio_initialize *init_data)
Jan Glauber's avatar
Jan Glauber committed
1322
{
1323
	struct qdio_irq *irq_ptr = cdev->private->qdio_data;
1324
	struct subchannel_id schid;
Jan Glauber's avatar
Jan Glauber committed
1325 1326
	int rc;

1327 1328
	ccw_device_get_schid(cdev, &schid);
	DBF_EVENT("qestablish:%4x", schid.sch_no);
1329

Jan Glauber's avatar
Jan Glauber committed
1330 1331 1332
	if (!irq_ptr)
		return -ENODEV;

1333 1334 1335 1336 1337 1338 1339 1340
	if ((init_data->no_input_qs && !init_data->input_handler) ||
	    (init_data->no_output_qs && !init_data->output_handler))
		return -EINVAL;

	if (!init_data->input_sbal_addr_array ||
	    !init_data->output_sbal_addr_array)
		return -EINVAL;

Jan Glauber's avatar
Jan Glauber committed
1341
	mutex_lock(&irq_ptr->setup_mutex);
1342
	qdio_trace_init_data(irq_ptr, init_data);
1343
	qdio_setup_irq(irq_ptr, init_data);
Jan Glauber's avatar
Jan Glauber committed
1344 1345 1346

	rc = qdio_establish_thinint(irq_ptr);
	if (rc) {
1347
		qdio_shutdown_irq(irq_ptr);
Jan Glauber's avatar
Jan Glauber committed
1348 1349 1350 1351 1352 1353 1354 1355 1356 1357
		mutex_unlock(&irq_ptr->setup_mutex);
		return rc;
	}

	/* establish q */
	irq_ptr->ccw.cmd_code = irq_ptr->equeue.cmd;
	irq_ptr->ccw.flags = CCW_FLAG_SLI;
	irq_ptr->ccw.count = irq_ptr->equeue.count;
	irq_ptr->ccw.cda = (u32)((addr_t)irq_ptr->qdr);

1358
	spin_lock_irq(get_ccwdev_lock(cdev));
Jan Glauber's avatar
Jan Glauber committed
1359 1360 1361
	ccw_device_set_options_mask(cdev, 0);

	rc = ccw_device_start(cdev, &irq_ptr->ccw, QDIO_DOING_ESTABLISH, 0, 0);
1362
	spin_unlock_irq(get_ccwdev_lock(cdev));
Jan Glauber's avatar
Jan Glauber committed
1363
	if (rc) {
1364 1365
		DBF_ERROR("%4x est IO ERR", irq_ptr->schid.sch_no);
		DBF_ERROR("rc:%4x", rc);
1366
		qdio_shutdown_thinint(irq_ptr);
1367
		qdio_shutdown_irq(irq_ptr);
Jan Glauber's avatar
Jan Glauber committed
1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383
		mutex_unlock(&irq_ptr->setup_mutex);
		return rc;
	}

	wait_event_interruptible_timeout(cdev->private->wait_q,
		irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED ||
		irq_ptr->state == QDIO_IRQ_STATE_ERR, HZ);

	if (irq_ptr->state != QDIO_IRQ_STATE_ESTABLISHED) {
		mutex_unlock(&irq_ptr->setup_mutex);
		qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR);
		return -EIO;
	}

	qdio_setup_ssqd_info(irq_ptr);

1384 1385
	qdio_detect_hsicq(irq_ptr);

Jan Glauber's avatar
Jan Glauber committed
1386 1387 1388 1389
	/* qebsm is now setup if available, initialize buffer states */
	qdio_init_buf_states(irq_ptr);

	mutex_unlock(&irq_ptr->setup_mutex);
1390 1391
	qdio_print_subchannel_info(irq_ptr);
	qdio_setup_debug_entries(irq_ptr);
Jan Glauber's avatar
Jan Glauber committed
1392 1393 1394 1395 1396 1397 1398 1399 1400 1401
	return 0;
}
EXPORT_SYMBOL_GPL(qdio_establish);

/**
 * qdio_activate - activate queues on a qdio subchannel
 * @cdev: associated cdev
 */
int qdio_activate(struct ccw_device *cdev)
{
1402
	struct qdio_irq *irq_ptr = cdev->private->qdio_data;
1403
	struct subchannel_id schid;
Jan Glauber's avatar
Jan Glauber committed
1404 1405
	int rc;

1406 1407
	ccw_device_get_schid(cdev, &schid);
	DBF_EVENT("qactivate:%4x", schid.sch_no);
1408

Jan Glauber's avatar
Jan Glauber committed
1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422
	if (!irq_ptr)
		return -ENODEV;

	mutex_lock(&irq_ptr->setup_mutex);
	if (irq_ptr->state == QDIO_IRQ_STATE_INACTIVE) {
		rc = -EBUSY;
		goto out;
	}

	irq_ptr->ccw.cmd_code = irq_ptr->aqueue.cmd;
	irq_ptr->ccw.flags = CCW_FLAG_SLI;
	irq_ptr->ccw.count = irq_ptr->aqueue.count;
	irq_ptr->ccw.cda = 0;

1423
	spin_lock_irq(get_ccwdev_lock(cdev));
Jan Glauber's avatar
Jan Glauber committed
1424 1425 1426 1427
	ccw_device_set_options(cdev, CCWDEV_REPORT_ALL);

	rc = ccw_device_start(cdev, &irq_ptr->ccw, QDIO_DOING_ACTIVATE,
			      0, DOIO_DENY_PREFETCH);
1428
	spin_unlock_irq(get_ccwdev_lock(cdev));
Jan Glauber's avatar
Jan Glauber committed
1429
	if (rc) {
1430 1431
		DBF_ERROR("%4x act IO ERR", irq_ptr->schid.sch_no);
		DBF_ERROR("rc:%4x", rc);
Jan Glauber's avatar
Jan Glauber committed
1432
		goto out;
1433
	}
Jan Glauber's avatar
Jan Glauber committed
1434 1435

	if (is_thinint_irq(irq_ptr))
1436
		tiqdio_add_device(irq_ptr);
Jan Glauber's avatar
Jan Glauber committed
1437 1438 1439 1440 1441 1442 1443

	/* wait for subchannel to become active */
	msleep(5);

	switch (irq_ptr->state) {
	case QDIO_IRQ_STATE_STOPPED:
	case QDIO_IRQ_STATE_ERR:
1444 1445
		rc = -EIO;
		break;
Jan Glauber's avatar
Jan Glauber committed
1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481
	default:
		qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ACTIVE);
		rc = 0;
	}
out:
	mutex_unlock(&irq_ptr->setup_mutex);
	return rc;
}
EXPORT_SYMBOL_GPL(qdio_activate);

static inline int buf_in_between(int bufnr, int start, int count)
{
	int end = add_buf(start, count);

	if (end > start) {
		if (bufnr >= start && bufnr < end)
			return 1;
		else
			return 0;
	}

	/* wrap-around case */
	if ((bufnr >= start && bufnr <= QDIO_MAX_BUFFERS_PER_Q) ||
	    (bufnr < end))
		return 1;
	else
		return 0;
}

/**
 * handle_inbound - reset processed input buffers
 * @q: queue containing the buffers
 * @callflags: flags
 * @bufnr: first buffer to process
 * @count: how many buffers are emptied
 */
1482 1483
static int handle_inbound(struct qdio_q *q, unsigned int callflags,
			  int bufnr, int count)
Jan Glauber's avatar
Jan Glauber committed
1484
{
1485
	int diff;
Jan Glauber's avatar
Jan Glauber committed
1486

1487 1488
	qperf_inc(q, inbound_call);

1489
	if (!q->u.in.ack_count)
1490 1491 1492 1493 1494 1495 1496
		goto set;

	/* protect against stop polling setting an ACK for an emptied slsb */
	if (count == QDIO_MAX_BUFFERS_PER_Q) {
		/* overwriting everything, just delete polling status */
		q->u.in.ack_count = 0;
		goto set;
1497
	} else if (buf_in_between(q->u.in.ack_start, bufnr, count)) {
1498
		if (is_qebsm(q)) {
1499
			/* partial overwrite, just update ack_start */
1500
			diff = add_buf(bufnr, count);
1501
			diff = sub_buf(diff, q->u.in.ack_start);
1502 1503 1504 1505 1506
			q->u.in.ack_count -= diff;
			if (q->u.in.ack_count <= 0) {
				q->u.in.ack_count = 0;
				goto set;
			}
1507
			q->u.in.ack_start = add_buf(q->u.in.ack_start, diff);
1508 1509 1510
		} else {
			/* the only ACK will be deleted */
			q->u.in.ack_count = 0;
1511 1512
		}
	}
Jan Glauber's avatar
Jan Glauber committed
1513

1514
set:
Jan Glauber's avatar
Jan Glauber committed
1515
	count = set_buf_states(q, bufnr, SLSB_CU_INPUT_EMPTY, count);
1516
	atomic_add(count, &q->nr_buf_used);
Jan Glauber's avatar
Jan Glauber committed
1517

1518 1519
	if (need_siga_in(q))
		return qdio_siga_input(q);
1520

1521
	return 0;
Jan Glauber's avatar
Jan Glauber committed
1522 1523 1524 1525 1526 1527 1528 1529 1530
}

/**
 * handle_outbound - process filled outbound buffers
 * @q: queue containing the buffers
 * @callflags: flags
 * @bufnr: first buffer to process
 * @count: how many buffers are filled
 */
1531
static int handle_outbound(struct qdio_q *q, unsigned int callflags,
1532
			   unsigned int bufnr, unsigned int count)
Jan Glauber's avatar
Jan Glauber committed
1533
{
1534
	const unsigned int scan_threshold = q->irq_ptr->scan_threshold;
1535
	unsigned char state = 0;
1536
	int used, rc = 0;
Jan Glauber's avatar
Jan Glauber committed
1537

1538
	qperf_inc(q, outbound_call);
Jan Glauber's avatar
Jan Glauber committed
1539 1540 1541 1542

	count = set_buf_states(q, bufnr, SLSB_CU_OUTPUT_PRIMED, count);
	used = atomic_add_return(count, &q->nr_buf_used);

1543 1544 1545
	if (used == QDIO_MAX_BUFFERS_PER_Q)
		qperf_inc(q, outbound_queue_full);

1546
	if (callflags & QDIO_FLAG_PCI_OUT) {
Jan Glauber's avatar
Jan Glauber committed
1547
		q->u.out.pci_out_enabled = 1;
1548
		qperf_inc(q, pci_request_int);
1549
	} else
Jan Glauber's avatar
Jan Glauber committed
1550 1551 1552
		q->u.out.pci_out_enabled = 0;

	if (queue_type(q) == QDIO_IQDIO_QFMT) {
1553 1554
		unsigned long phys_aob = 0;

1555
		if (q->u.out.use_cq && count == 1)
1556
			phys_aob = qdio_aob_for_buffer(&q->u.out, bufnr);
1557

1558
		rc = qdio_kick_outbound_q(q, count, phys_aob);
Jan Glauber's avatar
Jan Glauber committed
1559
	} else if (need_siga_sync(q)) {
1560
		rc = qdio_siga_sync_q(q);
1561 1562 1563 1564 1565
	} else if (count < QDIO_MAX_BUFFERS_PER_Q &&
		   get_buf_state(q, prev_buf(bufnr), &state, 0) > 0 &&
		   state == SLSB_CU_OUTPUT_PRIMED) {
		/* The previous buffer is not processed yet, tack on. */
		qperf_inc(q, fast_requeue);
1566
	} else {
1567
		rc = qdio_kick_outbound_q(q, count, 0);
Jan Glauber's avatar
Jan Glauber committed
1568 1569
	}

1570 1571 1572 1573
	/* Let drivers implement their own completion scanning: */
	if (!scan_threshold)
		return rc;

1574
	/* in case of SIGA errors we must process the error immediately */
1575
	if (used >= scan_threshold || rc)
1576
		qdio_tasklet_schedule(q);
1577 1578
	else
		/* free the SBALs in case of no further traffic */
1579 1580
		if (!timer_pending(&q->u.out.timer) &&
		    likely(q->irq_ptr->state == QDIO_IRQ_STATE_ACTIVE))
1581
			mod_timer(&q->u.out.timer, jiffies + HZ);
1582
	return rc;
Jan Glauber's avatar
Jan Glauber committed
1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593
}

/**
 * do_QDIO - process input or output buffers
 * @cdev: associated ccw_device for the qdio subchannel
 * @callflags: input or output and special flags from the program
 * @q_nr: queue number
 * @bufnr: buffer number
 * @count: how many buffers to process
 */
int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
1594
	    int q_nr, unsigned int bufnr, unsigned int count)
Jan Glauber's avatar
Jan Glauber committed
1595 1596 1597
{
	struct qdio_irq *irq_ptr;

1598
	if (bufnr >= QDIO_MAX_BUFFERS_PER_Q || count > QDIO_MAX_BUFFERS_PER_Q)
Jan Glauber's avatar
Jan Glauber committed
1599 1600 1601 1602 1603 1604
		return -EINVAL;

	irq_ptr = cdev->private->qdio_data;
	if (!irq_ptr)
		return -ENODEV;

1605 1606
	DBF_DEV_EVENT(DBF_INFO, irq_ptr,
		      "do%02x b:%02x c:%02x", callflags, bufnr, count);
Jan Glauber's avatar
Jan Glauber committed
1607 1608

	if (irq_ptr->state != QDIO_IRQ_STATE_ACTIVE)
1609
		return -EIO;
1610 1611
	if (!count)
		return 0;
Jan Glauber's avatar
Jan Glauber committed
1612
	if (callflags & QDIO_FLAG_SYNC_INPUT)
1613 1614
		return handle_inbound(irq_ptr->input_qs[q_nr],
				      callflags, bufnr, count);
Jan Glauber's avatar
Jan Glauber committed
1615
	else if (callflags & QDIO_FLAG_SYNC_OUTPUT)
1616 1617 1618
		return handle_outbound(irq_ptr->output_qs[q_nr],
				       callflags, bufnr, count);
	return -EINVAL;
Jan Glauber's avatar
Jan Glauber committed
1619 1620 1621
}
EXPORT_SYMBOL_GPL(do_QDIO);

1622 1623 1624 1625 1626 1627 1628 1629
/**
 * qdio_start_irq - process input buffers
 * @cdev: associated ccw_device for the qdio subchannel
 *
 * Return codes
 *   0 - success
 *   1 - irqs not started since new data is available
 */
1630
int qdio_start_irq(struct ccw_device *cdev)
1631 1632 1633
{
	struct qdio_q *q;
	struct qdio_irq *irq_ptr = cdev->private->qdio_data;
1634
	unsigned int i;
1635 1636 1637 1638

	if (!irq_ptr)
		return -ENODEV;

1639 1640 1641 1642
	for_each_input_queue(irq_ptr, q, i)
		qdio_stop_polling(q);

	clear_bit(QDIO_IRQ_DISABLED, &irq_ptr->poll_state);
1643 1644 1645 1646 1647

	/*
	 * We need to check again to not lose initiative after
	 * resetting the ACK state.
	 */
1648
	if (test_nonshared_ind(irq_ptr))
1649
		goto rescan;
1650 1651 1652 1653 1654 1655

	for_each_input_queue(irq_ptr, q, i) {
		if (!qdio_inbound_q_done(q, q->first_to_check))
			goto rescan;
	}

1656 1657 1658
	return 0;

rescan:
1659
	if (test_and_set_bit(QDIO_IRQ_DISABLED, &irq_ptr->poll_state))
1660 1661 1662 1663 1664 1665 1666
		return 0;
	else
		return 1;

}
EXPORT_SYMBOL(qdio_start_irq);

1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704
static int __qdio_inspect_queue(struct qdio_q *q, unsigned int *bufnr,
				unsigned int *error)
{
	unsigned int start = q->first_to_check;
	int count;

	count = q->is_input_q ? qdio_inbound_q_moved(q, start) :
				qdio_outbound_q_moved(q, start);
	if (count == 0)
		return 0;

	*bufnr = start;
	*error = q->qdio_error;

	/* for the next time */
	q->first_to_check = add_buf(start, count);
	q->qdio_error = 0;

	return count;
}

int qdio_inspect_queue(struct ccw_device *cdev, unsigned int nr, bool is_input,
		       unsigned int *bufnr, unsigned int *error)
{
	struct qdio_irq *irq_ptr = cdev->private->qdio_data;
	struct qdio_q *q;

	if (!irq_ptr)
		return -ENODEV;
	q = is_input ? irq_ptr->input_qs[nr] : irq_ptr->output_qs[nr];

	if (need_siga_sync(q))
		qdio_siga_sync_q(q);

	return __qdio_inspect_queue(q, bufnr, error);
}
EXPORT_SYMBOL_GPL(qdio_inspect_queue);

1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727
/**
 * qdio_get_next_buffers - process input buffers
 * @cdev: associated ccw_device for the qdio subchannel
 * @nr: input queue number
 * @bufnr: first filled buffer number
 * @error: buffers are in error state
 *
 * Return codes
 *   < 0 - error
 *   = 0 - no new buffers found
 *   > 0 - number of processed buffers
 */
int qdio_get_next_buffers(struct ccw_device *cdev, int nr, int *bufnr,
			  int *error)
{
	struct qdio_q *q;
	struct qdio_irq *irq_ptr = cdev->private->qdio_data;

	if (!irq_ptr)
		return -ENODEV;
	q = irq_ptr->input_qs[nr];

	/*
Jan Glauber's avatar
Jan Glauber committed
1728 1729
	 * Cannot rely on automatic sync after interrupt since queues may
	 * also be examined without interrupt.
1730
	 */
Jan Glauber's avatar
Jan Glauber committed
1731 1732 1733
	if (need_siga_sync(q))
		qdio_sync_queues(q);

1734
	qdio_check_outbound_pci_queues(irq_ptr);
1735 1736 1737 1738 1739

	/* Note: upper-layer MUST stop processing immediately here ... */
	if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE))
		return -EIO;

1740
	return __qdio_inspect_queue(q, bufnr, error);
1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751
}
EXPORT_SYMBOL(qdio_get_next_buffers);

/**
 * qdio_stop_irq - disable interrupt processing for the device
 * @cdev: associated ccw_device for the qdio subchannel
 *
 * Return codes
 *   0 - interrupts were already disabled
 *   1 - interrupts successfully disabled
 */
1752
int qdio_stop_irq(struct ccw_device *cdev)
1753 1754 1755 1756 1757 1758
{
	struct qdio_irq *irq_ptr = cdev->private->qdio_data;

	if (!irq_ptr)
		return -ENODEV;

1759
	if (test_and_set_bit(QDIO_IRQ_DISABLED, &irq_ptr->poll_state))
1760 1761 1762 1763 1764 1765
		return 0;
	else
		return 1;
}
EXPORT_SYMBOL(qdio_stop_irq);

1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853
/**
 * qdio_pnso_brinfo() - perform network subchannel op #0 - bridge info.
 * @schid:		Subchannel ID.
 * @cnc:		Boolean Change-Notification Control
 * @response:		Response code will be stored at this address
 * @cb: 		Callback function will be executed for each element
 *			of the address list
 * @priv:		Pointer to pass to the callback function.
 *
 * Performs "Store-network-bridging-information list" operation and calls
 * the callback function for every entry in the list. If "change-
 * notification-control" is set, further changes in the address list
 * will be reported via the IPA command.
 */
int qdio_pnso_brinfo(struct subchannel_id schid,
		int cnc, u16 *response,
		void (*cb)(void *priv, enum qdio_brinfo_entry_type type,
				void *entry),
		void *priv)
{
	struct chsc_pnso_area *rr;
	int rc;
	u32 prev_instance = 0;
	int isfirstblock = 1;
	int i, size, elems;

	rr = (struct chsc_pnso_area *)get_zeroed_page(GFP_KERNEL);
	if (rr == NULL)
		return -ENOMEM;
	do {
		/* on the first iteration, naihdr.resume_token will be zero */
		rc = chsc_pnso_brinfo(schid, rr, rr->naihdr.resume_token, cnc);
		if (rc != 0 && rc != -EBUSY)
			goto out;
		if (rr->response.code != 1) {
			rc = -EIO;
			continue;
		} else
			rc = 0;

		if (cb == NULL)
			continue;

		size = rr->naihdr.naids;
		elems = (rr->response.length -
				sizeof(struct chsc_header) -
				sizeof(struct chsc_brinfo_naihdr)) /
				size;

		if (!isfirstblock && (rr->naihdr.instance != prev_instance)) {
			/* Inform the caller that they need to scrap */
			/* the data that was already reported via cb */
				rc = -EAGAIN;
				break;
		}
		isfirstblock = 0;
		prev_instance = rr->naihdr.instance;
		for (i = 0; i < elems; i++)
			switch (size) {
			case sizeof(struct qdio_brinfo_entry_l3_ipv6):
				(*cb)(priv, l3_ipv6_addr,
						&rr->entries.l3_ipv6[i]);
				break;
			case sizeof(struct qdio_brinfo_entry_l3_ipv4):
				(*cb)(priv, l3_ipv4_addr,
						&rr->entries.l3_ipv4[i]);
				break;
			case sizeof(struct qdio_brinfo_entry_l2):
				(*cb)(priv, l2_addr_lnid,
						&rr->entries.l2[i]);
				break;
			default:
				WARN_ON_ONCE(1);
				rc = -EIO;
				goto out;
			}
	} while (rr->response.code == 0x0107 ||  /* channel busy */
		  (rr->response.code == 1 && /* list stored */
		   /* resume token is non-zero => list incomplete */
		   (rr->naihdr.resume_token.t1 || rr->naihdr.resume_token.t2)));
	(*response) = rr->response.code;

out:
	free_page((unsigned long)rr);
	return rc;
}
EXPORT_SYMBOL_GPL(qdio_pnso_brinfo);

Jan Glauber's avatar
Jan Glauber committed
1854 1855 1856 1857
static int __init init_QDIO(void)
{
	int rc;

1858
	rc = qdio_debug_init();
Jan Glauber's avatar
Jan Glauber committed
1859 1860
	if (rc)
		return rc;
1861 1862 1863
	rc = qdio_setup_init();
	if (rc)
		goto out_debug;
Jan Glauber's avatar
Jan Glauber committed
1864 1865 1866 1867 1868
	rc = tiqdio_allocate_memory();
	if (rc)
		goto out_cache;
	rc = tiqdio_register_thinints();
	if (rc)
1869
		goto out_ti;
Jan Glauber's avatar
Jan Glauber committed
1870 1871 1872 1873 1874 1875
	return 0;

out_ti:
	tiqdio_free_memory();
out_cache:
	qdio_setup_exit();
1876 1877
out_debug:
	qdio_debug_exit();
Jan Glauber's avatar
Jan Glauber committed
1878 1879 1880 1881 1882 1883 1884 1885
	return rc;
}

static void __exit exit_QDIO(void)
{
	tiqdio_unregister_thinints();
	tiqdio_free_memory();
	qdio_setup_exit();
1886
	qdio_debug_exit();
Jan Glauber's avatar
Jan Glauber committed
1887 1888 1889 1890
}

module_init(init_QDIO);
module_exit(exit_QDIO);