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