1#ifndef _CSS_H 2#define _CSS_H 3 4#include <linux/mutex.h> 5#include <linux/wait.h> 6#include <linux/workqueue.h> 7#include <linux/device.h> 8#include <linux/types.h> 9 10#include <asm/cio.h> 11#include <asm/chpid.h> 12 13#include "schid.h" 14 15/* 16 * path grouping stuff 17 */ 18#define SPID_FUNC_SINGLE_PATH 0x00 19#define SPID_FUNC_MULTI_PATH 0x80 20#define SPID_FUNC_ESTABLISH 0x00 21#define SPID_FUNC_RESIGN 0x40 22#define SPID_FUNC_DISBAND 0x20 23 24#define SNID_STATE1_RESET 0 25#define SNID_STATE1_UNGROUPED 2 26#define SNID_STATE1_GROUPED 3 27 28#define SNID_STATE2_NOT_RESVD 0 29#define SNID_STATE2_RESVD_ELSE 2 30#define SNID_STATE2_RESVD_SELF 3 31 32#define SNID_STATE3_MULTI_PATH 1 33#define SNID_STATE3_SINGLE_PATH 0 34 35struct path_state { 36 __u8 state1 : 2; /* path state value 1 */ 37 __u8 state2 : 2; /* path state value 2 */ 38 __u8 state3 : 1; /* path state value 3 */ 39 __u8 resvd : 3; /* reserved */ 40} __attribute__ ((packed)); 41 42struct extended_cssid { 43 u8 version; 44 u8 cssid; 45} __attribute__ ((packed)); 46 47struct pgid { 48 union { 49 __u8 fc; /* SPID function code */ 50 struct path_state ps; /* SNID path state */ 51 } __attribute__ ((packed)) inf; 52 union { 53 __u32 cpu_addr : 16; /* CPU address */ 54 struct extended_cssid ext_cssid; 55 } __attribute__ ((packed)) pgid_high; 56 __u32 cpu_id : 24; /* CPU identification */ 57 __u32 cpu_model : 16; /* CPU model */ 58 __u32 tod_high; /* high word TOD clock */ 59} __attribute__ ((packed)); 60 61#define MAX_CIWS 8 62 63/* 64 * sense-id response buffer layout 65 */ 66struct senseid { 67 /* common part */ 68 __u8 reserved; /* always 0x'FF' */ 69 __u16 cu_type; /* control unit type */ 70 __u8 cu_model; /* control unit model */ 71 __u16 dev_type; /* device type */ 72 __u8 dev_model; /* device model */ 73 __u8 unused; /* padding byte */ 74 /* extended part */ 75 struct ciw ciw[MAX_CIWS]; /* variable # of CIWs */ 76} __attribute__ ((packed,aligned(4))); 77 78struct ccw_device_private { 79 struct ccw_device *cdev; 80 struct subchannel *sch; 81 int state; /* device state */ 82 atomic_t onoff; 83 unsigned long registered; 84 struct ccw_dev_id dev_id; /* device id */ 85 struct subchannel_id schid; /* subchannel number */ 86 __u8 imask; /* lpm mask for SNID/SID/SPGID */ 87 int iretry; /* retry counter SNID/SID/SPGID */ 88 struct { 89 unsigned int fast:1; /* post with "channel end" */ 90 unsigned int repall:1; /* report every interrupt status */ 91 unsigned int pgroup:1; /* do path grouping */ 92 unsigned int force:1; /* allow forced online */ 93 } __attribute__ ((packed)) options; 94 struct { 95 unsigned int pgid_single:1; /* use single path for Set PGID */ 96 unsigned int esid:1; /* Ext. SenseID supported by HW */ 97 unsigned int dosense:1; /* delayed SENSE required */ 98 unsigned int doverify:1; /* delayed path verification */ 99 unsigned int donotify:1; /* call notify function */ 100 unsigned int recog_done:1; /* dev. recog. complete */ 101 unsigned int fake_irb:1; /* deliver faked irb */ 102 unsigned int intretry:1; /* retry internal operation */ 103 } __attribute__((packed)) flags; 104 unsigned long intparm; /* user interruption parameter */ 105 struct qdio_irq *qdio_data; 106 struct irb irb; /* device status */ 107 struct senseid senseid; /* SenseID info */ 108 struct pgid pgid[8]; /* path group IDs per chpid*/ 109 struct ccw1 iccws[2]; /* ccws for SNID/SID/SPGID commands */ 110 struct work_struct kick_work; 111 wait_queue_head_t wait_q; 112 struct timer_list timer; 113 void *cmb; /* measurement information */ 114 struct list_head cmb_list; /* list of measured devices */ 115 u64 cmb_start_time; /* clock value of cmb reset */ 116 void *cmb_wait; /* deferred cmb enable/disable */ 117}; 118 119/* 120 * A css driver handles all subchannels of one type. 121 * Currently, we only care about I/O subchannels (type 0), these 122 * have a ccw_device connected to them. 123 */ 124struct subchannel; 125struct css_driver { 126 unsigned int subchannel_type; 127 struct device_driver drv; 128 void (*irq)(struct device *); 129 int (*notify)(struct device *, int); 130 void (*verify)(struct device *); 131 void (*termination)(struct device *); 132 int (*probe)(struct subchannel *); 133 int (*remove)(struct subchannel *); 134 void (*shutdown)(struct subchannel *); 135}; 136 137/* 138 * all css_drivers have the css_bus_type 139 */ 140extern struct bus_type css_bus_type; 141 142extern void css_sch_device_unregister(struct subchannel *); 143extern struct subchannel * get_subchannel_by_schid(struct subchannel_id); 144extern int css_init_done; 145extern int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *); 146extern void css_process_crw(int, int); 147extern void css_reiterate_subchannels(void); 148void css_update_ssd_info(struct subchannel *sch); 149 150#define __MAX_SUBCHANNEL 65535 151#define __MAX_SSID 3 152 153struct channel_subsystem { 154 u8 cssid; 155 int valid; 156 struct channel_path *chps[__MAX_CHPID + 1]; 157 struct device device; 158 struct pgid global_pgid; 159 struct mutex mutex; 160 /* channel measurement related */ 161 int cm_enabled; 162 void *cub_addr1; 163 void *cub_addr2; 164 /* for orphaned ccw devices */ 165 struct subchannel *pseudo_subchannel; 166}; 167#define to_css(dev) container_of(dev, struct channel_subsystem, device) 168 169extern struct bus_type css_bus_type; 170extern struct channel_subsystem *channel_subsystems[]; 171 172/* Some helper functions for disconnected state. */ 173int device_is_disconnected(struct subchannel *); 174void device_set_disconnected(struct subchannel *); 175void device_trigger_reprobe(struct subchannel *); 176 177/* Helper functions for vary on/off. */ 178int device_is_online(struct subchannel *); 179void device_kill_io(struct subchannel *); 180void device_set_intretry(struct subchannel *sch); 181int device_trigger_verify(struct subchannel *sch); 182 183/* Machine check helper function. */ 184void device_kill_pending_timer(struct subchannel *); 185 186/* Helper functions to build lists for the slow path. */ 187void css_schedule_eval(struct subchannel_id schid); 188void css_schedule_eval_all(void); 189 190int sch_is_pseudo_sch(struct subchannel *); 191 192extern struct workqueue_struct *slow_path_wq; 193 194extern struct attribute_group *subch_attr_groups[]; 195#endif 196