css.h 5.2 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8
#ifndef _CSS_H
#define _CSS_H

#include <linux/wait.h>
#include <linux/workqueue.h>

#include <asm/cio.h>

9 10
#include "schid.h"

L
Linus Torvalds 已提交
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
/*
 * path grouping stuff
 */
#define SPID_FUNC_SINGLE_PATH	   0x00
#define SPID_FUNC_MULTI_PATH	   0x80
#define SPID_FUNC_ESTABLISH	   0x00
#define SPID_FUNC_RESIGN	   0x40
#define SPID_FUNC_DISBAND	   0x20

#define SNID_STATE1_RESET	   0
#define SNID_STATE1_UNGROUPED	   2
#define SNID_STATE1_GROUPED	   3

#define SNID_STATE2_NOT_RESVD	   0
#define SNID_STATE2_RESVD_ELSE	   2
#define SNID_STATE2_RESVD_SELF	   3

#define SNID_STATE3_MULTI_PATH	   1
#define SNID_STATE3_SINGLE_PATH	   0

struct path_state {
	__u8  state1 : 2;	/* path state value 1 */
	__u8  state2 : 2;	/* path state value 2 */
	__u8  state3 : 1;	/* path state value 3 */
	__u8  resvd  : 3;	/* reserved */
} __attribute__ ((packed));

38 39 40 41 42
struct extended_cssid {
	u8 version;
	u8 cssid;
} __attribute__ ((packed));

L
Linus Torvalds 已提交
43 44 45 46 47
struct pgid {
	union {
		__u8 fc;   	/* SPID function code */
		struct path_state ps;	/* SNID path state */
	} inf;
48 49 50 51
	union {
		__u32 cpu_addr	: 16;	/* CPU address */
		struct extended_cssid ext_cssid;
	} pgid_high;
L
Linus Torvalds 已提交
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
	__u32 cpu_id	: 24;	/* CPU identification */
	__u32 cpu_model : 16;	/* CPU model */
	__u32 tod_high;		/* high word TOD clock */
} __attribute__ ((packed));

#define MAX_CIWS 8

/*
 * sense-id response buffer layout
 */
struct senseid {
	/* common part */
	__u8  reserved;     	/* always 0x'FF' */
	__u16 cu_type;	     	/* control unit type */
	__u8  cu_model;     	/* control unit model */
	__u16 dev_type;     	/* device type */
	__u8  dev_model;    	/* device model */
	__u8  unused;	     	/* padding byte */
	/* extended part */
	struct ciw ciw[MAX_CIWS];	/* variable # of CIWs */
}  __attribute__ ((packed,aligned(4)));

struct ccw_device_private {
	int state;		/* device state */
	atomic_t onoff;
	unsigned long registered;
	__u16 devno;		/* device number */
79
	__u16 sch_no;		/* subchannel number */
80
	__u8 ssid;              /* subchannel set id */
L
Linus Torvalds 已提交
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
	__u8 imask;		/* lpm mask for SNID/SID/SPGID */
	int iretry;		/* retry counter SNID/SID/SPGID */
	struct {
		unsigned int fast:1;	/* post with "channel end" */
		unsigned int repall:1;	/* report every interrupt status */
		unsigned int pgroup:1;  /* do path grouping */
		unsigned int force:1;   /* allow forced online */
	} __attribute__ ((packed)) options;
	struct {
		unsigned int pgid_single:1; /* use single path for Set PGID */
		unsigned int esid:1;        /* Ext. SenseID supported by HW */
		unsigned int dosense:1;	    /* delayed SENSE required */
		unsigned int doverify:1;    /* delayed path verification */
		unsigned int donotify:1;    /* call notify function */
		unsigned int recog_done:1;  /* dev. recog. complete */
		unsigned int fake_irb:1;    /* deliver faked irb */
	} __attribute__((packed)) flags;
	unsigned long intparm;	/* user interruption parameter */
	struct qdio_irq *qdio_data;
	struct irb irb;		/* device status */
	struct senseid senseid;	/* SenseID info */
	struct pgid pgid;	/* path group ID */
	struct ccw1 iccws[2];	/* ccws for SNID/SID/SPGID commands */
	struct work_struct kick_work;
	wait_queue_head_t wait_q;
	struct timer_list timer;
	void *cmb;			/* measurement information */
	struct list_head cmb_list;	/* list of measured devices */
	u64 cmb_start_time;		/* clock value of cmb reset */
	void *cmb_wait;			/* deferred cmb enable/disable */
};

/*
 * A css driver handles all subchannels of one type.
 * Currently, we only care about I/O subchannels (type 0), these
 * have a ccw_device connected to them.
 */
struct css_driver {
	unsigned int subchannel_type;
	struct device_driver drv;
	void (*irq)(struct device *);
	int (*notify)(struct device *, int);
	void (*verify)(struct device *);
	void (*termination)(struct device *);
};

/*
 * all css_drivers have the css_bus_type
 */
extern struct bus_type css_bus_type;
extern struct css_driver io_subchannel_driver;

133 134
extern int css_probe_device(struct subchannel_id);
extern struct subchannel * get_subchannel_by_schid(struct subchannel_id);
L
Linus Torvalds 已提交
135
extern int css_init_done;
136
extern int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *);
L
Linus Torvalds 已提交
137

138
#define __MAX_SUBCHANNEL 65535
139
#define __MAX_SSID 3
140 141 142 143 144 145 146 147 148 149 150
#define __MAX_CHPID 255
#define __MAX_CSSID 0

struct channel_subsystem {
	u8 cssid;
	int valid;
	struct channel_path *chps[__MAX_CHPID];
	struct device device;
	struct pgid global_pgid;
};
#define to_css(dev) container_of(dev, struct channel_subsystem, device)
L
Linus Torvalds 已提交
151 152

extern struct bus_type css_bus_type;
153
extern struct channel_subsystem *css[];
L
Linus Torvalds 已提交
154 155 156 157 158 159 160 161 162 163 164 165 166 167

/* Some helper functions for disconnected state. */
int device_is_disconnected(struct subchannel *);
void device_set_disconnected(struct subchannel *);
void device_trigger_reprobe(struct subchannel *);

/* Helper functions for vary on/off. */
int device_is_online(struct subchannel *);
void device_set_waiting(struct subchannel *);

/* Machine check helper function. */
void device_kill_pending_timer(struct subchannel *);

/* Helper functions to build lists for the slow path. */
168
extern int css_enqueue_subchannel_slow(struct subchannel_id schid);
L
Linus Torvalds 已提交
169 170 171 172 173 174 175 176
void css_walk_subchannel_slow_list(void (*fn)(unsigned long));
void css_clear_subchannel_slow_list(void);
int css_slow_subchannels_exist(void);
extern int need_rescan;

extern struct workqueue_struct *slow_path_wq;
extern struct work_struct slow_path_work;
#endif