xref: /openbmc/linux/drivers/s390/cio/css.h (revision 9a87ffc99ec8eb8d35eed7c4f816d75f5cc9662e)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
21da177e4SLinus Torvalds #ifndef _CSS_H
31da177e4SLinus Torvalds #define _CSS_H
41da177e4SLinus Torvalds 
5495a5b45SCornelia Huck #include <linux/mutex.h>
61da177e4SLinus Torvalds #include <linux/wait.h>
71da177e4SLinus Torvalds #include <linux/workqueue.h>
8e6b6e10aSPeter Oberparleiter #include <linux/device.h>
9e5854a58SPeter Oberparleiter #include <linux/types.h>
101da177e4SLinus Torvalds 
111da177e4SLinus Torvalds #include <asm/cio.h>
12e5854a58SPeter Oberparleiter #include <asm/chpid.h>
139d92a7e1SCornelia Huck #include <asm/schid.h>
14a8237fc4SCornelia Huck 
15390935acSPeter Oberparleiter #include "cio.h"
16390935acSPeter Oberparleiter 
171da177e4SLinus Torvalds /*
181da177e4SLinus Torvalds  * path grouping stuff
191da177e4SLinus Torvalds  */
201da177e4SLinus Torvalds #define SPID_FUNC_SINGLE_PATH	   0x00
211da177e4SLinus Torvalds #define SPID_FUNC_MULTI_PATH	   0x80
221da177e4SLinus Torvalds #define SPID_FUNC_ESTABLISH	   0x00
231da177e4SLinus Torvalds #define SPID_FUNC_RESIGN	   0x40
241da177e4SLinus Torvalds #define SPID_FUNC_DISBAND	   0x20
251da177e4SLinus Torvalds 
261da177e4SLinus Torvalds #define SNID_STATE1_RESET	   0
271da177e4SLinus Torvalds #define SNID_STATE1_UNGROUPED	   2
281da177e4SLinus Torvalds #define SNID_STATE1_GROUPED	   3
291da177e4SLinus Torvalds 
301da177e4SLinus Torvalds #define SNID_STATE2_NOT_RESVD	   0
311da177e4SLinus Torvalds #define SNID_STATE2_RESVD_ELSE	   2
321da177e4SLinus Torvalds #define SNID_STATE2_RESVD_SELF	   3
331da177e4SLinus Torvalds 
341da177e4SLinus Torvalds #define SNID_STATE3_MULTI_PATH	   1
351da177e4SLinus Torvalds #define SNID_STATE3_SINGLE_PATH	   0
361da177e4SLinus Torvalds 
37172da89eSVineeth Vijayan /*
38172da89eSVineeth Vijayan  * Conditions used to specify which subchannels need evaluation
39172da89eSVineeth Vijayan  */
40172da89eSVineeth Vijayan enum css_eval_cond {
41*ca34cda7SVineeth Vijayan 	CSS_EVAL_NO_PATH,		/* Subchannels with no operational paths */
42172da89eSVineeth Vijayan 	CSS_EVAL_NOT_ONLINE	/* sch without an online-device */
43172da89eSVineeth Vijayan };
44172da89eSVineeth Vijayan 
451da177e4SLinus Torvalds struct path_state {
461da177e4SLinus Torvalds 	__u8  state1 : 2;	/* path state value 1 */
471da177e4SLinus Torvalds 	__u8  state2 : 2;	/* path state value 2 */
481da177e4SLinus Torvalds 	__u8  state3 : 1;	/* path state value 3 */
491da177e4SLinus Torvalds 	__u8  resvd  : 3;	/* reserved */
501da177e4SLinus Torvalds } __attribute__ ((packed));
511da177e4SLinus Torvalds 
52a28c6944SCornelia Huck struct extended_cssid {
53a28c6944SCornelia Huck 	u8 version;
54a28c6944SCornelia Huck 	u8 cssid;
55a28c6944SCornelia Huck } __attribute__ ((packed));
56a28c6944SCornelia Huck 
571da177e4SLinus Torvalds struct pgid {
581da177e4SLinus Torvalds 	union {
591da177e4SLinus Torvalds 		__u8 fc;   	/* SPID function code */
601da177e4SLinus Torvalds 		struct path_state ps;	/* SNID path state */
614ae9538dSPeter Oberparleiter 	} __attribute__ ((packed)) inf;
62a28c6944SCornelia Huck 	union {
631da177e4SLinus Torvalds 		__u32 cpu_addr	: 16;	/* CPU address */
64a28c6944SCornelia Huck 		struct extended_cssid ext_cssid;
654ae9538dSPeter Oberparleiter 	} __attribute__ ((packed)) pgid_high;
661da177e4SLinus Torvalds 	__u32 cpu_id	: 24;	/* CPU identification */
671da177e4SLinus Torvalds 	__u32 cpu_model : 16;	/* CPU model */
681da177e4SLinus Torvalds 	__u32 tod_high;		/* high word TOD clock */
691da177e4SLinus Torvalds } __attribute__ ((packed));
701da177e4SLinus Torvalds 
718bbace7eSCornelia Huck struct subchannel;
7299611f87SCornelia Huck struct chp_link;
73c820de39SCornelia Huck /**
74c820de39SCornelia Huck  * struct css_driver - device driver for subchannels
75c820de39SCornelia Huck  * @subchannel_type: subchannel type supported by this driver
76c820de39SCornelia Huck  * @drv: embedded device driver structure
77c820de39SCornelia Huck  * @irq: called on interrupts
78c820de39SCornelia Huck  * @chp_event: called for events affecting a channel path
79c820de39SCornelia Huck  * @sch_event: called for events affecting the subchannel
80c820de39SCornelia Huck  * @probe: function called on probe
81c820de39SCornelia Huck  * @remove: function called on remove
82c820de39SCornelia Huck  * @shutdown: called at device shutdown
838ea7f559SSebastian Ott  * @settle: wait for asynchronous work to finish
84c820de39SCornelia Huck  */
851da177e4SLinus Torvalds struct css_driver {
86f08adc00SCornelia Huck 	struct css_device_id *subchannel_type;
871da177e4SLinus Torvalds 	struct device_driver drv;
88602b20f2SCornelia Huck 	void (*irq)(struct subchannel *);
8999611f87SCornelia Huck 	int (*chp_event)(struct subchannel *, struct chp_link *, int);
90c820de39SCornelia Huck 	int (*sch_event)(struct subchannel *, int);
918bbace7eSCornelia Huck 	int (*probe)(struct subchannel *);
92a7bdb9a9SUwe Kleine-König 	void (*remove)(struct subchannel *);
938bbace7eSCornelia Huck 	void (*shutdown)(struct subchannel *);
94b4c70721SSebastian Ott 	int (*settle)(void);
951da177e4SLinus Torvalds };
961da177e4SLinus Torvalds 
97084325d8SCornelia Huck #define to_cssdriver(n) container_of(n, struct css_driver, drv)
98084325d8SCornelia Huck 
9925b7bb58SCornelia Huck extern int css_driver_register(struct css_driver *);
10025b7bb58SCornelia Huck extern void css_driver_unregister(struct css_driver *);
10125b7bb58SCornelia Huck 
1026ab4879aSCornelia Huck extern void css_sch_device_unregister(struct subchannel *);
10314556b33SSebastian Ott extern int css_register_subchannel(struct subchannel *);
104d4f5d79eSSebastian Ott extern struct subchannel *css_alloc_subchannel(struct subchannel_id,
105d4f5d79eSSebastian Ott 					       struct schib *schib);
106a8237fc4SCornelia Huck extern struct subchannel *get_subchannel_by_schid(struct subchannel_id);
1071da177e4SLinus Torvalds extern int css_init_done;
108b0a285d3SSebastian Ott extern int max_ssid;
109e82a1567SPeter Oberparleiter int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *),
110e82a1567SPeter Oberparleiter 			       int (*fn_unknown)(struct subchannel_id,
111e82a1567SPeter Oberparleiter 			       void *), void *data);
112f97a56fbSCornelia Huck extern int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *);
1137ad6a249SPeter Oberparleiter void css_update_ssd_info(struct subchannel *sch);
1141da177e4SLinus Torvalds 
115a28c6944SCornelia Huck struct channel_subsystem {
116b983aa1fSAlexandra Winter 	u8 cssid;
117b983aa1fSAlexandra Winter 	u8 iid;
118b983aa1fSAlexandra Winter 	bool id_valid; /* cssid,iid */
119871931c1SCornelia Huck 	struct channel_path *chps[__MAX_CHPID + 1];
120a28c6944SCornelia Huck 	struct device device;
121a28c6944SCornelia Huck 	struct pgid global_pgid;
122495a5b45SCornelia Huck 	struct mutex mutex;
123495a5b45SCornelia Huck 	/* channel measurement related */
124495a5b45SCornelia Huck 	int cm_enabled;
125495a5b45SCornelia Huck 	void *cub_addr1;
126495a5b45SCornelia Huck 	void *cub_addr2;
127d7b5a4c9SCornelia Huck 	/* for orphaned ccw devices */
128d7b5a4c9SCornelia Huck 	struct subchannel *pseudo_subchannel;
129a28c6944SCornelia Huck };
130a28c6944SCornelia Huck #define to_css(dev) container_of(dev, struct channel_subsystem, device)
1311da177e4SLinus Torvalds 
1327c9f4e3aSCornelia Huck extern struct channel_subsystem *channel_subsystems[];
1331da177e4SLinus Torvalds 
13498cc43abSSebastian Ott /* Dummy helper which needs to change once we support more than one css. */
css_by_id(u8 cssid)13598cc43abSSebastian Ott static inline struct channel_subsystem *css_by_id(u8 cssid)
13698cc43abSSebastian Ott {
13798cc43abSSebastian Ott 	return channel_subsystems[0];
13898cc43abSSebastian Ott }
13998cc43abSSebastian Ott 
14098cc43abSSebastian Ott /* Dummy iterator which needs to change once we support more than one css. */
14198cc43abSSebastian Ott #define for_each_css(css)						\
14298cc43abSSebastian Ott 	for ((css) = channel_subsystems[0]; (css); (css) = NULL)
14398cc43abSSebastian Ott 
1441da177e4SLinus Torvalds /* Helper functions to build lists for the slow path. */
14583b3370cSPeter Oberparleiter void css_schedule_eval(struct subchannel_id schid);
14683b3370cSPeter Oberparleiter void css_schedule_eval_all(void);
147172da89eSVineeth Vijayan void css_schedule_eval_cond(enum css_eval_cond, unsigned long delay);
1480d01bb89SSebastian Ott int css_complete_work(void);
1491da177e4SLinus Torvalds 
150d7b5a4c9SCornelia Huck int sch_is_pseudo_sch(struct subchannel *);
151b279a4f5SCornelia Huck struct schib;
152b279a4f5SCornelia Huck int css_sch_is_valid(struct schib *);
153d7b5a4c9SCornelia Huck 
154be5d3823SSebastian Ott extern struct workqueue_struct *cio_work_q;
15522806dc1SCornelia Huck void css_wait_for_slow_path(void);
156390935acSPeter Oberparleiter void css_sched_sch_todo(struct subchannel *sch, enum sch_todo todo);
1571da177e4SLinus Torvalds #endif
158