1/* 2 * osd_protocol.h - OSD T10 standard C definitions. 3 * 4 * Copyright (C) 2008 Panasas Inc. All rights reserved. 5 * 6 * Authors: 7 * Boaz Harrosh <ooo@electrozaur.com> 8 * Benny Halevy <bhalevy@panasas.com> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 12 * 13 * This file contains types and constants that are defined by the protocol 14 * Note: All names and symbols are taken from the OSD standard's text. 15 */ 16#ifndef __OSD_PROTOCOL_H__ 17#define __OSD_PROTOCOL_H__ 18 19#include <linux/types.h> 20#include <linux/kernel.h> 21#include <asm/unaligned.h> 22#include <scsi/scsi.h> 23 24enum { 25 OSDv1_ADDITIONAL_CDB_LENGTH = 192, 26 OSDv1_TOTAL_CDB_LEN = OSDv1_ADDITIONAL_CDB_LENGTH + 8, 27 OSDv1_CAP_LEN = 80, 28 29 /* Latest supported version */ 30 OSDv2_ADDITIONAL_CDB_LENGTH = 228, 31 OSD_ADDITIONAL_CDB_LENGTH = 32 OSDv2_ADDITIONAL_CDB_LENGTH, 33 OSD_TOTAL_CDB_LEN = OSD_ADDITIONAL_CDB_LENGTH + 8, 34 OSD_CAP_LEN = 104, 35 36 OSD_SYSTEMID_LEN = 20, 37 OSDv1_CRYPTO_KEYID_SIZE = 20, 38 OSDv2_CRYPTO_KEYID_SIZE = 32, 39 OSD_CRYPTO_KEYID_SIZE = OSDv2_CRYPTO_KEYID_SIZE, 40 OSD_CRYPTO_SEED_SIZE = 4, 41 OSD_CRYPTO_NONCE_SIZE = 12, 42 OSD_MAX_SENSE_LEN = 252, /* from SPC-3 */ 43 44 OSD_PARTITION_FIRST_ID = 0x10000, 45 OSD_OBJECT_FIRST_ID = 0x10000, 46}; 47 48/* (osd-r10 5.2.4) 49 * osd2r03: 5.2.3 Caching control bits 50 */ 51enum osd_options_byte { 52 OSD_CDB_FUA = 0x08, /* Force Unit Access */ 53 OSD_CDB_DPO = 0x10, /* Disable Page Out */ 54}; 55 56/* 57 * osd2r03: 5.2.5 Isolation. 58 * First 3 bits, V2-only. 59 * Also for attr 110h "default isolation method" at Root Information page 60 */ 61enum osd_options_byte_isolation { 62 OSD_ISOLATION_DEFAULT = 0, 63 OSD_ISOLATION_NONE = 1, 64 OSD_ISOLATION_STRICT = 2, 65 OSD_ISOLATION_RANGE = 4, 66 OSD_ISOLATION_FUNCTIONAL = 5, 67 OSD_ISOLATION_VENDOR = 7, 68}; 69 70/* (osd-r10: 6.7) 71 * osd2r03: 6.8 FLUSH, FLUSH COLLECTION, FLUSH OSD, FLUSH PARTITION 72 */ 73enum osd_options_flush_scope_values { 74 OSD_CDB_FLUSH_ALL = 0, 75 OSD_CDB_FLUSH_ATTR_ONLY = 1, 76 77 OSD_CDB_FLUSH_ALL_RECURSIVE = 2, 78 /* V2-only */ 79 OSD_CDB_FLUSH_ALL_RANGE = 2, 80}; 81 82/* osd2r03: 5.2.10 Timestamps control */ 83enum { 84 OSD_CDB_NORMAL_TIMESTAMPS = 0, 85 OSD_CDB_BYPASS_TIMESTAMPS = 0x7f, 86}; 87 88/* (osd-r10: 5.2.2.1) 89 * osd2r03: 5.2.4.1 Get and set attributes CDB format selection 90 * 2 bits at second nibble of command_specific_options byte 91 */ 92enum osd_attributes_mode { 93 /* V2-only */ 94 OSD_CDB_SET_ONE_ATTR = 0x10, 95 96 OSD_CDB_GET_ATTR_PAGE_SET_ONE = 0x20, 97 OSD_CDB_GET_SET_ATTR_LISTS = 0x30, 98 99 OSD_CDB_GET_SET_ATTR_MASK = 0x30, 100}; 101 102/* (osd-r10: 4.12.5) 103 * osd2r03: 4.14.5 Data-In and Data-Out buffer offsets 104 * byte offset = mantissa * (2^(exponent+8)) 105 * struct { 106 * unsigned mantissa: 28; 107 * int exponent: 04; 108 * } 109 */ 110typedef __be32 osd_cdb_offset; 111 112enum { 113 OSD_OFFSET_UNUSED = 0xFFFFFFFF, 114 OSD_OFFSET_MAX_BITS = 28, 115 116 OSDv1_OFFSET_MIN_SHIFT = 8, 117 OSD_OFFSET_MIN_SHIFT = 3, 118 OSD_OFFSET_MAX_SHIFT = 16, 119}; 120 121/* Return the smallest allowed encoded offset that contains @offset. 122 * 123 * The actual encoded offset returned is @offset + *padding. 124 * (up to max_shift, non-inclusive) 125 */ 126osd_cdb_offset __osd_encode_offset(u64 offset, unsigned *padding, 127 int min_shift, int max_shift); 128 129/* Minimum alignment is 256 bytes 130 * Note: Seems from std v1 that exponent can be from 0+8 to 0xE+8 (inclusive) 131 * which is 8 to 23 but IBM code restricts it to 16, so be it. 132 */ 133static inline osd_cdb_offset osd_encode_offset_v1(u64 offset, unsigned *padding) 134{ 135 return __osd_encode_offset(offset, padding, 136 OSDv1_OFFSET_MIN_SHIFT, OSD_OFFSET_MAX_SHIFT); 137} 138 139/* Minimum 8 bytes alignment 140 * Same as v1 but since exponent can be signed than a less than 141 * 256 alignment can be reached with small offsets (<2GB) 142 */ 143static inline osd_cdb_offset osd_encode_offset_v2(u64 offset, unsigned *padding) 144{ 145 return __osd_encode_offset(offset, padding, 146 OSD_OFFSET_MIN_SHIFT, OSD_OFFSET_MAX_SHIFT); 147} 148 149/* osd2r03: 5.2.1 Overview */ 150struct osd_cdb_head { 151 struct scsi_varlen_cdb_hdr varlen_cdb; 152/*10*/ u8 options; 153 u8 command_specific_options; 154 u8 timestamp_control; 155/*13*/ u8 reserved1[3]; 156/*16*/ __be64 partition; 157/*24*/ __be64 object; 158/*32*/ union { /* V1 vs V2 alignment differences */ 159 struct __osdv1_cdb_addr_len { 160/*32*/ __be32 list_identifier;/* Rarely used */ 161/*36*/ __be64 length; 162/*44*/ __be64 start_address; 163 } __packed v1; 164 165 struct __osdv2_cdb_addr_len { 166 /* called allocation_length in some commands */ 167/*32*/ __be64 length; 168/*40*/ __be64 start_address; 169 union { 170/*48*/ __be32 list_identifier;/* Rarely used */ 171 /* OSD2r05 5.2.5 CDB continuation length */ 172/*48*/ __be32 cdb_continuation_length; 173 }; 174 } __packed v2; 175 }; 176/*52*/ union { /* selected attributes mode Page/List/Single */ 177 struct osd_attributes_page_mode { 178/*52*/ __be32 get_attr_page; 179/*56*/ __be32 get_attr_alloc_length; 180/*60*/ osd_cdb_offset get_attr_offset; 181 182/*64*/ __be32 set_attr_page; 183/*68*/ __be32 set_attr_id; 184/*72*/ __be32 set_attr_length; 185/*76*/ osd_cdb_offset set_attr_offset; 186/*80*/ } __packed attrs_page; 187 188 struct osd_attributes_list_mode { 189/*52*/ __be32 get_attr_desc_bytes; 190/*56*/ osd_cdb_offset get_attr_desc_offset; 191 192/*60*/ __be32 get_attr_alloc_length; 193/*64*/ osd_cdb_offset get_attr_offset; 194 195/*68*/ __be32 set_attr_bytes; 196/*72*/ osd_cdb_offset set_attr_offset; 197 __be32 not_used; 198/*80*/ } __packed attrs_list; 199 200 /* osd2r03:5.2.4.2 Set one attribute value using CDB fields */ 201 struct osd_attributes_cdb_mode { 202/*52*/ __be32 set_attr_page; 203/*56*/ __be32 set_attr_id; 204/*60*/ __be16 set_attr_len; 205/*62*/ u8 set_attr_val[18]; 206/*80*/ } __packed attrs_cdb; 207/*52*/ u8 get_set_attributes_parameters[28]; 208 }; 209} __packed; 210/*80*/ 211 212/*160 v1*/ 213struct osdv1_security_parameters { 214/*160*/u8 integrity_check_value[OSDv1_CRYPTO_KEYID_SIZE]; 215/*180*/u8 request_nonce[OSD_CRYPTO_NONCE_SIZE]; 216/*192*/osd_cdb_offset data_in_integrity_check_offset; 217/*196*/osd_cdb_offset data_out_integrity_check_offset; 218} __packed; 219/*200 v1*/ 220 221/*184 v2*/ 222struct osdv2_security_parameters { 223/*184*/u8 integrity_check_value[OSDv2_CRYPTO_KEYID_SIZE]; 224/*216*/u8 request_nonce[OSD_CRYPTO_NONCE_SIZE]; 225/*228*/osd_cdb_offset data_in_integrity_check_offset; 226/*232*/osd_cdb_offset data_out_integrity_check_offset; 227} __packed; 228/*236 v2*/ 229 230struct osd_security_parameters { 231 union { 232 struct osdv1_security_parameters v1; 233 struct osdv2_security_parameters v2; 234 }; 235}; 236 237struct osdv1_cdb { 238 struct osd_cdb_head h; 239 u8 caps[OSDv1_CAP_LEN]; 240 struct osdv1_security_parameters sec_params; 241} __packed; 242 243struct osdv2_cdb { 244 struct osd_cdb_head h; 245 u8 caps[OSD_CAP_LEN]; 246 struct osdv2_security_parameters sec_params; 247} __packed; 248 249struct osd_cdb { 250 union { 251 struct osdv1_cdb v1; 252 struct osdv2_cdb v2; 253 u8 buff[OSD_TOTAL_CDB_LEN]; 254 }; 255} __packed; 256 257static inline struct osd_cdb_head *osd_cdb_head(struct osd_cdb *ocdb) 258{ 259 return (struct osd_cdb_head *)ocdb->buff; 260} 261 262/* define both version actions 263 * Ex name = FORMAT_OSD we have OSD_ACT_FORMAT_OSD && OSDv1_ACT_FORMAT_OSD 264 */ 265#define OSD_ACT___(Name, Num) \ 266 OSD_ACT_##Name = cpu_to_be16(0x8880 + Num), \ 267 OSDv1_ACT_##Name = cpu_to_be16(0x8800 + Num), 268 269/* V2 only actions */ 270#define OSD_ACT_V2(Name, Num) \ 271 OSD_ACT_##Name = cpu_to_be16(0x8880 + Num), 272 273#define OSD_ACT_V1_V2(Name, Num1, Num2) \ 274 OSD_ACT_##Name = cpu_to_be16(Num2), \ 275 OSDv1_ACT_##Name = cpu_to_be16(Num1), 276 277enum osd_service_actions { 278 OSD_ACT_V2(OBJECT_STRUCTURE_CHECK, 0x00) 279 OSD_ACT___(FORMAT_OSD, 0x01) 280 OSD_ACT___(CREATE, 0x02) 281 OSD_ACT___(LIST, 0x03) 282 OSD_ACT_V2(PUNCH, 0x04) 283 OSD_ACT___(READ, 0x05) 284 OSD_ACT___(WRITE, 0x06) 285 OSD_ACT___(APPEND, 0x07) 286 OSD_ACT___(FLUSH, 0x08) 287 OSD_ACT_V2(CLEAR, 0x09) 288 OSD_ACT___(REMOVE, 0x0A) 289 OSD_ACT___(CREATE_PARTITION, 0x0B) 290 OSD_ACT___(REMOVE_PARTITION, 0x0C) 291 OSD_ACT___(GET_ATTRIBUTES, 0x0E) 292 OSD_ACT___(SET_ATTRIBUTES, 0x0F) 293 OSD_ACT___(CREATE_AND_WRITE, 0x12) 294 OSD_ACT___(CREATE_COLLECTION, 0x15) 295 OSD_ACT___(REMOVE_COLLECTION, 0x16) 296 OSD_ACT___(LIST_COLLECTION, 0x17) 297 OSD_ACT___(SET_KEY, 0x18) 298 OSD_ACT___(SET_MASTER_KEY, 0x19) 299 OSD_ACT___(FLUSH_COLLECTION, 0x1A) 300 OSD_ACT___(FLUSH_PARTITION, 0x1B) 301 OSD_ACT___(FLUSH_OSD, 0x1C) 302 303 OSD_ACT_V2(QUERY, 0x20) 304 OSD_ACT_V2(REMOVE_MEMBER_OBJECTS, 0x21) 305 OSD_ACT_V2(GET_MEMBER_ATTRIBUTES, 0x22) 306 OSD_ACT_V2(SET_MEMBER_ATTRIBUTES, 0x23) 307 308 OSD_ACT_V2(CREATE_CLONE, 0x28) 309 OSD_ACT_V2(CREATE_SNAPSHOT, 0x29) 310 OSD_ACT_V2(DETACH_CLONE, 0x2A) 311 OSD_ACT_V2(REFRESH_SNAPSHOT_CLONE, 0x2B) 312 OSD_ACT_V2(RESTORE_PARTITION_FROM_SNAPSHOT, 0x2C) 313 314 OSD_ACT_V2(READ_MAP, 0x31) 315 OSD_ACT_V2(READ_MAPS_COMPARE, 0x32) 316 317 OSD_ACT_V1_V2(PERFORM_SCSI_COMMAND, 0x8F7E, 0x8F7C) 318 OSD_ACT_V1_V2(SCSI_TASK_MANAGEMENT, 0x8F7F, 0x8F7D) 319 /* 0x8F80 to 0x8FFF are Vendor specific */ 320}; 321 322/* osd2r03: 7.1.3.2 List entry format for retrieving attributes */ 323struct osd_attributes_list_attrid { 324 __be32 attr_page; 325 __be32 attr_id; 326} __packed; 327 328/* 329 * NOTE: v1: is not aligned. 330 */ 331struct osdv1_attributes_list_element { 332 __be32 attr_page; 333 __be32 attr_id; 334 __be16 attr_bytes; /* valid bytes at attr_val without padding */ 335 u8 attr_val[0]; 336} __packed; 337 338/* 339 * osd2r03: 7.1.3.3 List entry format for retrieved attributes and 340 * for setting attributes 341 * NOTE: v2 is 8-bytes aligned 342 */ 343struct osdv2_attributes_list_element { 344 __be32 attr_page; 345 __be32 attr_id; 346 u8 reserved[6]; 347 __be16 attr_bytes; /* valid bytes at attr_val without padding */ 348 u8 attr_val[0]; 349} __packed; 350 351enum { 352 OSDv1_ATTRIBUTES_ELEM_ALIGN = 1, 353 OSD_ATTRIBUTES_ELEM_ALIGN = 8, 354}; 355 356enum { 357 OSD_ATTR_LIST_ALL_PAGES = 0xFFFFFFFF, 358 OSD_ATTR_LIST_ALL_IN_PAGE = 0xFFFFFFFF, 359}; 360 361static inline unsigned osdv1_attr_list_elem_size(unsigned len) 362{ 363 return ALIGN(len + sizeof(struct osdv1_attributes_list_element), 364 OSDv1_ATTRIBUTES_ELEM_ALIGN); 365} 366 367static inline unsigned osdv2_attr_list_elem_size(unsigned len) 368{ 369 return ALIGN(len + sizeof(struct osdv2_attributes_list_element), 370 OSD_ATTRIBUTES_ELEM_ALIGN); 371} 372 373/* 374 * osd2r03: 7.1.3 OSD attributes lists (Table 184) — List type values 375 */ 376enum osd_attr_list_types { 377 OSD_ATTR_LIST_GET = 0x1, /* descriptors only */ 378 OSD_ATTR_LIST_SET_RETRIEVE = 0x9, /*descriptors/values variable-length*/ 379 OSD_V2_ATTR_LIST_MULTIPLE = 0xE, /* ver2, Multiple Objects lists*/ 380 OSD_V1_ATTR_LIST_CREATE_MULTIPLE = 0xF,/*ver1, used by create_multple*/ 381}; 382 383/* osd2r03: 7.1.3.4 Multi-object retrieved attributes format */ 384struct osd_attributes_list_multi_header { 385 __be64 object_id; 386 u8 object_type; /* object_type enum below */ 387 u8 reserved[5]; 388 __be16 list_bytes; 389 /* followed by struct osd_attributes_list_element's */ 390}; 391 392struct osdv1_attributes_list_header { 393 u8 type; /* low 4-bit only */ 394 u8 pad; 395 __be16 list_bytes; /* Initiator shall set to Zero. Only set by target */ 396 /* 397 * type=9 followed by struct osd_attributes_list_element's 398 * type=E followed by struct osd_attributes_list_multi_header's 399 */ 400} __packed; 401 402static inline unsigned osdv1_list_size(struct osdv1_attributes_list_header *h) 403{ 404 return be16_to_cpu(h->list_bytes); 405} 406 407struct osdv2_attributes_list_header { 408 u8 type; /* lower 4-bits only */ 409 u8 pad[3]; 410/*4*/ __be32 list_bytes; /* Initiator shall set to zero. Only set by target */ 411 /* 412 * type=9 followed by struct osd_attributes_list_element's 413 * type=E followed by struct osd_attributes_list_multi_header's 414 */ 415} __packed; 416 417static inline unsigned osdv2_list_size(struct osdv2_attributes_list_header *h) 418{ 419 return be32_to_cpu(h->list_bytes); 420} 421 422/* (osd-r10 6.13) 423 * osd2r03: 6.15 LIST (Table 79) LIST command parameter data. 424 * for root_lstchg below 425 */ 426enum { 427 OSD_OBJ_ID_LIST_PAR = 0x1, /* V1-only. Not used in V2 */ 428 OSD_OBJ_ID_LIST_LSTCHG = 0x2, 429}; 430 431/* 432 * osd2r03: 6.15.2 LIST command parameter data 433 * (Also for LIST COLLECTION) 434 */ 435struct osd_obj_id_list { 436 __be64 list_bytes; /* bytes in list excluding list_bytes (-8) */ 437 __be64 continuation_id; 438 __be32 list_identifier; 439 u8 pad[3]; 440 u8 root_lstchg; 441 __be64 object_ids[0]; 442} __packed; 443 444static inline bool osd_is_obj_list_done(struct osd_obj_id_list *list, 445 bool *is_changed) 446{ 447 *is_changed = (0 != (list->root_lstchg & OSD_OBJ_ID_LIST_LSTCHG)); 448 return 0 != list->continuation_id; 449} 450 451/* 452 * osd2r03: 4.12.4.5 The ALLDATA security method 453 */ 454struct osd_data_out_integrity_info { 455 __be64 data_bytes; 456 __be64 set_attributes_bytes; 457 __be64 get_attributes_bytes; 458 __u8 integrity_check_value[OSD_CRYPTO_KEYID_SIZE]; 459} __packed; 460 461/* Same osd_data_out_integrity_info is used for OSD2/OSD1. The only difference 462 * Is the sizeof the structure since in OSD1 the last array is smaller. Use 463 * below for version independent handling of this structure 464 */ 465static inline int osd_data_out_integrity_info_sizeof(bool is_ver1) 466{ 467 return sizeof(struct osd_data_out_integrity_info) - 468 (is_ver1 * (OSDv2_CRYPTO_KEYID_SIZE - OSDv1_CRYPTO_KEYID_SIZE)); 469} 470 471struct osd_data_in_integrity_info { 472 __be64 data_bytes; 473 __be64 retrieved_attributes_bytes; 474 __u8 integrity_check_value[OSD_CRYPTO_KEYID_SIZE]; 475} __packed; 476 477/* Same osd_data_in_integrity_info is used for OSD2/OSD1. The only difference 478 * Is the sizeof the structure since in OSD1 the last array is smaller. Use 479 * below for version independent handling of this structure 480 */ 481static inline int osd_data_in_integrity_info_sizeof(bool is_ver1) 482{ 483 return sizeof(struct osd_data_in_integrity_info) - 484 (is_ver1 * (OSDv2_CRYPTO_KEYID_SIZE - OSDv1_CRYPTO_KEYID_SIZE)); 485} 486 487struct osd_timestamp { 488 u8 time[6]; /* number of milliseconds since 1/1/1970 UT (big endian) */ 489} __packed; 490/* FIXME: define helper functions to convert to/from osd time format */ 491 492/* 493 * Capability & Security definitions 494 * osd2r03: 4.11.2.2 Capability format 495 * osd2r03: 5.2.8 Security parameters 496 */ 497 498struct osd_key_identifier { 499 u8 id[7]; /* if you know why 7 please email ooo@electrozaur.com */ 500} __packed; 501 502/* for osd_capability.format */ 503enum { 504 OSD_SEC_CAP_FORMAT_NO_CAPS = 0, 505 OSD_SEC_CAP_FORMAT_VER1 = 1, 506 OSD_SEC_CAP_FORMAT_VER2 = 2, 507}; 508 509/* security_method */ 510enum { 511 OSD_SEC_NOSEC = 0, 512 OSD_SEC_CAPKEY = 1, 513 OSD_SEC_CMDRSP = 2, 514 OSD_SEC_ALLDATA = 3, 515}; 516 517enum object_type { 518 OSD_SEC_OBJ_ROOT = 0x1, 519 OSD_SEC_OBJ_PARTITION = 0x2, 520 OSD_SEC_OBJ_COLLECTION = 0x40, 521 OSD_SEC_OBJ_USER = 0x80, 522}; 523 524enum osd_capability_bit_masks { 525 OSD_SEC_CAP_APPEND = BIT(0), 526 OSD_SEC_CAP_OBJ_MGMT = BIT(1), 527 OSD_SEC_CAP_REMOVE = BIT(2), 528 OSD_SEC_CAP_CREATE = BIT(3), 529 OSD_SEC_CAP_SET_ATTR = BIT(4), 530 OSD_SEC_CAP_GET_ATTR = BIT(5), 531 OSD_SEC_CAP_WRITE = BIT(6), 532 OSD_SEC_CAP_READ = BIT(7), 533 534 OSD_SEC_CAP_NONE1 = BIT(8), 535 OSD_SEC_CAP_NONE2 = BIT(9), 536 OSD_SEC_GBL_REM = BIT(10), /*v2 only*/ 537 OSD_SEC_CAP_QUERY = BIT(11), /*v2 only*/ 538 OSD_SEC_CAP_M_OBJECT = BIT(12), /*v2 only*/ 539 OSD_SEC_CAP_POL_SEC = BIT(13), 540 OSD_SEC_CAP_GLOBAL = BIT(14), 541 OSD_SEC_CAP_DEV_MGMT = BIT(15), 542}; 543 544/* for object_descriptor_type (hi nibble used) */ 545enum { 546 OSD_SEC_OBJ_DESC_NONE = 0, /* Not allowed */ 547 OSD_SEC_OBJ_DESC_OBJ = 1 << 4, /* v1: also collection */ 548 OSD_SEC_OBJ_DESC_PAR = 2 << 4, /* also root */ 549 OSD_SEC_OBJ_DESC_COL = 3 << 4, /* v2 only */ 550}; 551 552/* (osd-r10:4.9.2.2) 553 * osd2r03:4.11.2.2 Capability format 554 */ 555struct osd_capability_head { 556 u8 format; /* low nibble */ 557 u8 integrity_algorithm__key_version; /* MAKE_BYTE(integ_alg, key_ver) */ 558 u8 security_method; 559 u8 reserved1; 560/*04*/ struct osd_timestamp expiration_time; 561/*10*/ u8 audit[20]; 562/*30*/ u8 discriminator[12]; 563/*42*/ struct osd_timestamp object_created_time; 564/*48*/ u8 object_type; 565/*49*/ u8 permissions_bit_mask[5]; 566/*54*/ u8 reserved2; 567/*55*/ u8 object_descriptor_type; /* high nibble */ 568} __packed; 569 570/*56 v1*/ 571struct osdv1_cap_object_descriptor { 572 union { 573 struct { 574/*56*/ __be32 policy_access_tag; 575/*60*/ __be64 allowed_partition_id; 576/*68*/ __be64 allowed_object_id; 577/*76*/ __be32 reserved; 578 } __packed obj_desc; 579 580/*56*/ u8 object_descriptor[24]; 581 }; 582} __packed; 583/*80 v1*/ 584 585/*56 v2*/ 586struct osd_cap_object_descriptor { 587 union { 588 struct { 589/*56*/ __be32 allowed_attributes_access; 590/*60*/ __be32 policy_access_tag; 591/*64*/ __be16 boot_epoch; 592/*66*/ u8 reserved[6]; 593/*72*/ __be64 allowed_partition_id; 594/*80*/ __be64 allowed_object_id; 595/*88*/ __be64 allowed_range_length; 596/*96*/ __be64 allowed_range_start; 597 } __packed obj_desc; 598 599/*56*/ u8 object_descriptor[48]; 600 }; 601} __packed; 602/*104 v2*/ 603 604struct osdv1_capability { 605 struct osd_capability_head h; 606 struct osdv1_cap_object_descriptor od; 607} __packed; 608 609struct osd_capability { 610 struct osd_capability_head h; 611 struct osd_cap_object_descriptor od; 612} __packed; 613 614/** 615 * osd_sec_set_caps - set cap-bits into the capabilities header 616 * 617 * @cap: The osd_capability_head to set cap bits to. 618 * @bit_mask: Use an ORed list of enum osd_capability_bit_masks values 619 * 620 * permissions_bit_mask is unaligned use below to set into caps 621 * in a version independent way 622 */ 623static inline void osd_sec_set_caps(struct osd_capability_head *cap, 624 u16 bit_mask) 625{ 626 /* 627 *Note: The bits above are defined LE order this is because this way 628 * they can grow in the future to more then 16, and still retain 629 * there constant values. 630 */ 631 put_unaligned_le16(bit_mask, &cap->permissions_bit_mask); 632} 633 634/* osd2r05a sec 5.3: CDB continuation segment formats */ 635enum osd_continuation_segment_format { 636 CDB_CONTINUATION_FORMAT_V2 = 0x01, 637}; 638 639struct osd_continuation_segment_header { 640 u8 format; 641 u8 reserved1; 642 __be16 service_action; 643 __be32 reserved2; 644 u8 integrity_check[OSDv2_CRYPTO_KEYID_SIZE]; 645} __packed; 646 647/* osd2r05a sec 5.4.1: CDB continuation descriptors */ 648enum osd_continuation_descriptor_type { 649 NO_MORE_DESCRIPTORS = 0x0000, 650 SCATTER_GATHER_LIST = 0x0001, 651 QUERY_LIST = 0x0002, 652 USER_OBJECT = 0x0003, 653 COPY_USER_OBJECT_SOURCE = 0x0101, 654 EXTENSION_CAPABILITIES = 0xFFEE 655}; 656 657struct osd_continuation_descriptor_header { 658 __be16 type; 659 u8 reserved; 660 u8 pad_length; 661 __be32 length; 662} __packed; 663 664 665/* osd2r05a sec 5.4.2: Scatter/gather list */ 666struct osd_sg_list_entry { 667 __be64 offset; 668 __be64 len; 669}; 670 671struct osd_sg_continuation_descriptor { 672 struct osd_continuation_descriptor_header hdr; 673 struct osd_sg_list_entry entries[]; 674}; 675 676#endif /* ndef __OSD_PROTOCOL_H__ */ 677