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