blob: 2150aed541be1b23a9eaa569cffbbb763e2ee414 [file] [log] [blame]
Horst Hummel138c0142006-06-29 14:58:12 +02001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 * File...........: linux/drivers/s390/block/dasd_eckd.h
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
Horst Hummel138c0142006-06-29 14:58:12 +02004 * Horst Hummel <Horst.Hummel@de.ibm.com>
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 * Bugreports.to..: <Linux390@de.ibm.com>
6 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
7 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07008 */
9
10#ifndef DASD_ECKD_H
11#define DASD_ECKD_H
12
13/*****************************************************************************
14 * SECTION: CCW Definitions
15 ****************************************************************************/
16#define DASD_ECKD_CCW_WRITE 0x05
17#define DASD_ECKD_CCW_READ 0x06
18#define DASD_ECKD_CCW_WRITE_HOME_ADDRESS 0x09
19#define DASD_ECKD_CCW_READ_HOME_ADDRESS 0x0a
20#define DASD_ECKD_CCW_WRITE_KD 0x0d
21#define DASD_ECKD_CCW_READ_KD 0x0e
22#define DASD_ECKD_CCW_ERASE 0x11
23#define DASD_ECKD_CCW_READ_COUNT 0x12
24#define DASD_ECKD_CCW_SLCK 0x14
25#define DASD_ECKD_CCW_WRITE_RECORD_ZERO 0x15
26#define DASD_ECKD_CCW_READ_RECORD_ZERO 0x16
27#define DASD_ECKD_CCW_WRITE_CKD 0x1d
28#define DASD_ECKD_CCW_READ_CKD 0x1e
29#define DASD_ECKD_CCW_PSF 0x27
Stefan Weinhuber196339f2010-10-29 16:50:43 +020030#define DASD_ECKD_CCW_SNID 0x34
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#define DASD_ECKD_CCW_RSSD 0x3e
32#define DASD_ECKD_CCW_LOCATE_RECORD 0x47
Stefan Weinhuber20c64462006-03-24 03:15:25 -080033#define DASD_ECKD_CCW_SNSS 0x54
Linus Torvalds1da177e2005-04-16 15:20:36 -070034#define DASD_ECKD_CCW_DEFINE_EXTENT 0x63
35#define DASD_ECKD_CCW_WRITE_MT 0x85
36#define DASD_ECKD_CCW_READ_MT 0x86
37#define DASD_ECKD_CCW_WRITE_KD_MT 0x8d
38#define DASD_ECKD_CCW_READ_KD_MT 0x8e
39#define DASD_ECKD_CCW_RELEASE 0x94
40#define DASD_ECKD_CCW_READ_CKD_MT 0x9e
41#define DASD_ECKD_CCW_WRITE_CKD_MT 0x9d
Stefan Weinhuberf3eb5382009-03-26 15:23:48 +010042#define DASD_ECKD_CCW_WRITE_TRACK_DATA 0xA5
43#define DASD_ECKD_CCW_READ_TRACK_DATA 0xA6
Linus Torvalds1da177e2005-04-16 15:20:36 -070044#define DASD_ECKD_CCW_RESERVE 0xB4
Stefan Weinhuber8e09f212008-01-26 14:11:23 +010045#define DASD_ECKD_CCW_PFX 0xE7
Stefan Weinhuberf3eb5382009-03-26 15:23:48 +010046#define DASD_ECKD_CCW_PFX_READ 0xEA
Stefan Weinhuber8e09f212008-01-26 14:11:23 +010047#define DASD_ECKD_CCW_RSCK 0xF9
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
49/*
Horst Hummel40545572006-06-29 15:08:18 +020050 * Perform Subsystem Function / Sub-Orders
Linus Torvalds1da177e2005-04-16 15:20:36 -070051 */
Horst Hummel40545572006-06-29 15:08:18 +020052#define PSF_ORDER_PRSSD 0x18
53#define PSF_ORDER_SSC 0x1D
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
Stefan Weinhuberb44b0ab32009-03-26 15:23:47 +010055/*
56 * Size that is reportet for large volumes in the old 16-bit no_cyl field
57 */
58#define LV_COMPAT_CYL 0xFFFE
59
Stefan Weinhuberef19298b2011-01-05 12:48:02 +010060
61#define FCX_MAX_DATA_FACTOR 65536
62
63
Linus Torvalds1da177e2005-04-16 15:20:36 -070064/*****************************************************************************
65 * SECTION: Type Definitions
66 ****************************************************************************/
67
68struct eckd_count {
69 __u16 cyl;
70 __u16 head;
71 __u8 record;
72 __u8 kl;
73 __u16 dl;
74} __attribute__ ((packed));
75
76struct ch_t {
77 __u16 cyl;
78 __u16 head;
79} __attribute__ ((packed));
80
81struct chs_t {
82 __u16 cyl;
83 __u16 head;
84 __u32 sector;
85} __attribute__ ((packed));
86
87struct chr_t {
88 __u16 cyl;
89 __u16 head;
90 __u8 record;
91} __attribute__ ((packed));
92
93struct geom_t {
94 __u16 cyl;
95 __u16 head;
96 __u32 sector;
97} __attribute__ ((packed));
98
99struct eckd_home {
100 __u8 skip_control[14];
101 __u16 cell_number;
102 __u8 physical_addr[3];
103 __u8 flag;
104 struct ch_t track_addr;
105 __u8 reserved;
106 __u8 key_length;
107 __u8 reserved2[2];
108} __attribute__ ((packed));
109
110struct DE_eckd_data {
111 struct {
112 unsigned char perm:2; /* Permissions on this extent */
113 unsigned char reserved:1;
114 unsigned char seek:2; /* Seek control */
115 unsigned char auth:2; /* Access authorization */
116 unsigned char pci:1; /* PCI Fetch mode */
117 } __attribute__ ((packed)) mask;
118 struct {
119 unsigned char mode:2; /* Architecture mode */
120 unsigned char ckd:1; /* CKD Conversion */
121 unsigned char operation:3; /* Operation mode */
122 unsigned char cfw:1; /* Cache fast write */
123 unsigned char dfw:1; /* DASD fast write */
124 } __attribute__ ((packed)) attributes;
125 __u16 blk_size; /* Blocksize */
126 __u16 fast_write_id;
127 __u8 ga_additional; /* Global Attributes Additional */
128 __u8 ga_extended; /* Global Attributes Extended */
129 struct ch_t beg_ext;
130 struct ch_t end_ext;
131 unsigned long long ep_sys_time; /* Ext Parameter - System Time Stamp */
132 __u8 ep_format; /* Extended Parameter format byte */
133 __u8 ep_prio; /* Extended Parameter priority I/O byte */
Stefan Weinhuberf3eb5382009-03-26 15:23:48 +0100134 __u8 ep_reserved1; /* Extended Parameter Reserved */
135 __u8 ep_rec_per_track; /* Number of records on a track */
136 __u8 ep_reserved[4]; /* Extended Parameter Reserved */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137} __attribute__ ((packed));
138
139struct LO_eckd_data {
140 struct {
141 unsigned char orientation:2;
142 unsigned char operation:6;
143 } __attribute__ ((packed)) operation;
144 struct {
145 unsigned char last_bytes_used:1;
146 unsigned char reserved:6;
147 unsigned char read_count_suffix:1;
148 } __attribute__ ((packed)) auxiliary;
149 __u8 unused;
150 __u8 count;
151 struct ch_t seek_addr;
152 struct chr_t search_arg;
153 __u8 sector;
154 __u16 length;
155} __attribute__ ((packed));
156
Stefan Weinhuberf3eb5382009-03-26 15:23:48 +0100157struct LRE_eckd_data {
158 struct {
159 unsigned char orientation:2;
160 unsigned char operation:6;
161 } __attribute__ ((packed)) operation;
162 struct {
163 unsigned char length_valid:1;
164 unsigned char length_scope:1;
165 unsigned char imbedded_ccw_valid:1;
166 unsigned char check_bytes:2;
167 unsigned char imbedded_count_valid:1;
168 unsigned char reserved:1;
169 unsigned char read_count_suffix:1;
170 } __attribute__ ((packed)) auxiliary;
171 __u8 imbedded_ccw;
172 __u8 count;
173 struct ch_t seek_addr;
174 struct chr_t search_arg;
175 __u8 sector;
176 __u16 length;
177 __u8 imbedded_count;
178 __u8 extended_operation;
179 __u16 extended_parameter_length;
180 __u8 extended_parameter[0];
181} __attribute__ ((packed));
182
Stefan Weinhuber8e09f212008-01-26 14:11:23 +0100183/* Prefix data for format 0x00 and 0x01 */
184struct PFX_eckd_data {
185 unsigned char format;
186 struct {
Stefan Weinhuberf3eb5382009-03-26 15:23:48 +0100187 unsigned char define_extent:1;
Stefan Weinhuber8e09f212008-01-26 14:11:23 +0100188 unsigned char time_stamp:1;
189 unsigned char verify_base:1;
190 unsigned char hyper_pav:1;
191 unsigned char reserved:4;
192 } __attribute__ ((packed)) validity;
193 __u8 base_address;
194 __u8 aux;
195 __u8 base_lss;
196 __u8 reserved[7];
Stefan Weinhuberf3eb5382009-03-26 15:23:48 +0100197 struct DE_eckd_data define_extent;
198 struct LRE_eckd_data locate_record;
Stefan Weinhuber8e09f212008-01-26 14:11:23 +0100199} __attribute__ ((packed));
200
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201struct dasd_eckd_characteristics {
202 __u16 cu_type;
203 struct {
204 unsigned char support:2;
205 unsigned char async:1;
206 unsigned char reserved:1;
207 unsigned char cache_info:1;
208 unsigned char model:3;
209 } __attribute__ ((packed)) cu_model;
210 __u16 dev_type;
211 __u8 dev_model;
212 struct {
213 unsigned char mult_burst:1;
214 unsigned char RT_in_LR:1;
215 unsigned char reserved1:1;
216 unsigned char RD_IN_LR:1;
217 unsigned char reserved2:4;
218 unsigned char reserved3:8;
219 unsigned char defect_wr:1;
Horst Hummel138c0142006-06-29 14:58:12 +0200220 unsigned char XRC_supported:1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221 unsigned char reserved4:1;
222 unsigned char striping:1;
223 unsigned char reserved5:4;
224 unsigned char cfw:1;
225 unsigned char reserved6:2;
226 unsigned char cache:1;
227 unsigned char dual_copy:1;
228 unsigned char dfw:1;
229 unsigned char reset_alleg:1;
230 unsigned char sense_down:1;
231 } __attribute__ ((packed)) facilities;
232 __u8 dev_class;
233 __u8 unit_type;
234 __u16 no_cyl;
235 __u16 trk_per_cyl;
236 __u8 sec_per_trk;
237 __u8 byte_per_track[3];
238 __u16 home_bytes;
239 __u8 formula;
240 union {
241 struct {
242 __u8 f1;
243 __u16 f2;
244 __u16 f3;
245 } __attribute__ ((packed)) f_0x01;
246 struct {
247 __u8 f1;
248 __u8 f2;
249 __u8 f3;
250 __u8 f4;
251 __u8 f5;
252 } __attribute__ ((packed)) f_0x02;
253 } __attribute__ ((packed)) factors;
254 __u16 first_alt_trk;
255 __u16 no_alt_trk;
256 __u16 first_dia_trk;
257 __u16 no_dia_trk;
258 __u16 first_sup_trk;
259 __u16 no_sup_trk;
260 __u8 MDR_ID;
261 __u8 OBR_ID;
262 __u8 director;
263 __u8 rd_trk_set;
264 __u16 max_rec_zero;
265 __u8 reserved1;
266 __u8 RWANY_in_LR;
267 __u8 factor6;
268 __u8 factor7;
269 __u8 factor8;
270 __u8 reserved2[3];
Stefan Weinhuberb44b0ab32009-03-26 15:23:47 +0100271 __u8 reserved3[6];
272 __u32 long_no_cyl;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273} __attribute__ ((packed));
274
Stefan Weinhuber4abb08c2008-08-01 16:39:09 +0200275/* elements of the configuration data */
276struct dasd_ned {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277 struct {
Stefan Weinhuber4abb08c2008-08-01 16:39:09 +0200278 __u8 identifier:2;
279 __u8 token_id:1;
280 __u8 sno_valid:1;
281 __u8 subst_sno:1;
282 __u8 recNED:1;
283 __u8 emuNED:1;
284 __u8 reserved:1;
285 } __attribute__ ((packed)) flags;
286 __u8 descriptor;
287 __u8 dev_class;
288 __u8 reserved;
289 __u8 dev_type[6];
290 __u8 dev_model[3];
291 __u8 HDA_manufacturer[3];
292 __u8 HDA_location[2];
293 __u8 HDA_seqno[12];
294 __u8 ID;
295 __u8 unit_addr;
296} __attribute__ ((packed));
297
298struct dasd_sneq {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299 struct {
Stefan Weinhuber4abb08c2008-08-01 16:39:09 +0200300 __u8 identifier:2;
301 __u8 reserved:6;
302 } __attribute__ ((packed)) flags;
303 __u8 res1;
304 __u16 format;
305 __u8 res2[4]; /* byte 4- 7 */
306 __u8 sua_flags; /* byte 8 */
307 __u8 base_unit_addr; /* byte 9 */
308 __u8 res3[22]; /* byte 10-31 */
309} __attribute__ ((packed));
310
311struct vd_sneq {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312 struct {
Stefan Weinhuber4abb08c2008-08-01 16:39:09 +0200313 __u8 identifier:2;
314 __u8 reserved:6;
315 } __attribute__ ((packed)) flags;
316 __u8 res1;
317 __u16 format;
318 __u8 res2[4]; /* byte 4- 7 */
319 __u8 uit[16]; /* byte 8-23 */
320 __u8 res3[8]; /* byte 24-31 */
321} __attribute__ ((packed));
322
323struct dasd_gneq {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324 struct {
Stefan Weinhuber4abb08c2008-08-01 16:39:09 +0200325 __u8 identifier:2;
326 __u8 reserved:6;
327 } __attribute__ ((packed)) flags;
Stefan Haberland7c8faa82010-08-09 18:13:00 +0200328 __u8 reserved[5];
329 struct {
330 __u8 value:2;
331 __u8 number:6;
332 } __attribute__ ((packed)) timeout;
333 __u8 reserved3;
Stefan Weinhuber4abb08c2008-08-01 16:39:09 +0200334 __u16 subsystemID;
335 __u8 reserved2[22];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336} __attribute__ ((packed));
337
338struct dasd_eckd_path {
339 __u8 opm;
340 __u8 ppm;
341 __u8 npm;
342};
343
Stefan Weinhuber8e09f212008-01-26 14:11:23 +0100344struct dasd_rssd_features {
345 char feature[256];
346} __attribute__((packed));
347
348
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349/*
Horst Hummel138c0142006-06-29 14:58:12 +0200350 * Perform Subsystem Function - Prepare for Read Subsystem Data
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351 */
352struct dasd_psf_prssd_data {
353 unsigned char order;
354 unsigned char flags;
355 unsigned char reserved[4];
356 unsigned char suborder;
Stefan Weinhuber49fd38b2008-08-21 19:46:38 +0200357 unsigned char varies[5];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358} __attribute__ ((packed));
359
Horst Hummel40545572006-06-29 15:08:18 +0200360/*
361 * Perform Subsystem Function - Set Subsystem Characteristics
362 */
363struct dasd_psf_ssc_data {
364 unsigned char order;
365 unsigned char flags;
366 unsigned char cu_type[4];
367 unsigned char suborder;
368 unsigned char reserved[59];
369} __attribute__((packed));
370
Stefan Weinhuber8e09f212008-01-26 14:11:23 +0100371
372/*
373 * some structures and definitions for alias handling
374 */
375struct dasd_unit_address_configuration {
376 struct {
377 char ua_type;
378 char base_ua;
379 } unit[256];
380} __attribute__((packed));
381
382
383#define MAX_DEVICES_PER_LCU 256
384
385/* flags on the LCU */
386#define NEED_UAC_UPDATE 0x01
387#define UPDATE_PENDING 0x02
388
389enum pavtype {NO_PAV, BASE_PAV, HYPER_PAV};
390
391
392struct alias_root {
393 struct list_head serverlist;
394 spinlock_t lock;
395};
396
397struct alias_server {
398 struct list_head server;
399 struct dasd_uid uid;
400 struct list_head lculist;
401};
402
403struct summary_unit_check_work_data {
404 char reason;
405 struct dasd_device *device;
406 struct work_struct worker;
407};
408
409struct read_uac_work_data {
410 struct dasd_device *device;
411 struct delayed_work dwork;
412};
413
414struct alias_lcu {
415 struct list_head lcu;
416 struct dasd_uid uid;
417 enum pavtype pav;
418 char flags;
419 spinlock_t lock;
420 struct list_head grouplist;
421 struct list_head active_devices;
422 struct list_head inactive_devices;
423 struct dasd_unit_address_configuration *uac;
424 struct summary_unit_check_work_data suc_data;
425 struct read_uac_work_data ruac_data;
426 struct dasd_ccw_req *rsu_cqr;
Stefan Weinhuberf4ac1d02009-12-07 12:51:53 +0100427 struct completion lcu_setup;
Stefan Weinhuber8e09f212008-01-26 14:11:23 +0100428};
429
430struct alias_pav_group {
431 struct list_head group;
432 struct dasd_uid uid;
433 struct alias_lcu *lcu;
434 struct list_head baselist;
435 struct list_head aliaslist;
436 struct dasd_device *next;
437};
438
Stefan Weinhuber8e09f212008-01-26 14:11:23 +0100439struct dasd_eckd_private {
440 struct dasd_eckd_characteristics rdc_data;
Stefan Weinhuber4abb08c2008-08-01 16:39:09 +0200441 u8 *conf_data;
442 int conf_len;
443 /* pointers to specific parts in the conf_data */
444 struct dasd_ned *ned;
445 struct dasd_sneq *sneq;
446 struct vd_sneq *vdsneq;
447 struct dasd_gneq *gneq;
448
Stefan Weinhuber8e09f212008-01-26 14:11:23 +0100449 struct dasd_eckd_path path_data;
450 struct eckd_count count_area[5];
451 int init_cqr_status;
452 int uses_cdl;
453 struct attrib_data_t attrib; /* e.g. cache operations */
454 struct dasd_rssd_features features;
Stefan Weinhuberb44b0ab32009-03-26 15:23:47 +0100455 u32 real_cyl;
Stefan Weinhuber8e09f212008-01-26 14:11:23 +0100456
457 /* alias managemnet */
458 struct dasd_uid uid;
459 struct alias_pav_group *pavgroup;
460 struct alias_lcu *lcu;
461 int count;
Stefan Weinhuberef19298b2011-01-05 12:48:02 +0100462
463 u32 fcx_max_data;
Stefan Weinhuber8e09f212008-01-26 14:11:23 +0100464};
465
466
467
468int dasd_alias_make_device_known_to_lcu(struct dasd_device *);
469void dasd_alias_disconnect_device_from_lcu(struct dasd_device *);
470int dasd_alias_add_device(struct dasd_device *);
471int dasd_alias_remove_device(struct dasd_device *);
472struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *);
473void dasd_alias_handle_summary_unit_check(struct dasd_device *, struct irb *);
474void dasd_eckd_reset_ccw_to_base_io(struct dasd_ccw_req *);
Stefan Weinhuberf4ac1d02009-12-07 12:51:53 +0100475void dasd_alias_lcu_setup_complete(struct dasd_device *);
476void dasd_alias_wait_for_lcu_setup(struct dasd_device *);
Stefan Haberland501183f2010-05-17 10:00:10 +0200477int dasd_alias_update_add_device(struct dasd_device *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478#endif /* DASD_ECKD_H */