xref: /OK3568_Linux_fs/kernel/drivers/s390/cio/css.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun #ifndef _CSS_H
3*4882a593Smuzhiyun #define _CSS_H
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun #include <linux/mutex.h>
6*4882a593Smuzhiyun #include <linux/wait.h>
7*4882a593Smuzhiyun #include <linux/workqueue.h>
8*4882a593Smuzhiyun #include <linux/device.h>
9*4882a593Smuzhiyun #include <linux/types.h>
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #include <asm/cio.h>
12*4882a593Smuzhiyun #include <asm/chpid.h>
13*4882a593Smuzhiyun #include <asm/schid.h>
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun #include "cio.h"
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun /*
18*4882a593Smuzhiyun  * path grouping stuff
19*4882a593Smuzhiyun  */
20*4882a593Smuzhiyun #define SPID_FUNC_SINGLE_PATH	   0x00
21*4882a593Smuzhiyun #define SPID_FUNC_MULTI_PATH	   0x80
22*4882a593Smuzhiyun #define SPID_FUNC_ESTABLISH	   0x00
23*4882a593Smuzhiyun #define SPID_FUNC_RESIGN	   0x40
24*4882a593Smuzhiyun #define SPID_FUNC_DISBAND	   0x20
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun #define SNID_STATE1_RESET	   0
27*4882a593Smuzhiyun #define SNID_STATE1_UNGROUPED	   2
28*4882a593Smuzhiyun #define SNID_STATE1_GROUPED	   3
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #define SNID_STATE2_NOT_RESVD	   0
31*4882a593Smuzhiyun #define SNID_STATE2_RESVD_ELSE	   2
32*4882a593Smuzhiyun #define SNID_STATE2_RESVD_SELF	   3
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun #define SNID_STATE3_MULTI_PATH	   1
35*4882a593Smuzhiyun #define SNID_STATE3_SINGLE_PATH	   0
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun struct path_state {
38*4882a593Smuzhiyun 	__u8  state1 : 2;	/* path state value 1 */
39*4882a593Smuzhiyun 	__u8  state2 : 2;	/* path state value 2 */
40*4882a593Smuzhiyun 	__u8  state3 : 1;	/* path state value 3 */
41*4882a593Smuzhiyun 	__u8  resvd  : 3;	/* reserved */
42*4882a593Smuzhiyun } __attribute__ ((packed));
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun struct extended_cssid {
45*4882a593Smuzhiyun 	u8 version;
46*4882a593Smuzhiyun 	u8 cssid;
47*4882a593Smuzhiyun } __attribute__ ((packed));
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun struct pgid {
50*4882a593Smuzhiyun 	union {
51*4882a593Smuzhiyun 		__u8 fc;   	/* SPID function code */
52*4882a593Smuzhiyun 		struct path_state ps;	/* SNID path state */
53*4882a593Smuzhiyun 	} __attribute__ ((packed)) inf;
54*4882a593Smuzhiyun 	union {
55*4882a593Smuzhiyun 		__u32 cpu_addr	: 16;	/* CPU address */
56*4882a593Smuzhiyun 		struct extended_cssid ext_cssid;
57*4882a593Smuzhiyun 	} __attribute__ ((packed)) pgid_high;
58*4882a593Smuzhiyun 	__u32 cpu_id	: 24;	/* CPU identification */
59*4882a593Smuzhiyun 	__u32 cpu_model : 16;	/* CPU model */
60*4882a593Smuzhiyun 	__u32 tod_high;		/* high word TOD clock */
61*4882a593Smuzhiyun } __attribute__ ((packed));
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun struct subchannel;
64*4882a593Smuzhiyun struct chp_link;
65*4882a593Smuzhiyun /**
66*4882a593Smuzhiyun  * struct css_driver - device driver for subchannels
67*4882a593Smuzhiyun  * @subchannel_type: subchannel type supported by this driver
68*4882a593Smuzhiyun  * @drv: embedded device driver structure
69*4882a593Smuzhiyun  * @irq: called on interrupts
70*4882a593Smuzhiyun  * @chp_event: called for events affecting a channel path
71*4882a593Smuzhiyun  * @sch_event: called for events affecting the subchannel
72*4882a593Smuzhiyun  * @probe: function called on probe
73*4882a593Smuzhiyun  * @remove: function called on remove
74*4882a593Smuzhiyun  * @shutdown: called at device shutdown
75*4882a593Smuzhiyun  * @prepare: prepare for pm state transition
76*4882a593Smuzhiyun  * @complete: undo work done in @prepare
77*4882a593Smuzhiyun  * @freeze: callback for freezing during hibernation snapshotting
78*4882a593Smuzhiyun  * @thaw: undo work done in @freeze
79*4882a593Smuzhiyun  * @restore: callback for restoring after hibernation
80*4882a593Smuzhiyun  * @settle: wait for asynchronous work to finish
81*4882a593Smuzhiyun  */
82*4882a593Smuzhiyun struct css_driver {
83*4882a593Smuzhiyun 	struct css_device_id *subchannel_type;
84*4882a593Smuzhiyun 	struct device_driver drv;
85*4882a593Smuzhiyun 	void (*irq)(struct subchannel *);
86*4882a593Smuzhiyun 	int (*chp_event)(struct subchannel *, struct chp_link *, int);
87*4882a593Smuzhiyun 	int (*sch_event)(struct subchannel *, int);
88*4882a593Smuzhiyun 	int (*probe)(struct subchannel *);
89*4882a593Smuzhiyun 	int (*remove)(struct subchannel *);
90*4882a593Smuzhiyun 	void (*shutdown)(struct subchannel *);
91*4882a593Smuzhiyun 	int (*prepare) (struct subchannel *);
92*4882a593Smuzhiyun 	void (*complete) (struct subchannel *);
93*4882a593Smuzhiyun 	int (*freeze)(struct subchannel *);
94*4882a593Smuzhiyun 	int (*thaw) (struct subchannel *);
95*4882a593Smuzhiyun 	int (*restore)(struct subchannel *);
96*4882a593Smuzhiyun 	int (*settle)(void);
97*4882a593Smuzhiyun };
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun #define to_cssdriver(n) container_of(n, struct css_driver, drv)
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun extern int css_driver_register(struct css_driver *);
102*4882a593Smuzhiyun extern void css_driver_unregister(struct css_driver *);
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun extern void css_sch_device_unregister(struct subchannel *);
105*4882a593Smuzhiyun extern int css_register_subchannel(struct subchannel *);
106*4882a593Smuzhiyun extern struct subchannel *css_alloc_subchannel(struct subchannel_id,
107*4882a593Smuzhiyun 					       struct schib *schib);
108*4882a593Smuzhiyun extern struct subchannel *get_subchannel_by_schid(struct subchannel_id);
109*4882a593Smuzhiyun extern int css_init_done;
110*4882a593Smuzhiyun extern int max_ssid;
111*4882a593Smuzhiyun int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *),
112*4882a593Smuzhiyun 			       int (*fn_unknown)(struct subchannel_id,
113*4882a593Smuzhiyun 			       void *), void *data);
114*4882a593Smuzhiyun extern int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *);
115*4882a593Smuzhiyun void css_update_ssd_info(struct subchannel *sch);
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun struct channel_subsystem {
118*4882a593Smuzhiyun 	u8 cssid;
119*4882a593Smuzhiyun 	u8 iid;
120*4882a593Smuzhiyun 	bool id_valid; /* cssid,iid */
121*4882a593Smuzhiyun 	struct channel_path *chps[__MAX_CHPID + 1];
122*4882a593Smuzhiyun 	struct device device;
123*4882a593Smuzhiyun 	struct pgid global_pgid;
124*4882a593Smuzhiyun 	struct mutex mutex;
125*4882a593Smuzhiyun 	/* channel measurement related */
126*4882a593Smuzhiyun 	int cm_enabled;
127*4882a593Smuzhiyun 	void *cub_addr1;
128*4882a593Smuzhiyun 	void *cub_addr2;
129*4882a593Smuzhiyun 	/* for orphaned ccw devices */
130*4882a593Smuzhiyun 	struct subchannel *pseudo_subchannel;
131*4882a593Smuzhiyun };
132*4882a593Smuzhiyun #define to_css(dev) container_of(dev, struct channel_subsystem, device)
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun extern struct channel_subsystem *channel_subsystems[];
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun /* Dummy helper which needs to change once we support more than one css. */
css_by_id(u8 cssid)137*4882a593Smuzhiyun static inline struct channel_subsystem *css_by_id(u8 cssid)
138*4882a593Smuzhiyun {
139*4882a593Smuzhiyun 	return channel_subsystems[0];
140*4882a593Smuzhiyun }
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun /* Dummy iterator which needs to change once we support more than one css. */
143*4882a593Smuzhiyun #define for_each_css(css)						\
144*4882a593Smuzhiyun 	for ((css) = channel_subsystems[0]; (css); (css) = NULL)
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun /* Helper functions to build lists for the slow path. */
147*4882a593Smuzhiyun void css_schedule_eval(struct subchannel_id schid);
148*4882a593Smuzhiyun void css_schedule_eval_all(void);
149*4882a593Smuzhiyun void css_schedule_eval_all_unreg(unsigned long delay);
150*4882a593Smuzhiyun int css_complete_work(void);
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun int sch_is_pseudo_sch(struct subchannel *);
153*4882a593Smuzhiyun struct schib;
154*4882a593Smuzhiyun int css_sch_is_valid(struct schib *);
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun extern struct workqueue_struct *cio_work_q;
157*4882a593Smuzhiyun void css_wait_for_slow_path(void);
158*4882a593Smuzhiyun void css_sched_sch_todo(struct subchannel *sch, enum sch_todo todo);
159*4882a593Smuzhiyun #endif
160