aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block/dasd_eckd.h
diff options
context:
space:
mode:
authorStefan Weinhuber <wein@de.ibm.com>2008-01-26 08:11:23 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2008-01-26 08:11:28 -0500
commit8e09f21574ea3028d5629e5de759e0b196c690c5 (patch)
treeced4feb1847ee6c2a7b7b4cec8f3118f83d3a386 /drivers/s390/block/dasd_eckd.h
parent0ac30be461084f30ad6e22c6b91347e880ed41aa (diff)
[S390] dasd: add hyper PAV support to DASD device driver, part 1
Parallel access volumes (PAV) is a storage server feature, that allows to start multiple channel programs on the same DASD in parallel. It defines alias devices which can be used as alternative paths to the same disk. With the old base PAV support we only needed rudimentary functionality in the DASD device driver. As the mapping between base and alias devices was static, we just had to export an identifier (uid) and could leave the combining of devices to external layers like a device mapper multipath. Now hyper PAV removes the requirement to dedicate alias devices to specific base devices. Instead each alias devices can be combined with multiple base device on a per request basis. This requires full support by the DASD device driver as now each channel program itself has to identify the target base device. The changes to the dasd device driver and the ECKD discipline are: - Separate subchannel device representation (dasd_device) from block device representation (dasd_block). Only base devices are block devices. - Gather information about base and alias devices and possible combinations. - For each request decide which dasd_device should be used (base or alias) and build specific channel program. - Support summary unit checks, which allow the storage server to upgrade / downgrade between base and hyper PAV at runtime (support is mandatory). Signed-off-by: Stefan Weinhuber <wein@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/block/dasd_eckd.h')
-rw-r--r--drivers/s390/block/dasd_eckd.h125
1 files changed, 124 insertions, 1 deletions
diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h
index 712ff1650134..fc2509c939bc 100644
--- a/drivers/s390/block/dasd_eckd.h
+++ b/drivers/s390/block/dasd_eckd.h
@@ -39,6 +39,8 @@
39#define DASD_ECKD_CCW_READ_CKD_MT 0x9e 39#define DASD_ECKD_CCW_READ_CKD_MT 0x9e
40#define DASD_ECKD_CCW_WRITE_CKD_MT 0x9d 40#define DASD_ECKD_CCW_WRITE_CKD_MT 0x9d
41#define DASD_ECKD_CCW_RESERVE 0xB4 41#define DASD_ECKD_CCW_RESERVE 0xB4
42#define DASD_ECKD_CCW_PFX 0xE7
43#define DASD_ECKD_CCW_RSCK 0xF9
42 44
43/* 45/*
44 * Perform Subsystem Function / Sub-Orders 46 * Perform Subsystem Function / Sub-Orders
@@ -137,6 +139,25 @@ struct LO_eckd_data {
137 __u16 length; 139 __u16 length;
138} __attribute__ ((packed)); 140} __attribute__ ((packed));
139 141
142/* Prefix data for format 0x00 and 0x01 */
143struct PFX_eckd_data {
144 unsigned char format;
145 struct {
146 unsigned char define_extend:1;
147 unsigned char time_stamp:1;
148 unsigned char verify_base:1;
149 unsigned char hyper_pav:1;
150 unsigned char reserved:4;
151 } __attribute__ ((packed)) validity;
152 __u8 base_address;
153 __u8 aux;
154 __u8 base_lss;
155 __u8 reserved[7];
156 struct DE_eckd_data define_extend;
157 struct LO_eckd_data locate_record;
158 __u8 LO_extended_data[4];
159} __attribute__ ((packed));
160
140struct dasd_eckd_characteristics { 161struct dasd_eckd_characteristics {
141 __u16 cu_type; 162 __u16 cu_type;
142 struct { 163 struct {
@@ -254,7 +275,9 @@ struct dasd_eckd_confdata {
254 } __attribute__ ((packed)) ned; 275 } __attribute__ ((packed)) ned;
255 struct { 276 struct {
256 unsigned char flags; /* byte 0 */ 277 unsigned char flags; /* byte 0 */
257 unsigned char res2[7]; /* byte 1- 7 */ 278 unsigned char res1; /* byte 1 */
279 __u16 format; /* byte 2-3 */
280 unsigned char res2[4]; /* byte 4-7 */
258 unsigned char sua_flags; /* byte 8 */ 281 unsigned char sua_flags; /* byte 8 */
259 __u8 base_unit_addr; /* byte 9 */ 282 __u8 base_unit_addr; /* byte 9 */
260 unsigned char res3[22]; /* byte 10-31 */ 283 unsigned char res3[22]; /* byte 10-31 */
@@ -343,6 +366,11 @@ struct dasd_eckd_path {
343 __u8 npm; 366 __u8 npm;
344}; 367};
345 368
369struct dasd_rssd_features {
370 char feature[256];
371} __attribute__((packed));
372
373
346/* 374/*
347 * Perform Subsystem Function - Prepare for Read Subsystem Data 375 * Perform Subsystem Function - Prepare for Read Subsystem Data
348 */ 376 */
@@ -365,4 +393,99 @@ struct dasd_psf_ssc_data {
365 unsigned char reserved[59]; 393 unsigned char reserved[59];
366} __attribute__((packed)); 394} __attribute__((packed));
367 395
396
397/*
398 * some structures and definitions for alias handling
399 */
400struct dasd_unit_address_configuration {
401 struct {
402 char ua_type;
403 char base_ua;
404 } unit[256];
405} __attribute__((packed));
406
407
408#define MAX_DEVICES_PER_LCU 256
409
410/* flags on the LCU */
411#define NEED_UAC_UPDATE 0x01
412#define UPDATE_PENDING 0x02
413
414enum pavtype {NO_PAV, BASE_PAV, HYPER_PAV};
415
416
417struct alias_root {
418 struct list_head serverlist;
419 spinlock_t lock;
420};
421
422struct alias_server {
423 struct list_head server;
424 struct dasd_uid uid;
425 struct list_head lculist;
426};
427
428struct summary_unit_check_work_data {
429 char reason;
430 struct dasd_device *device;
431 struct work_struct worker;
432};
433
434struct read_uac_work_data {
435 struct dasd_device *device;
436 struct delayed_work dwork;
437};
438
439struct alias_lcu {
440 struct list_head lcu;
441 struct dasd_uid uid;
442 enum pavtype pav;
443 char flags;
444 spinlock_t lock;
445 struct list_head grouplist;
446 struct list_head active_devices;
447 struct list_head inactive_devices;
448 struct dasd_unit_address_configuration *uac;
449 struct summary_unit_check_work_data suc_data;
450 struct read_uac_work_data ruac_data;
451 struct dasd_ccw_req *rsu_cqr;
452};
453
454struct alias_pav_group {
455 struct list_head group;
456 struct dasd_uid uid;
457 struct alias_lcu *lcu;
458 struct list_head baselist;
459 struct list_head aliaslist;
460 struct dasd_device *next;
461};
462
463
464struct dasd_eckd_private {
465 struct dasd_eckd_characteristics rdc_data;
466 struct dasd_eckd_confdata conf_data;
467 struct dasd_eckd_path path_data;
468 struct eckd_count count_area[5];
469 int init_cqr_status;
470 int uses_cdl;
471 struct attrib_data_t attrib; /* e.g. cache operations */
472 struct dasd_rssd_features features;
473
474 /* alias managemnet */
475 struct dasd_uid uid;
476 struct alias_pav_group *pavgroup;
477 struct alias_lcu *lcu;
478 int count;
479};
480
481
482
483int dasd_alias_make_device_known_to_lcu(struct dasd_device *);
484void dasd_alias_disconnect_device_from_lcu(struct dasd_device *);
485int dasd_alias_add_device(struct dasd_device *);
486int dasd_alias_remove_device(struct dasd_device *);
487struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *);
488void dasd_alias_handle_summary_unit_check(struct dasd_device *, struct irb *);
489void dasd_eckd_reset_ccw_to_base_io(struct dasd_ccw_req *);
490
368#endif /* DASD_ECKD_H */ 491#endif /* DASD_ECKD_H */