brintos

brintos / linux-shallow public Read only

0
0
Text · 5.0 KiB · acf1edd Raw
307 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Channel subsystem I/O instructions.4 */5 6#include <linux/export.h>7 8#include <asm/asm-extable.h>9#include <asm/chpid.h>10#include <asm/schid.h>11#include <asm/crw.h>12 13#include "ioasm.h"14#include "orb.h"15#include "cio.h"16#include "cio_inject.h"17 18static inline int __stsch(struct subchannel_id schid, struct schib *addr)19{20	unsigned long r1 = *(unsigned int *)&schid;21	int ccode = -EIO;22 23	asm volatile(24		"	lgr	1,%[r1]\n"25		"	stsch	%[addr]\n"26		"0:	ipm	%[cc]\n"27		"	srl	%[cc],28\n"28		"1:\n"29		EX_TABLE(0b, 1b)30		: [cc] "+&d" (ccode), [addr] "=Q" (*addr)31		: [r1] "d" (r1)32		: "cc", "1");33	return ccode;34}35 36int stsch(struct subchannel_id schid, struct schib *addr)37{38	int ccode;39 40	ccode = __stsch(schid, addr);41	trace_s390_cio_stsch(schid, addr, ccode);42 43	return ccode;44}45EXPORT_SYMBOL(stsch);46 47static inline int __msch(struct subchannel_id schid, struct schib *addr)48{49	unsigned long r1 = *(unsigned int *)&schid;50	int ccode = -EIO;51 52	asm volatile(53		"	lgr	1,%[r1]\n"54		"	msch	%[addr]\n"55		"0:	ipm	%[cc]\n"56		"	srl	%[cc],28\n"57		"1:\n"58		EX_TABLE(0b, 1b)59		: [cc] "+&d" (ccode)60		: [r1] "d" (r1), [addr] "Q" (*addr)61		: "cc", "1");62	return ccode;63}64 65int msch(struct subchannel_id schid, struct schib *addr)66{67	int ccode;68 69	ccode = __msch(schid, addr);70	trace_s390_cio_msch(schid, addr, ccode);71 72	return ccode;73}74 75static inline int __tsch(struct subchannel_id schid, struct irb *addr)76{77	unsigned long r1 = *(unsigned int *)&schid;78	int ccode;79 80	asm volatile(81		"	lgr	1,%[r1]\n"82		"	tsch	%[addr]\n"83		"	ipm	%[cc]\n"84		"	srl	%[cc],28"85		: [cc] "=&d" (ccode), [addr] "=Q" (*addr)86		: [r1] "d" (r1)87		: "cc", "1");88	return ccode;89}90 91int tsch(struct subchannel_id schid, struct irb *addr)92{93	int ccode;94 95	ccode = __tsch(schid, addr);96	trace_s390_cio_tsch(schid, addr, ccode);97 98	return ccode;99}100 101static inline int __ssch(struct subchannel_id schid, union orb *addr)102{103	unsigned long r1 = *(unsigned int *)&schid;104	int ccode = -EIO;105 106	asm volatile(107		"	lgr	1,%[r1]\n"108		"	ssch	%[addr]\n"109		"0:	ipm	%[cc]\n"110		"	srl	%[cc],28\n"111		"1:\n"112		EX_TABLE(0b, 1b)113		: [cc] "+&d" (ccode)114		: [r1] "d" (r1), [addr] "Q" (*addr)115		: "cc", "memory", "1");116	return ccode;117}118 119int ssch(struct subchannel_id schid, union orb *addr)120{121	int ccode;122 123	ccode = __ssch(schid, addr);124	trace_s390_cio_ssch(schid, addr, ccode);125 126	return ccode;127}128EXPORT_SYMBOL(ssch);129 130static inline int __csch(struct subchannel_id schid)131{132	unsigned long r1 = *(unsigned int *)&schid;133	int ccode;134 135	asm volatile(136		"	lgr	1,%[r1]\n"137		"	csch\n"138		"	ipm	%[cc]\n"139		"	srl	%[cc],28\n"140		: [cc] "=&d" (ccode)141		: [r1] "d" (r1)142		: "cc", "1");143	return ccode;144}145 146int csch(struct subchannel_id schid)147{148	int ccode;149 150	ccode = __csch(schid);151	trace_s390_cio_csch(schid, ccode);152 153	return ccode;154}155EXPORT_SYMBOL(csch);156 157int tpi(struct tpi_info *addr)158{159	int ccode;160 161	asm volatile(162		"	tpi	%[addr]\n"163		"	ipm	%[cc]\n"164		"	srl	%[cc],28"165		: [cc] "=&d" (ccode), [addr] "=Q" (*addr)166		:167		: "cc");168	trace_s390_cio_tpi(addr, ccode);169 170	return ccode;171}172 173int chsc(void *chsc_area)174{175	typedef struct { char _[4096]; } addr_type;176	int cc = -EIO;177 178	asm volatile(179		"	.insn	rre,0xb25f0000,%[chsc_area],0\n"180		"0:	ipm	%[cc]\n"181		"	srl	%[cc],28\n"182		"1:\n"183		EX_TABLE(0b, 1b)184		: [cc] "+&d" (cc), "+m" (*(addr_type *)chsc_area)185		: [chsc_area] "d" (chsc_area)186		: "cc");187	trace_s390_cio_chsc(chsc_area, cc);188 189	return cc;190}191EXPORT_SYMBOL(chsc);192 193static inline int __rsch(struct subchannel_id schid)194{195	unsigned long r1 = *(unsigned int *)&schid;196	int ccode;197 198	asm volatile(199		"	lgr	1,%[r1]\n"200		"	rsch\n"201		"	ipm	%[cc]\n"202		"	srl	%[cc],28\n"203		: [cc] "=&d" (ccode)204		: [r1] "d" (r1)205		: "cc", "memory", "1");206	return ccode;207}208 209int rsch(struct subchannel_id schid)210{211	int ccode;212 213	ccode = __rsch(schid);214	trace_s390_cio_rsch(schid, ccode);215 216	return ccode;217}218 219static inline int __hsch(struct subchannel_id schid)220{221	unsigned long r1 = *(unsigned int *)&schid;222	int ccode;223 224	asm volatile(225		"	lgr	1,%[r1]\n"226		"	hsch\n"227		"	ipm	%[cc]\n"228		"	srl	%[cc],28\n"229		: [cc] "=&d" (ccode)230		: [r1] "d" (r1)231		: "cc", "1");232	return ccode;233}234 235int hsch(struct subchannel_id schid)236{237	int ccode;238 239	ccode = __hsch(schid);240	trace_s390_cio_hsch(schid, ccode);241 242	return ccode;243}244EXPORT_SYMBOL(hsch);245 246static inline int __xsch(struct subchannel_id schid)247{248	unsigned long r1 = *(unsigned int *)&schid;249	int ccode;250 251	asm volatile(252		"	lgr	1,%[r1]\n"253		"	xsch\n"254		"	ipm	%[cc]\n"255		"	srl	%[cc],28\n"256		: [cc] "=&d" (ccode)257		: [r1] "d" (r1)258		: "cc", "1");259	return ccode;260}261 262int xsch(struct subchannel_id schid)263{264	int ccode;265 266	ccode = __xsch(schid);267	trace_s390_cio_xsch(schid, ccode);268 269	return ccode;270}271 272static inline int __stcrw(struct crw *crw)273{274	int ccode;275 276	asm volatile(277		"	stcrw	%[crw]\n"278		"	ipm	%[cc]\n"279		"	srl	%[cc],28\n"280		: [cc] "=&d" (ccode), [crw] "=Q" (*crw)281		:282		: "cc");283	return ccode;284}285 286static inline int _stcrw(struct crw *crw)287{288#ifdef CONFIG_CIO_INJECT289	if (static_branch_unlikely(&cio_inject_enabled)) {290		if (stcrw_get_injected(crw) == 0)291			return 0;292	}293#endif294 295	return __stcrw(crw);296}297 298int stcrw(struct crw *crw)299{300	int ccode;301 302	ccode = _stcrw(crw);303	trace_s390_cio_stcrw(crw, ccode);304 305	return ccode;306}307