1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 4 * Horst Hummel <Horst.Hummel@de.ibm.com> 5 * Bugreports.to..: <Linux390@de.ibm.com> 6 * Copyright IBM Corp. 1999, 2000 7 * 8 */ 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 30 #define DASD_ECKD_CCW_SNID 0x34 31 #define DASD_ECKD_CCW_RSSD 0x3e 32 #define DASD_ECKD_CCW_LOCATE_RECORD 0x47 33 #define DASD_ECKD_CCW_LOCATE_RECORD_EXT 0x4b 34 #define DASD_ECKD_CCW_SNSS 0x54 35 #define DASD_ECKD_CCW_DEFINE_EXTENT 0x63 36 #define DASD_ECKD_CCW_WRITE_MT 0x85 37 #define DASD_ECKD_CCW_READ_MT 0x86 38 #define DASD_ECKD_CCW_WRITE_KD_MT 0x8d 39 #define DASD_ECKD_CCW_READ_KD_MT 0x8e 40 #define DASD_ECKD_CCW_READ_COUNT_MT 0x92 41 #define DASD_ECKD_CCW_RELEASE 0x94 42 #define DASD_ECKD_CCW_WRITE_FULL_TRACK 0x95 43 #define DASD_ECKD_CCW_READ_CKD_MT 0x9e 44 #define DASD_ECKD_CCW_WRITE_CKD_MT 0x9d 45 #define DASD_ECKD_CCW_WRITE_TRACK_DATA 0xA5 46 #define DASD_ECKD_CCW_READ_TRACK_DATA 0xA6 47 #define DASD_ECKD_CCW_RESERVE 0xB4 48 #define DASD_ECKD_CCW_READ_TRACK 0xDE 49 #define DASD_ECKD_CCW_PFX 0xE7 50 #define DASD_ECKD_CCW_PFX_READ 0xEA 51 #define DASD_ECKD_CCW_RSCK 0xF9 52 #define DASD_ECKD_CCW_RCD 0xFA 53 #define DASD_ECKD_CCW_DSO 0xF7 54 55 /* Define Subssystem Function / Orders */ 56 #define DSO_ORDER_RAS 0x81 57 58 /* 59 * Perform Subsystem Function / Orders 60 */ 61 #define PSF_ORDER_PRSSD 0x18 62 #define PSF_ORDER_CUIR_RESPONSE 0x1A 63 #define PSF_ORDER_SSC 0x1D 64 65 /* 66 * Perform Subsystem Function / Sub-Orders 67 */ 68 #define PSF_SUBORDER_QHA 0x1C /* Query Host Access */ 69 #define PSF_SUBORDER_VSQ 0x52 /* Volume Storage Query */ 70 #define PSF_SUBORDER_LCQ 0x53 /* Logical Configuration Query */ 71 72 /* 73 * CUIR response condition codes 74 */ 75 #define PSF_CUIR_INVALID 0x00 76 #define PSF_CUIR_COMPLETED 0x01 77 #define PSF_CUIR_NOT_SUPPORTED 0x02 78 #define PSF_CUIR_ERROR_IN_REQ 0x03 79 #define PSF_CUIR_DENIED 0x04 80 #define PSF_CUIR_LAST_PATH 0x05 81 #define PSF_CUIR_DEVICE_ONLINE 0x06 82 #define PSF_CUIR_VARY_FAILURE 0x07 83 #define PSF_CUIR_SOFTWARE_FAILURE 0x08 84 #define PSF_CUIR_NOT_RECOGNIZED 0x09 85 86 /* 87 * CUIR codes 88 */ 89 #define CUIR_QUIESCE 0x01 90 #define CUIR_RESUME 0x02 91 92 /* 93 * Out-of-space (OOS) Codes 94 */ 95 #define REPO_WARN 0x01 96 #define REPO_EXHAUST 0x02 97 #define POOL_WARN 0x03 98 #define POOL_EXHAUST 0x04 99 #define REPO_RELIEVE 0x05 100 #define POOL_RELIEVE 0x06 101 102 /* 103 * attention message definitions 104 */ 105 #define ATTENTION_LENGTH_CUIR 0x0e 106 #define ATTENTION_FORMAT_CUIR 0x01 107 #define ATTENTION_LENGTH_OOS 0x10 108 #define ATTENTION_FORMAT_OOS 0x06 109 110 #define DASD_ECKD_PG_GROUPED 0x10 111 112 /* 113 * Size that is reportet for large volumes in the old 16-bit no_cyl field 114 */ 115 #define LV_COMPAT_CYL 0xFFFE 116 117 118 #define FCX_MAX_DATA_FACTOR 65536 119 #define DASD_ECKD_RCD_DATA_SIZE 256 120 121 #define DASD_ECKD_PATH_THRHLD 256 122 #define DASD_ECKD_PATH_INTERVAL 300 123 124 /* 125 * Maximum number of blocks to be chained 126 */ 127 #define DASD_ECKD_MAX_BLOCKS 190 128 #define DASD_ECKD_MAX_BLOCKS_RAW 256 129 130 /***************************************************************************** 131 * SECTION: Type Definitions 132 ****************************************************************************/ 133 134 struct eckd_count { 135 __u16 cyl; 136 __u16 head; 137 __u8 record; 138 __u8 kl; 139 __u16 dl; 140 } __attribute__ ((packed)); 141 142 struct ch_t { 143 __u16 cyl; 144 __u16 head; 145 } __attribute__ ((packed)); 146 147 struct chr_t { 148 __u16 cyl; 149 __u16 head; 150 __u8 record; 151 } __attribute__ ((packed)); 152 153 struct DE_eckd_data { 154 struct { 155 unsigned char perm:2; /* Permissions on this extent */ 156 unsigned char reserved:1; 157 unsigned char seek:2; /* Seek control */ 158 unsigned char auth:2; /* Access authorization */ 159 unsigned char pci:1; /* PCI Fetch mode */ 160 } __attribute__ ((packed)) mask; 161 struct { 162 unsigned char mode:2; /* Architecture mode */ 163 unsigned char ckd:1; /* CKD Conversion */ 164 unsigned char operation:3; /* Operation mode */ 165 unsigned char cfw:1; /* Cache fast write */ 166 unsigned char dfw:1; /* DASD fast write */ 167 } __attribute__ ((packed)) attributes; 168 __u16 blk_size; /* Blocksize */ 169 __u16 fast_write_id; 170 __u8 ga_additional; /* Global Attributes Additional */ 171 __u8 ga_extended; /* Global Attributes Extended */ 172 struct ch_t beg_ext; 173 struct ch_t end_ext; 174 unsigned long ep_sys_time; /* Ext Parameter - System Time Stamp */ 175 __u8 ep_format; /* Extended Parameter format byte */ 176 __u8 ep_prio; /* Extended Parameter priority I/O byte */ 177 __u8 ep_reserved1; /* Extended Parameter Reserved */ 178 __u8 ep_rec_per_track; /* Number of records on a track */ 179 __u8 ep_reserved[4]; /* Extended Parameter Reserved */ 180 } __attribute__ ((packed)); 181 182 struct LO_eckd_data { 183 struct { 184 unsigned char orientation:2; 185 unsigned char operation:6; 186 } __attribute__ ((packed)) operation; 187 struct { 188 unsigned char last_bytes_used:1; 189 unsigned char reserved:6; 190 unsigned char read_count_suffix:1; 191 } __attribute__ ((packed)) auxiliary; 192 __u8 unused; 193 __u8 count; 194 struct ch_t seek_addr; 195 struct chr_t search_arg; 196 __u8 sector; 197 __u16 length; 198 } __attribute__ ((packed)); 199 200 struct LRE_eckd_data { 201 struct { 202 unsigned char orientation:2; 203 unsigned char operation:6; 204 } __attribute__ ((packed)) operation; 205 struct { 206 unsigned char length_valid:1; 207 unsigned char length_scope:1; 208 unsigned char imbedded_ccw_valid:1; 209 unsigned char check_bytes:2; 210 unsigned char imbedded_count_valid:1; 211 unsigned char reserved:1; 212 unsigned char read_count_suffix:1; 213 } __attribute__ ((packed)) auxiliary; 214 __u8 imbedded_ccw; 215 __u8 count; 216 struct ch_t seek_addr; 217 struct chr_t search_arg; 218 __u8 sector; 219 __u16 length; 220 __u8 imbedded_count; 221 __u8 extended_operation; 222 __u16 extended_parameter_length; 223 __u8 extended_parameter[]; 224 } __attribute__ ((packed)); 225 226 /* Prefix data for format 0x00 and 0x01 */ 227 struct PFX_eckd_data { 228 unsigned char format; 229 struct { 230 unsigned char define_extent:1; 231 unsigned char time_stamp:1; 232 unsigned char verify_base:1; 233 unsigned char hyper_pav:1; 234 unsigned char reserved:4; 235 } __attribute__ ((packed)) validity; 236 __u8 base_address; 237 __u8 aux; 238 __u8 base_lss; 239 __u8 reserved[7]; 240 struct DE_eckd_data define_extent; 241 struct LRE_eckd_data locate_record; 242 } __attribute__ ((packed)); 243 244 struct dasd_eckd_characteristics { 245 __u16 cu_type; 246 struct { 247 unsigned char support:2; 248 unsigned char async:1; 249 unsigned char reserved:1; 250 unsigned char cache_info:1; 251 unsigned char model:3; 252 } __attribute__ ((packed)) cu_model; 253 __u16 dev_type; 254 __u8 dev_model; 255 struct { 256 unsigned char mult_burst:1; 257 unsigned char RT_in_LR:1; 258 unsigned char reserved1:1; 259 unsigned char RD_IN_LR:1; 260 unsigned char reserved2:4; 261 unsigned char reserved3:8; 262 unsigned char defect_wr:1; 263 unsigned char XRC_supported:1; 264 unsigned char reserved4:1; 265 unsigned char striping:1; 266 unsigned char reserved5:4; 267 unsigned char cfw:1; 268 unsigned char reserved6:2; 269 unsigned char cache:1; 270 unsigned char dual_copy:1; 271 unsigned char dfw:1; 272 unsigned char reset_alleg:1; 273 unsigned char sense_down:1; 274 } __attribute__ ((packed)) facilities; 275 __u8 dev_class; 276 __u8 unit_type; 277 __u16 no_cyl; 278 __u16 trk_per_cyl; 279 __u8 sec_per_trk; 280 __u8 byte_per_track[3]; 281 __u16 home_bytes; 282 __u8 formula; 283 union { 284 struct { 285 __u8 f1; 286 __u16 f2; 287 __u16 f3; 288 } __attribute__ ((packed)) f_0x01; 289 struct { 290 __u8 f1; 291 __u8 f2; 292 __u8 f3; 293 __u8 f4; 294 __u8 f5; 295 } __attribute__ ((packed)) f_0x02; 296 } __attribute__ ((packed)) factors; 297 __u16 first_alt_trk; 298 __u16 no_alt_trk; 299 __u16 first_dia_trk; 300 __u16 no_dia_trk; 301 __u16 first_sup_trk; 302 __u16 no_sup_trk; 303 __u8 MDR_ID; 304 __u8 OBR_ID; 305 __u8 director; 306 __u8 rd_trk_set; 307 __u16 max_rec_zero; 308 __u8 reserved1; 309 __u8 RWANY_in_LR; 310 __u8 factor6; 311 __u8 factor7; 312 __u8 factor8; 313 __u8 reserved2[3]; 314 __u8 reserved3[6]; 315 __u32 long_no_cyl; 316 } __attribute__ ((packed)); 317 318 /* elements of the configuration data */ 319 struct dasd_ned { 320 struct { 321 __u8 identifier:2; 322 __u8 token_id:1; 323 __u8 sno_valid:1; 324 __u8 subst_sno:1; 325 __u8 recNED:1; 326 __u8 emuNED:1; 327 __u8 reserved:1; 328 } __attribute__ ((packed)) flags; 329 __u8 descriptor; 330 __u8 dev_class; 331 __u8 reserved; 332 __u8 dev_type[6]; 333 __u8 dev_model[3]; 334 __u8 HDA_manufacturer[3]; 335 __u8 HDA_location[2]; 336 __u8 HDA_seqno[12]; 337 __u8 ID; 338 __u8 unit_addr; 339 } __attribute__ ((packed)); 340 341 struct dasd_sneq { 342 struct { 343 __u8 identifier:2; 344 __u8 reserved:6; 345 } __attribute__ ((packed)) flags; 346 __u8 res1; 347 __u16 format; 348 __u8 res2[4]; /* byte 4- 7 */ 349 __u8 sua_flags; /* byte 8 */ 350 __u8 base_unit_addr; /* byte 9 */ 351 __u8 res3[22]; /* byte 10-31 */ 352 } __attribute__ ((packed)); 353 354 struct vd_sneq { 355 struct { 356 __u8 identifier:2; 357 __u8 reserved:6; 358 } __attribute__ ((packed)) flags; 359 __u8 res1; 360 __u16 format; 361 __u8 res2[4]; /* byte 4- 7 */ 362 __u8 uit[16]; /* byte 8-23 */ 363 __u8 res3[8]; /* byte 24-31 */ 364 } __attribute__ ((packed)); 365 366 struct dasd_gneq { 367 struct { 368 __u8 identifier:2; 369 __u8 reserved:6; 370 } __attribute__ ((packed)) flags; 371 __u8 record_selector; 372 __u8 reserved[4]; 373 struct { 374 __u8 value:2; 375 __u8 number:6; 376 } __attribute__ ((packed)) timeout; 377 __u8 reserved3; 378 __u16 subsystemID; 379 __u8 reserved2[22]; 380 } __attribute__ ((packed)); 381 382 struct dasd_rssd_features { 383 char feature[256]; 384 } __attribute__((packed)); 385 386 struct dasd_rssd_messages { 387 __u16 length; 388 __u8 format; 389 __u8 code; 390 __u32 message_id; 391 __u8 flags; 392 char messages[4087]; 393 } __packed; 394 395 /* 396 * Read Subsystem Data - Volume Storage Query 397 */ 398 struct dasd_rssd_vsq { 399 struct { 400 __u8 tse:1; 401 __u8 space_not_available:1; 402 __u8 ese:1; 403 __u8 unused:5; 404 } __packed vol_info; 405 __u8 unused1; 406 __u16 extent_pool_id; 407 __u8 warn_cap_limit; 408 __u8 warn_cap_guaranteed; 409 __u16 unused2; 410 __u32 limit_capacity; 411 __u32 guaranteed_capacity; 412 __u32 space_allocated; 413 __u32 space_configured; 414 __u32 logical_capacity; 415 } __packed; 416 417 /* 418 * Extent Pool Summary 419 */ 420 struct dasd_ext_pool_sum { 421 __u16 pool_id; 422 __u8 repo_warn_thrshld; 423 __u8 warn_thrshld; 424 struct { 425 __u8 type:1; /* 0 - CKD / 1 - FB */ 426 __u8 track_space_efficient:1; 427 __u8 extent_space_efficient:1; 428 __u8 standard_volume:1; 429 __u8 extent_size_valid:1; 430 __u8 capacity_at_warnlevel:1; 431 __u8 pool_oos:1; 432 __u8 unused0:1; 433 __u8 unused1; 434 } __packed flags; 435 struct { 436 __u8 reserved0:1; 437 __u8 size_1G:1; 438 __u8 reserved1:5; 439 __u8 size_16M:1; 440 } __packed extent_size; 441 __u8 unused; 442 } __packed; 443 444 /* 445 * Read Subsystem Data-Response - Logical Configuration Query - Header 446 */ 447 struct dasd_rssd_lcq { 448 __u16 data_length; /* Length of data returned */ 449 __u16 pool_count; /* Count of extent pools returned - Max: 448 */ 450 struct { 451 __u8 pool_info_valid:1; /* Detailed Information valid */ 452 __u8 pool_id_volume:1; 453 __u8 pool_id_cec:1; 454 __u8 unused0:5; 455 __u8 unused1; 456 } __packed header_flags; 457 char sfi_type[6]; /* Storage Facility Image Type (EBCDIC) */ 458 char sfi_model[3]; /* Storage Facility Image Model (EBCDIC) */ 459 __u8 sfi_seq_num[10]; /* Storage Facility Image Sequence Number */ 460 __u8 reserved[7]; 461 struct dasd_ext_pool_sum ext_pool_sum[448]; 462 } __packed; 463 464 struct dasd_oos_message { 465 __u16 length; 466 __u8 format; 467 __u8 code; 468 __u8 percentage_empty; 469 __u8 reserved; 470 __u16 ext_pool_id; 471 __u16 token; 472 __u8 unused[6]; 473 } __packed; 474 475 struct dasd_cuir_message { 476 __u16 length; 477 __u8 format; 478 __u8 code; 479 __u32 message_id; 480 __u8 flags; 481 __u8 neq_map[3]; 482 __u8 ned_map; 483 __u8 record_selector; 484 } __packed; 485 486 struct dasd_psf_cuir_response { 487 __u8 order; 488 __u8 flags; 489 __u8 cc; 490 __u8 chpid; 491 __u16 device_nr; 492 __u16 reserved; 493 __u32 message_id; 494 __u64 system_id; 495 __u8 cssid; 496 __u8 ssid; 497 } __packed; 498 499 struct dasd_ckd_path_group_entry { 500 __u8 status_flags; 501 __u8 pgid[11]; 502 __u8 sysplex_name[8]; 503 __u32 timestamp; 504 __u32 cylinder; 505 __u8 reserved[4]; 506 } __packed; 507 508 struct dasd_ckd_host_information { 509 __u8 access_flags; 510 __u8 entry_size; 511 __u16 entry_count; 512 __u8 entry[16390]; 513 } __packed; 514 515 struct dasd_psf_query_host_access { 516 __u8 access_flag; 517 __u8 version; 518 __u16 CKD_length; 519 __u16 SCSI_length; 520 __u8 unused[10]; 521 __u8 host_access_information[16394]; 522 } __packed; 523 524 /* 525 * Perform Subsystem Function - Prepare for Read Subsystem Data 526 */ 527 struct dasd_psf_prssd_data { 528 unsigned char order; 529 unsigned char flags; 530 unsigned char reserved1; 531 unsigned char reserved2; 532 unsigned char lss; 533 unsigned char volume; 534 unsigned char suborder; 535 unsigned char varies[5]; 536 } __attribute__ ((packed)); 537 538 /* 539 * Perform Subsystem Function - Set Subsystem Characteristics 540 */ 541 struct dasd_psf_ssc_data { 542 unsigned char order; 543 unsigned char flags; 544 unsigned char cu_type[4]; 545 unsigned char suborder; 546 unsigned char reserved[59]; 547 } __attribute__((packed)); 548 549 /* Maximum number of extents for a single Release Allocated Space command */ 550 #define DASD_ECKD_RAS_EXTS_MAX 110U 551 552 struct dasd_dso_ras_ext_range { 553 struct ch_t beg_ext; 554 struct ch_t end_ext; 555 } __packed; 556 557 /* 558 * Define Subsytem Operation - Release Allocated Space 559 */ 560 struct dasd_dso_ras_data { 561 __u8 order; 562 struct { 563 __u8 message:1; /* Must be zero */ 564 __u8 reserved1:2; 565 __u8 vol_type:1; /* 0 - CKD/FBA, 1 - FB */ 566 __u8 reserved2:4; 567 } __packed flags; 568 /* Operation Flags to specify scope */ 569 struct { 570 __u8 reserved1:2; 571 /* Release Space by Extent */ 572 __u8 by_extent:1; /* 0 - entire volume, 1 - specified extents */ 573 __u8 guarantee_init:1; 574 __u8 force_release:1; /* Internal - will be ignored */ 575 __u16 reserved2:11; 576 } __packed op_flags; 577 __u8 lss; 578 __u8 dev_addr; 579 __u32 reserved1; 580 __u8 reserved2[10]; 581 __u16 nr_exts; /* Defines number of ext_scope - max 110 */ 582 __u16 reserved3; 583 } __packed; 584 585 586 /* 587 * some structures and definitions for alias handling 588 */ 589 struct dasd_unit_address_configuration { 590 struct { 591 char ua_type; 592 char base_ua; 593 } unit[256]; 594 } __attribute__((packed)); 595 596 597 #define MAX_DEVICES_PER_LCU 256 598 599 /* flags on the LCU */ 600 #define NEED_UAC_UPDATE 0x01 601 #define UPDATE_PENDING 0x02 602 603 enum pavtype {NO_PAV, BASE_PAV, HYPER_PAV}; 604 605 606 struct alias_root { 607 struct list_head serverlist; 608 spinlock_t lock; 609 }; 610 611 struct alias_server { 612 struct list_head server; 613 struct dasd_uid uid; 614 struct list_head lculist; 615 }; 616 617 struct summary_unit_check_work_data { 618 char reason; 619 struct dasd_device *device; 620 struct work_struct worker; 621 }; 622 623 struct read_uac_work_data { 624 struct dasd_device *device; 625 struct delayed_work dwork; 626 }; 627 628 struct alias_lcu { 629 struct list_head lcu; 630 struct dasd_uid uid; 631 enum pavtype pav; 632 char flags; 633 spinlock_t lock; 634 struct list_head grouplist; 635 struct list_head active_devices; 636 struct list_head inactive_devices; 637 struct dasd_unit_address_configuration *uac; 638 struct summary_unit_check_work_data suc_data; 639 struct read_uac_work_data ruac_data; 640 struct dasd_ccw_req *rsu_cqr; 641 struct completion lcu_setup; 642 }; 643 644 struct alias_pav_group { 645 struct list_head group; 646 struct dasd_uid uid; 647 struct alias_lcu *lcu; 648 struct list_head baselist; 649 struct list_head aliaslist; 650 struct dasd_device *next; 651 }; 652 653 struct dasd_conf_data { 654 struct dasd_ned neds[5]; 655 u8 reserved[64]; 656 struct dasd_gneq gneq; 657 } __packed; 658 659 struct dasd_eckd_private { 660 struct dasd_eckd_characteristics rdc_data; 661 u8 *conf_data; 662 int conf_len; 663 664 /* pointers to specific parts in the conf_data */ 665 struct dasd_ned *ned; 666 struct dasd_sneq *sneq; 667 struct vd_sneq *vdsneq; 668 struct dasd_gneq *gneq; 669 670 struct eckd_count count_area[5]; 671 int init_cqr_status; 672 int uses_cdl; 673 struct attrib_data_t attrib; /* e.g. cache operations */ 674 struct dasd_rssd_features features; 675 struct dasd_rssd_vsq vsq; 676 struct dasd_ext_pool_sum eps; 677 u32 real_cyl; 678 679 /* alias managemnet */ 680 struct dasd_uid uid; 681 struct alias_pav_group *pavgroup; 682 struct alias_lcu *lcu; 683 int count; 684 685 u32 fcx_max_data; 686 char suc_reason; 687 }; 688 689 690 691 int dasd_alias_make_device_known_to_lcu(struct dasd_device *); 692 void dasd_alias_disconnect_device_from_lcu(struct dasd_device *); 693 int dasd_alias_add_device(struct dasd_device *); 694 int dasd_alias_remove_device(struct dasd_device *); 695 struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *); 696 void dasd_alias_handle_summary_unit_check(struct work_struct *); 697 void dasd_eckd_reset_ccw_to_base_io(struct dasd_ccw_req *); 698 int dasd_alias_update_add_device(struct dasd_device *); 699 #endif /* DASD_ECKD_H */ 700