11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef _CSS_H
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define _CSS_H
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4495a5b45ac33b8fe2c49780fdbcc8014cb6d6ddcCornelia Huck#include <linux/mutex.h>
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/wait.h>
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/workqueue.h>
7e6b6e10ac1de116fc6d2288f185393014851cccfPeter Oberparleiter#include <linux/device.h>
8e5854a5839fa426a7873f038080f63587de5f1f1Peter Oberparleiter#include <linux/types.h>
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/cio.h>
11e5854a5839fa426a7873f038080f63587de5f1f1Peter Oberparleiter#include <asm/chpid.h>
129d92a7e1b0d095c8be96ce5e592c6c5541684631Cornelia Huck#include <asm/schid.h>
13a8237fc4108060402d904bea5e1062e22e731969Cornelia Huck
14390935acac21f3ea1a130bdca8eb9397cb293643Peter Oberparleiter#include "cio.h"
15390935acac21f3ea1a130bdca8eb9397cb293643Peter Oberparleiter
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * path grouping stuff
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SPID_FUNC_SINGLE_PATH	   0x00
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SPID_FUNC_MULTI_PATH	   0x80
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SPID_FUNC_ESTABLISH	   0x00
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SPID_FUNC_RESIGN	   0x40
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SPID_FUNC_DISBAND	   0x20
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SNID_STATE1_RESET	   0
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SNID_STATE1_UNGROUPED	   2
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SNID_STATE1_GROUPED	   3
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SNID_STATE2_NOT_RESVD	   0
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SNID_STATE2_RESVD_ELSE	   2
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SNID_STATE2_RESVD_SELF	   3
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SNID_STATE3_MULTI_PATH	   1
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SNID_STATE3_SINGLE_PATH	   0
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct path_state {
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__u8  state1 : 2;	/* path state value 1 */
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__u8  state2 : 2;	/* path state value 2 */
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__u8  state3 : 1;	/* path state value 3 */
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__u8  resvd  : 3;	/* reserved */
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} __attribute__ ((packed));
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
43a28c69448154a0901e8815922030c5dcd2f8e388Cornelia Huckstruct extended_cssid {
44a28c69448154a0901e8815922030c5dcd2f8e388Cornelia Huck	u8 version;
45a28c69448154a0901e8815922030c5dcd2f8e388Cornelia Huck	u8 cssid;
46a28c69448154a0901e8815922030c5dcd2f8e388Cornelia Huck} __attribute__ ((packed));
47a28c69448154a0901e8815922030c5dcd2f8e388Cornelia Huck
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct pgid {
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	union {
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		__u8 fc;   	/* SPID function code */
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		struct path_state ps;	/* SNID path state */
524ae9538dd02824257e8e72c053c69ad6680aba04Peter Oberparleiter	} __attribute__ ((packed)) inf;
53a28c69448154a0901e8815922030c5dcd2f8e388Cornelia Huck	union {
54a28c69448154a0901e8815922030c5dcd2f8e388Cornelia Huck		__u32 cpu_addr	: 16;	/* CPU address */
55a28c69448154a0901e8815922030c5dcd2f8e388Cornelia Huck		struct extended_cssid ext_cssid;
564ae9538dd02824257e8e72c053c69ad6680aba04Peter Oberparleiter	} __attribute__ ((packed)) pgid_high;
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__u32 cpu_id	: 24;	/* CPU identification */
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__u32 cpu_model : 16;	/* CPU model */
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__u32 tod_high;		/* high word TOD clock */
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} __attribute__ ((packed));
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
628bbace7e686f1536905c703038a7eddfb1520264Cornelia Huckstruct subchannel;
6399611f87176b2a908d8c66ab19a5fc550a3cd13aCornelia Huckstruct chp_link;
64c820de39bd083222f5be2563181c87493e436f7cCornelia Huck/**
65c820de39bd083222f5be2563181c87493e436f7cCornelia Huck * struct css_driver - device driver for subchannels
66c820de39bd083222f5be2563181c87493e436f7cCornelia Huck * @subchannel_type: subchannel type supported by this driver
67c820de39bd083222f5be2563181c87493e436f7cCornelia Huck * @drv: embedded device driver structure
68c820de39bd083222f5be2563181c87493e436f7cCornelia Huck * @irq: called on interrupts
69c820de39bd083222f5be2563181c87493e436f7cCornelia Huck * @chp_event: called for events affecting a channel path
70c820de39bd083222f5be2563181c87493e436f7cCornelia Huck * @sch_event: called for events affecting the subchannel
71c820de39bd083222f5be2563181c87493e436f7cCornelia Huck * @probe: function called on probe
72c820de39bd083222f5be2563181c87493e436f7cCornelia Huck * @remove: function called on remove
73c820de39bd083222f5be2563181c87493e436f7cCornelia Huck * @shutdown: called at device shutdown
74dcbd16d5111258df7c821ec1e4124fe6ffbf3c16Sebastian Ott * @prepare: prepare for pm state transition
75dcbd16d5111258df7c821ec1e4124fe6ffbf3c16Sebastian Ott * @complete: undo work done in @prepare
76dcbd16d5111258df7c821ec1e4124fe6ffbf3c16Sebastian Ott * @freeze: callback for freezing during hibernation snapshotting
77dcbd16d5111258df7c821ec1e4124fe6ffbf3c16Sebastian Ott * @thaw: undo work done in @freeze
78dcbd16d5111258df7c821ec1e4124fe6ffbf3c16Sebastian Ott * @restore: callback for restoring after hibernation
798ea7f5590142c0b9ab319aa3cae85cf430a207d8Sebastian Ott * @settle: wait for asynchronous work to finish
80c820de39bd083222f5be2563181c87493e436f7cCornelia Huck */
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct css_driver {
82f08adc008d84f6b03d377ede951e29ed169e76e2Cornelia Huck	struct css_device_id *subchannel_type;
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct device_driver drv;
84602b20f2bf335d0d5fce11cb2ade22aa74e7ba25Cornelia Huck	void (*irq)(struct subchannel *);
8599611f87176b2a908d8c66ab19a5fc550a3cd13aCornelia Huck	int (*chp_event)(struct subchannel *, struct chp_link *, int);
86c820de39bd083222f5be2563181c87493e436f7cCornelia Huck	int (*sch_event)(struct subchannel *, int);
878bbace7e686f1536905c703038a7eddfb1520264Cornelia Huck	int (*probe)(struct subchannel *);
888bbace7e686f1536905c703038a7eddfb1520264Cornelia Huck	int (*remove)(struct subchannel *);
898bbace7e686f1536905c703038a7eddfb1520264Cornelia Huck	void (*shutdown)(struct subchannel *);
90dcbd16d5111258df7c821ec1e4124fe6ffbf3c16Sebastian Ott	int (*prepare) (struct subchannel *);
91dcbd16d5111258df7c821ec1e4124fe6ffbf3c16Sebastian Ott	void (*complete) (struct subchannel *);
92dcbd16d5111258df7c821ec1e4124fe6ffbf3c16Sebastian Ott	int (*freeze)(struct subchannel *);
93dcbd16d5111258df7c821ec1e4124fe6ffbf3c16Sebastian Ott	int (*thaw) (struct subchannel *);
94dcbd16d5111258df7c821ec1e4124fe6ffbf3c16Sebastian Ott	int (*restore)(struct subchannel *);
95b4c707214c987da021d4d5c4ed54612cf73d80d6Sebastian Ott	int (*settle)(void);
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
98084325d80418adf4d75b10a9ceff1348f2e09163Cornelia Huck#define to_cssdriver(n) container_of(n, struct css_driver, drv)
99084325d80418adf4d75b10a9ceff1348f2e09163Cornelia Huck
10025b7bb5838ab81b68a9de72df577103d8b4aba3cCornelia Huckextern int css_driver_register(struct css_driver *);
10125b7bb5838ab81b68a9de72df577103d8b4aba3cCornelia Huckextern void css_driver_unregister(struct css_driver *);
10225b7bb5838ab81b68a9de72df577103d8b4aba3cCornelia Huck
1036ab4879a0d074c938fd17dba141dce042fc17beeCornelia Huckextern void css_sch_device_unregister(struct subchannel *);
104c820de39bd083222f5be2563181c87493e436f7cCornelia Huckextern int css_probe_device(struct subchannel_id);
105c820de39bd083222f5be2563181c87493e436f7cCornelia Huckextern struct subchannel *get_subchannel_by_schid(struct subchannel_id);
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern int css_init_done;
107b0a285d31bd475fdd4312e457288be558b705e55Sebastian Ottextern int max_ssid;
108e82a1567e4b22eb035da2499d20ddd573c9acf75Peter Oberparleiterint for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *),
109e82a1567e4b22eb035da2499d20ddd573c9acf75Peter Oberparleiter			       int (*fn_unknown)(struct subchannel_id,
110e82a1567e4b22eb035da2499d20ddd573c9acf75Peter Oberparleiter			       void *), void *data);
111f97a56fb768e5fe9cd07c56ca47870136bb5530cCornelia Huckextern int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *);
1122b67fc46061b2171fb8fbb55d1ac717abd533569Heiko Carstensextern void css_reiterate_subchannels(void);
1137ad6a24970325294a22a08446d473384c15b928ePeter Oberparleitervoid css_update_ssd_info(struct subchannel *sch);
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
115a8237fc4108060402d904bea5e1062e22e731969Cornelia Huck#define __MAX_SUBCHANNEL 65535
116fb6958a594da49ece869793e6ec163b89fc5f79fCornelia Huck#define __MAX_SSID 3
117a28c69448154a0901e8815922030c5dcd2f8e388Cornelia Huck
118a28c69448154a0901e8815922030c5dcd2f8e388Cornelia Huckstruct channel_subsystem {
119a28c69448154a0901e8815922030c5dcd2f8e388Cornelia Huck	u8 cssid;
120a28c69448154a0901e8815922030c5dcd2f8e388Cornelia Huck	int valid;
121871931c1eef1727d42ff3ecf993b1978cf1e209fCornelia Huck	struct channel_path *chps[__MAX_CHPID + 1];
122a28c69448154a0901e8815922030c5dcd2f8e388Cornelia Huck	struct device device;
123a28c69448154a0901e8815922030c5dcd2f8e388Cornelia Huck	struct pgid global_pgid;
124495a5b45ac33b8fe2c49780fdbcc8014cb6d6ddcCornelia Huck	struct mutex mutex;
125495a5b45ac33b8fe2c49780fdbcc8014cb6d6ddcCornelia Huck	/* channel measurement related */
126495a5b45ac33b8fe2c49780fdbcc8014cb6d6ddcCornelia Huck	int cm_enabled;
127495a5b45ac33b8fe2c49780fdbcc8014cb6d6ddcCornelia Huck	void *cub_addr1;
128495a5b45ac33b8fe2c49780fdbcc8014cb6d6ddcCornelia Huck	void *cub_addr2;
129d7b5a4c94f49131811112526f7d404a50f0b5ca7Cornelia Huck	/* for orphaned ccw devices */
130d7b5a4c94f49131811112526f7d404a50f0b5ca7Cornelia Huck	struct subchannel *pseudo_subchannel;
131a28c69448154a0901e8815922030c5dcd2f8e388Cornelia Huck};
132a28c69448154a0901e8815922030c5dcd2f8e388Cornelia Huck#define to_css(dev) container_of(dev, struct channel_subsystem, device)
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1347c9f4e3aaae020fc674f52393cbac1bdb648bf90Cornelia Huckextern struct channel_subsystem *channel_subsystems[];
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
136638ad34a8811119b32247b7722288ef8b90907d1Martin Schwidefskyvoid channel_subsystem_reinit(void);
137638ad34a8811119b32247b7722288ef8b90907d1Martin Schwidefsky
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Helper functions to build lists for the slow path. */
13983b3370c79b91b9be3f6540c3c914e689134b45fPeter Oberparleitervoid css_schedule_eval(struct subchannel_id schid);
14083b3370c79b91b9be3f6540c3c914e689134b45fPeter Oberparleitervoid css_schedule_eval_all(void);
1410d01bb89220490763d89571d27e7ee3f13f9b372Sebastian Ottint css_complete_work(void);
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
143d7b5a4c94f49131811112526f7d404a50f0b5ca7Cornelia Huckint sch_is_pseudo_sch(struct subchannel *);
144b279a4f56d5476a0b9b0a97397f7a7bbe00b9b2fCornelia Huckstruct schib;
145b279a4f56d5476a0b9b0a97397f7a7bbe00b9b2fCornelia Huckint css_sch_is_valid(struct schib *);
146d7b5a4c94f49131811112526f7d404a50f0b5ca7Cornelia Huck
147be5d3823f29c09676abd2eeea4f9767bc4a1a531Sebastian Ottextern struct workqueue_struct *cio_work_q;
14822806dc1a8ffd88a7c7bdd070879e6e323db496aCornelia Huckvoid css_wait_for_slow_path(void);
149390935acac21f3ea1a130bdca8eb9397cb293643Peter Oberparleitervoid css_sched_sch_todo(struct subchannel *sch, enum sch_todo todo);
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
151