Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
osd_protocol.h
Go to the documentation of this file.
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 <[email protected]>
8  * Benny Halevy <[email protected]>
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 
24 enum {
28 
29  /* Latest supported version */
34  OSD_CAP_LEN = 104,
35 
42  OSD_MAX_SENSE_LEN = 252, /* from SPC-3 */
43 
46 };
47 
48 /* (osd-r10 5.2.4)
49  * osd2r03: 5.2.3 Caching control bits
50  */
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  */
68 };
69 
70 /* (osd-r10: 6.7)
71  * osd2r03: 6.8 FLUSH, FLUSH COLLECTION, FLUSH OSD, FLUSH PARTITION
72  */
76 
78  /* V2-only */
80 };
81 
82 /* osd2r03: 5.2.10 Timestamps control */
83 enum {
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  */
93  /* V2-only */
95 
98 
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  */
111 
112 enum {
113  OSD_OFFSET_UNUSED = 0xFFFFFFFF,
115 
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  */
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  */
133 static inline osd_cdb_offset osd_encode_offset_v1(u64 offset, unsigned *padding)
134 {
135  return __osd_encode_offset(offset, padding,
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  */
143 static inline osd_cdb_offset osd_encode_offset_v2(u64 offset, unsigned *padding)
144 {
145  return __osd_encode_offset(offset, padding,
147 }
148 
149 /* osd2r03: 5.2.1 Overview */
150 struct osd_cdb_head {
152 /*10*/ u8 options;
155 /*13*/ u8 reserved1[3];
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;
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 */
173  };
174  } __packed v2;
175  };
176 /*52*/ union { /* selected attributes mode Page/List/Single */
177  struct osd_attributes_page_mode {
181 
186 /*80*/ } __packed attrs_page;
187 
188  struct osd_attributes_list_mode {
191 
194 
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;
205 /*62*/ u8 set_attr_val[18];
206 /*80*/ } __packed attrs_cdb;
208  };
209 } __packed;
210 /*80*/
211 
212 /*160 v1*/
218 } __packed;
219 /*200 v1*/
220 
221 /*184 v2*/
227 } __packed;
228 /*236 v2*/
229 
231  union {
234  };
235 };
236 
237 struct osdv1_cdb {
238  struct osd_cdb_head h;
241 } __packed;
242 
243 struct osdv2_cdb {
244  struct osd_cdb_head h;
247 } __packed;
248 
249 struct osd_cdb {
250  union {
251  struct osdv1_cdb v1;
252  struct osdv2_cdb v2;
254  };
255 } __packed;
256 
257 static 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 = __constant_cpu_to_be16(0x8880 + Num), \
267  OSDv1_ACT_##Name = __constant_cpu_to_be16(0x8800 + Num),
268 
269 /* V2 only actions */
270 #define OSD_ACT_V2(Name, Num) \
271  OSD_ACT_##Name = __constant_cpu_to_be16(0x8880 + Num),
272 
273 #define OSD_ACT_V1_V2(Name, Num1, Num2) \
274  OSD_ACT_##Name = __constant_cpu_to_be16(Num2), \
275  OSDv1_ACT_##Name = __constant_cpu_to_be16(Num1),
276 
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 */
326 } __packed;
327 
328 /*
329  * NOTE: v1: is not aligned.
330  */
334  __be16 attr_bytes; /* valid bytes at attr_val without padding */
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  */
347  __be16 attr_bytes; /* valid bytes at attr_val without padding */
349 } __packed;
350 
351 enum {
354 };
355 
356 enum {
359 };
360 
361 static inline unsigned osdv1_attr_list_elem_size(unsigned len)
362 {
363  return ALIGN(len + sizeof(struct osdv1_attributes_list_element),
365 }
366 
367 static inline unsigned osdv2_attr_list_elem_size(unsigned len)
368 {
369  return ALIGN(len + sizeof(struct osdv2_attributes_list_element),
371 }
372 
373 /*
374  * osd2r03: 7.1.3 OSD attributes lists (Table 184) — List type values
375  */
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 */
386  u8 object_type; /* object_type enum below */
389  /* followed by struct osd_attributes_list_element's */
390 };
391 
393  u8 type; /* low 4-bit only */
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 
402 static inline unsigned osdv1_list_size(struct osdv1_attributes_list_header *h)
403 {
404  return be16_to_cpu(h->list_bytes);
405 }
406 
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 
417 static 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  */
426 enum {
427  OSD_OBJ_ID_LIST_PAR = 0x1, /* V1-only. Not used in V2 */
429 };
430 
431 /*
432  * osd2r03: 6.15.2 LIST command parameter data
433  * (Also for LIST COLLECTION)
434  */
436  __be64 list_bytes; /* bytes in list excluding list_bytes (-8) */
439  u8 pad[3];
442 } __packed;
443 
444 static 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  */
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  */
465 static inline int osd_data_out_integrity_info_sizeof(bool is_ver1)
466 {
467  return sizeof(struct osd_data_out_integrity_info) -
469 }
470 
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  */
481 static inline int osd_data_in_integrity_info_sizeof(bool is_ver1)
482 {
483  return sizeof(struct osd_data_in_integrity_info) -
485 }
486 
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 
499  u8 id[7]; /* if you know why 7 please email [email protected] */
500 } __packed;
501 
502 /* for osd_capability.format */
503 enum {
507 };
508 
509 /* security_method */
510 enum {
515 };
516 
522 };
523 
533 
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*/
542 };
543 
544 /* for object_descriptor_type (hi nibble used) */
545 enum {
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  */
556  u8 format; /* low nibble */
557  u8 integrity_algorithm__key_version; /* MAKE_BYTE(integ_alg, key_ver) */
561 /*10*/ u8 audit[20];
562 /*30*/ u8 discriminator[12];
566 /*54*/ u8 reserved2;
567 /*55*/ u8 object_descriptor_type; /* high nibble */
568 } __packed;
569 
570 /*56 v1*/
572  union {
573  struct {
578  } __packed obj_desc;
579 
581  };
582 } __packed;
583 /*80 v1*/
584 
585 /*56 v2*/
587  union {
588  struct {
592 /*66*/ u8 reserved[6];
597  } __packed obj_desc;
598 
600  };
601 } __packed;
602 /*104 v2*/
603 
607 } __packed;
608 
612 } __packed;
613 
623 static 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 */
637 };
638 
645 } __packed;
646 
647 /* osd2r05a sec 5.4.1: CDB continuation descriptors */
651  QUERY_LIST = 0x0002,
652  USER_OBJECT = 0x0003,
655 };
656 
662 } __packed;
663 
664 
665 /* osd2r05a sec 5.4.2: Scatter/gather list */
669 };
670 
674 };
675 
676 #endif /* ndef __OSD_PROTOCOL_H__ */