/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Channel Subsystem tests
 *
 * Copyright (c) 2020 IBM Corp
 *
 * Authors:
 *  Pierre Morel <pmorel@linux.ibm.com>
 */

#include <libcflat.h>
#include <alloc_phys.h>
#include <asm/page.h>
#include <string.h>
#include <interrupt.h>
#include <asm/arch_def.h>

#include <css.h>

#define DEFAULT_CU_TYPE		0x3832 /* virtio-ccw */
static unsigned long cu_type = DEFAULT_CU_TYPE;

static int test_device_sid;
static struct senseid senseid;

static void test_enumerate(void)
{
	test_device_sid = css_enumerate();
	if (test_device_sid & SCHID_ONE) {
		report(1, "Schid of first I/O device: 0x%08x", test_device_sid);
		return;
	}
	report(0, "No I/O device found");
}

static void test_enable(void)
{
	int cc;

	if (!test_device_sid) {
		report_skip("No device");
		return;
	}

	cc = css_enable(test_device_sid, IO_SCH_ISC);

	report(cc == 0, "Enable subchannel %08x", test_device_sid);
}

/*
 * test_sense
 * Pre-requisites:
 * - We need the test device as the first recognized
 *   device by the enumeration.
 */
static void test_sense(void)
{
	int ret;
	int len;

	if (!test_device_sid) {
		report_skip("No device");
		return;
	}

	ret = css_enable(test_device_sid, IO_SCH_ISC);
	if (ret) {
		report(0, "Could not enable the subchannel: %08x",
		       test_device_sid);
		return;
	}

	ret = register_io_int_func(css_irq_io);
	if (ret) {
		report(0, "Could not register IRQ handler");
		return;
	}

	lowcore_ptr->io_int_param = 0;

	memset(&senseid, 0, sizeof(senseid));
	ret = start_single_ccw(test_device_sid, CCW_CMD_SENSE_ID,
			       &senseid, sizeof(senseid), CCW_F_SLI);
	if (ret)
		goto error;

	if (wait_and_check_io_completion(test_device_sid) < 0)
		goto error;

	/* Test transfer completion */
	report_prefix_push("ssch transfer completion");

	ret = css_residual_count(test_device_sid);

	if (ret < 0) {
		report_info("no valid residual count");
	} else if (ret != 0) {
		len = sizeof(senseid) - ret;
		if (ret && len < CSS_SENSEID_COMMON_LEN) {
			report(0, "transferred a too short length: %d", ret);
			goto error;
		} else if (ret && len)
			report_info("transferred a shorter length: %d", len);
	}

	if (senseid.reserved != 0xff) {
		report(0, "transferred garbage: 0x%02x", senseid.reserved);
		goto error;
	}

	report_prefix_pop();

	report_info("reserved 0x%02x cu_type 0x%04x cu_model 0x%02x dev_type 0x%04x dev_model 0x%02x",
		    senseid.reserved, senseid.cu_type, senseid.cu_model,
		    senseid.dev_type, senseid.dev_model);

	report(senseid.cu_type == cu_type, "cu_type expected 0x%04x got 0x%04x",
	       (uint16_t) cu_type, senseid.cu_type);

error:
	unregister_io_int_func(css_irq_io);
}

static struct {
	const char *name;
	void (*func)(void);
} tests[] = {
	{ "enumerate (stsch)", test_enumerate },
	{ "enable (msch)", test_enable },
	{ "sense (ssch/tsch)", test_sense },
	{ NULL, NULL }
};

int main(int argc, char *argv[])
{
	int i;

	report_prefix_push("Channel Subsystem");
	enable_io_isc(0x80 >> IO_SCH_ISC);
	for (i = 0; tests[i].name; i++) {
		report_prefix_push(tests[i].name);
		tests[i].func();
		report_prefix_pop();
	}
	report_prefix_pop();

	return report_summary();
}
