]>
Commit | Line | Data |
---|---|---|
df1fe5bb CH |
1 | /* |
2 | * Channel subsystem structures and definitions. | |
3 | * | |
4 | * Copyright 2012 IBM Corp. | |
5 | * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com> | |
6 | * | |
7 | * This work is licensed under the terms of the GNU GPL, version 2 or (at | |
8 | * your option) any later version. See the COPYING file in the top-level | |
9 | * directory. | |
10 | */ | |
11 | ||
12 | #ifndef CSS_H | |
13 | #define CSS_H | |
14 | ||
a28d8391 YMZ |
15 | #include "hw/s390x/adapter.h" |
16 | #include "hw/s390x/s390_flic.h" | |
bd3f16ac | 17 | #include "hw/s390x/ioinst.h" |
df1fe5bb CH |
18 | |
19 | /* Channel subsystem constants. */ | |
cf249935 | 20 | #define MAX_DEVNO 65535 |
df1fe5bb CH |
21 | #define MAX_SCHID 65535 |
22 | #define MAX_SSID 3 | |
882b3b97 | 23 | #define MAX_CSSID 255 |
df1fe5bb CH |
24 | #define MAX_CHPID 255 |
25 | ||
dde522bb FL |
26 | #define MAX_ISC 7 |
27 | ||
df1fe5bb CH |
28 | #define MAX_CIWS 62 |
29 | ||
cf249935 | 30 | #define VIRTUAL_CSSID 0xfe |
6c15e9bf | 31 | #define VIRTIO_CCW_CHPID 0 /* used by convention */ |
cf249935 | 32 | |
df1fe5bb CH |
33 | typedef struct CIW { |
34 | uint8_t type; | |
35 | uint8_t command; | |
36 | uint16_t count; | |
37 | } QEMU_PACKED CIW; | |
38 | ||
39 | typedef struct SenseId { | |
40 | /* common part */ | |
41 | uint8_t reserved; /* always 0x'FF' */ | |
42 | uint16_t cu_type; /* control unit type */ | |
43 | uint8_t cu_model; /* control unit model */ | |
44 | uint16_t dev_type; /* device type */ | |
45 | uint8_t dev_model; /* device model */ | |
46 | uint8_t unused; /* padding byte */ | |
47 | /* extended part */ | |
48 | CIW ciw[MAX_CIWS]; /* variable # of CIWs */ | |
49 | } QEMU_PACKED SenseId; | |
50 | ||
51 | /* Channel measurements, from linux/drivers/s390/cio/cmf.c. */ | |
52 | typedef struct CMB { | |
53 | uint16_t ssch_rsch_count; | |
54 | uint16_t sample_count; | |
55 | uint32_t device_connect_time; | |
56 | uint32_t function_pending_time; | |
57 | uint32_t device_disconnect_time; | |
58 | uint32_t control_unit_queuing_time; | |
59 | uint32_t device_active_only_time; | |
60 | uint32_t reserved[2]; | |
61 | } QEMU_PACKED CMB; | |
62 | ||
63 | typedef struct CMBE { | |
64 | uint32_t ssch_rsch_count; | |
65 | uint32_t sample_count; | |
66 | uint32_t device_connect_time; | |
67 | uint32_t function_pending_time; | |
68 | uint32_t device_disconnect_time; | |
69 | uint32_t control_unit_queuing_time; | |
70 | uint32_t device_active_only_time; | |
71 | uint32_t device_busy_time; | |
72 | uint32_t initial_command_response_time; | |
73 | uint32_t reserved[7]; | |
74 | } QEMU_PACKED CMBE; | |
75 | ||
bd3f16ac | 76 | typedef struct SubchDev SubchDev; |
df1fe5bb CH |
77 | struct SubchDev { |
78 | /* channel-subsystem related things: */ | |
79 | uint8_t cssid; | |
80 | uint8_t ssid; | |
81 | uint16_t schid; | |
82 | uint16_t devno; | |
83 | SCHIB curr_status; | |
84 | uint8_t sense_data[32]; | |
85 | hwaddr channel_prog; | |
86 | CCW1 last_cmd; | |
87 | bool last_cmd_valid; | |
a327c921 | 88 | bool ccw_fmt_1; |
7e749462 | 89 | bool thinint_active; |
e8601dd5 | 90 | uint8_t ccw_no_data_cnt; |
df1fe5bb CH |
91 | /* transport-provided data: */ |
92 | int (*ccw_cb) (SubchDev *, CCW1); | |
62ac4a52 | 93 | void (*disable_cb)(SubchDev *); |
df1fe5bb CH |
94 | SenseId id; |
95 | void *driver_data; | |
96 | }; | |
97 | ||
8f3cf012 XFR |
98 | /* |
99 | * Identify a device within the channel subsystem. | |
100 | * Note that this can be used to identify either the subchannel or | |
101 | * the attached I/O device, as there's always one I/O device per | |
102 | * subchannel. | |
103 | */ | |
104 | typedef struct CssDevId { | |
105 | uint8_t cssid; | |
106 | uint8_t ssid; | |
107 | uint16_t devid; | |
108 | bool valid; | |
109 | } CssDevId; | |
110 | ||
111 | extern PropertyInfo css_devid_propinfo; | |
112 | ||
113 | #define DEFINE_PROP_CSS_DEV_ID(_n, _s, _f) \ | |
114 | DEFINE_PROP(_n, _s, _f, css_devid_propinfo, CssDevId) | |
115 | ||
a28d8391 YMZ |
116 | typedef struct IndAddr { |
117 | hwaddr addr; | |
118 | uint64_t map; | |
119 | unsigned long refcnt; | |
120 | int len; | |
121 | QTAILQ_ENTRY(IndAddr) sibling; | |
122 | } IndAddr; | |
123 | ||
124 | IndAddr *get_indicator(hwaddr ind_addr, int len); | |
125 | void release_indicator(AdapterInfo *adapter, IndAddr *indicator); | |
126 | int map_indicator(AdapterInfo *adapter, IndAddr *indicator); | |
127 | ||
df1fe5bb CH |
128 | typedef SubchDev *(*css_subch_cb_func)(uint8_t m, uint8_t cssid, uint8_t ssid, |
129 | uint16_t schid); | |
bcb2b582 JF |
130 | void subch_device_save(SubchDev *s, QEMUFile *f); |
131 | int subch_device_load(SubchDev *s, QEMUFile *f); | |
df1fe5bb CH |
132 | int css_create_css_image(uint8_t cssid, bool default_image); |
133 | bool css_devno_used(uint8_t cssid, uint8_t ssid, uint16_t devno); | |
134 | void css_subch_assign(uint8_t cssid, uint8_t ssid, uint16_t schid, | |
135 | uint16_t devno, SubchDev *sch); | |
136 | void css_sch_build_virtual_schib(SubchDev *sch, uint8_t chpid, uint8_t type); | |
8f3cf012 | 137 | int css_sch_build_schib(SubchDev *sch, CssDevId *dev_id); |
6c15e9bf | 138 | unsigned int css_find_free_chpid(uint8_t cssid); |
b4436a0b | 139 | uint16_t css_build_subchannel_id(SubchDev *sch); |
df1fe5bb CH |
140 | void css_reset(void); |
141 | void css_reset_sch(SubchDev *sch); | |
142 | void css_queue_crw(uint8_t rsc, uint8_t erc, int chain, uint16_t rsid); | |
143 | void css_generate_sch_crws(uint8_t cssid, uint8_t ssid, uint16_t schid, | |
144 | int hotplugged, int add); | |
145 | void css_generate_chp_crws(uint8_t cssid, uint8_t chpid); | |
8cba80c3 | 146 | void css_generate_css_crws(uint8_t cssid); |
c81b4f89 | 147 | void css_clear_sei_pending(void); |
7e749462 | 148 | void css_adapter_interrupt(uint8_t isc); |
03cf077a | 149 | |
5b00bef2 FL |
150 | typedef enum { |
151 | CSS_IO_ADAPTER_VIRTIO = 0, | |
152 | CSS_IO_ADAPTER_PCI = 1, | |
153 | CSS_IO_ADAPTER_TYPE_NUMS, | |
154 | } CssIoAdapterType; | |
155 | ||
dde522bb FL |
156 | uint32_t css_get_adapter_id(CssIoAdapterType type, uint8_t isc); |
157 | void css_register_io_adapters(CssIoAdapterType type, bool swap, bool maskable, | |
158 | Error **errp); | |
bd3f16ac PB |
159 | |
160 | #ifndef CONFIG_USER_ONLY | |
161 | SubchDev *css_find_subch(uint8_t m, uint8_t cssid, uint8_t ssid, | |
162 | uint16_t schid); | |
163 | bool css_subch_visible(SubchDev *sch); | |
164 | void css_conditional_io_interrupt(SubchDev *sch); | |
165 | int css_do_stsch(SubchDev *sch, SCHIB *schib); | |
166 | bool css_schid_final(int m, uint8_t cssid, uint8_t ssid, uint16_t schid); | |
167 | int css_do_msch(SubchDev *sch, const SCHIB *schib); | |
168 | int css_do_xsch(SubchDev *sch); | |
169 | int css_do_csch(SubchDev *sch); | |
170 | int css_do_hsch(SubchDev *sch); | |
171 | int css_do_ssch(SubchDev *sch, ORB *orb); | |
172 | int css_do_tsch_get_irb(SubchDev *sch, IRB *irb, int *irb_len); | |
173 | void css_do_tsch_update_subch(SubchDev *sch); | |
174 | int css_do_stcrw(CRW *crw); | |
175 | void css_undo_stcrw(CRW *crw); | |
176 | int css_do_tpi(IOIntCode *int_code, int lowcore); | |
177 | int css_collect_chp_desc(int m, uint8_t cssid, uint8_t f_chpid, uint8_t l_chpid, | |
178 | int rfmt, void *buf); | |
179 | void css_do_schm(uint8_t mbk, int update, int dct, uint64_t mbo); | |
180 | int css_enable_mcsse(void); | |
181 | int css_enable_mss(void); | |
182 | int css_do_rsch(SubchDev *sch); | |
183 | int css_do_rchp(uint8_t cssid, uint8_t chpid); | |
184 | bool css_present(uint8_t cssid); | |
185 | #endif | |
186 | ||
c35fc6aa DJS |
187 | extern PropertyInfo css_devid_ro_propinfo; |
188 | ||
189 | #define DEFINE_PROP_CSS_DEV_ID_RO(_n, _s, _f) \ | |
190 | DEFINE_PROP(_n, _s, _f, css_devid_ro_propinfo, CssDevId) | |
191 | ||
cf249935 SS |
192 | /** |
193 | * Create a subchannel for the given bus id. | |
194 | * | |
195 | * If @p bus_id is valid, verify that it uses the virtual channel | |
196 | * subsystem id and is not already in use, and find a free subchannel | |
197 | * id for it. If @p bus_id is not valid, find a free subchannel id and | |
198 | * device number across all subchannel sets. If either of the former | |
199 | * actions succeed, allocate a subchannel structure, initialise it | |
200 | * with the bus id, subchannel id and device number, register it with | |
201 | * the CSS and return it. Otherwise return NULL. | |
202 | * | |
203 | * The caller becomes owner of the returned subchannel structure and | |
204 | * is responsible for unregistering and freeing it. | |
205 | */ | |
206 | SubchDev *css_create_virtual_sch(CssDevId bus_id, Error **errp); | |
df1fe5bb | 207 | #endif |