drivers/s390/cio/ioasm.c

Source file repositories/reference/linux-study-clean/drivers/s390/cio/ioasm.c

File Facts

System
Linux kernel
Corpus path
drivers/s390/cio/ioasm.c
Extension
.c
Size
5548 bytes
Lines
307
Domain
Driver Families
Bucket
drivers/s390
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0
/*
 * Channel subsystem I/O instructions.
 */

#include <linux/export.h>

#include <asm/asm-extable.h>
#include <asm/chpid.h>
#include <asm/schid.h>
#include <asm/asm.h>
#include <asm/crw.h>

#include "ioasm.h"
#include "orb.h"
#include "cio.h"
#include "cio_inject.h"

static inline int __stsch(struct subchannel_id schid, struct schib *addr)
{
	unsigned long r1 = *(unsigned int *)&schid;
	int ccode, exception;

	exception = 1;
	asm_inline volatile(
		"	lgr	1,%[r1]\n"
		"	stsch	%[addr]\n"
		"0:	lhi	%[exc],0\n"
		"1:\n"
		CC_IPM(cc)
		EX_TABLE(0b, 1b)
		: CC_OUT(cc, ccode), [addr] "=Q" (*addr), [exc] "+d" (exception)
		: [r1] "d" (r1)
		: CC_CLOBBER_LIST("1"));
	return exception ? -EIO : CC_TRANSFORM(ccode);
}

int stsch(struct subchannel_id schid, struct schib *addr)
{
	int ccode;

	ccode = __stsch(schid, addr);
	trace_s390_cio_stsch(schid, addr, ccode);

	return ccode;
}
EXPORT_SYMBOL(stsch);

static inline int __msch(struct subchannel_id schid, struct schib *addr)
{
	unsigned long r1 = *(unsigned int *)&schid;
	int ccode, exception;

	exception = 1;
	asm_inline volatile(
		"	lgr	1,%[r1]\n"
		"	msch	%[addr]\n"
		"0:	lhi	%[exc],0\n"
		"1:\n"
		CC_IPM(cc)
		EX_TABLE(0b, 1b)
		: CC_OUT(cc, ccode), [exc] "+d" (exception)
		: [r1] "d" (r1), [addr] "Q" (*addr)
		: CC_CLOBBER_LIST("1"));
	return exception ? -EIO : CC_TRANSFORM(ccode);
}

int msch(struct subchannel_id schid, struct schib *addr)
{
	int ccode;

	ccode = __msch(schid, addr);
	trace_s390_cio_msch(schid, addr, ccode);

	return ccode;
}

static inline int __tsch(struct subchannel_id schid, struct irb *addr)
{
	unsigned long r1 = *(unsigned int *)&schid;
	int ccode;

	asm volatile(
		"	lgr	1,%[r1]\n"
		"	tsch	%[addr]\n"
		CC_IPM(cc)
		: CC_OUT(cc, ccode), [addr] "=Q" (*addr)
		: [r1] "d" (r1)
		: CC_CLOBBER_LIST("1"));
	return CC_TRANSFORM(ccode);

Annotation

Implementation Notes