diff options
Diffstat (limited to 'include/scsi')
-rw-r--r-- | include/scsi/osd_initiator.h | 39 | ||||
-rw-r--r-- | include/scsi/osd_protocol.h | 90 |
2 files changed, 125 insertions, 4 deletions
diff --git a/include/scsi/osd_initiator.h b/include/scsi/osd_initiator.h index e84dc7aa5e34..8482777416d8 100644 --- a/include/scsi/osd_initiator.h +++ b/include/scsi/osd_initiator.h | |||
@@ -21,6 +21,23 @@ | |||
21 | 21 | ||
22 | /* Note: "NI" in comments below means "Not Implemented yet" */ | 22 | /* Note: "NI" in comments below means "Not Implemented yet" */ |
23 | 23 | ||
24 | /* Configure of code: | ||
25 | * #undef if you *don't* want OSD v1 support in runtime. | ||
26 | * If #defined the initiator will dynamically configure to encode OSD v1 | ||
27 | * CDB's if the target is detected to be OSD v1 only. | ||
28 | * OSD v2 only commands, options, and attributes will be ignored if target | ||
29 | * is v1 only. | ||
30 | * If #defined will result in bigger/slower code (OK Slower maybe not) | ||
31 | * Q: Should this be CONFIG_SCSI_OSD_VER1_SUPPORT and set from Kconfig? | ||
32 | */ | ||
33 | #define OSD_VER1_SUPPORT y | ||
34 | |||
35 | enum osd_std_version { | ||
36 | OSD_VER_NONE = 0, | ||
37 | OSD_VER1 = 1, | ||
38 | OSD_VER2 = 2, | ||
39 | }; | ||
40 | |||
24 | /* | 41 | /* |
25 | * Object-based Storage Device. | 42 | * Object-based Storage Device. |
26 | * This object represents an OSD device. | 43 | * This object represents an OSD device. |
@@ -31,6 +48,10 @@ | |||
31 | struct osd_dev { | 48 | struct osd_dev { |
32 | struct scsi_device *scsi_device; | 49 | struct scsi_device *scsi_device; |
33 | unsigned def_timeout; | 50 | unsigned def_timeout; |
51 | |||
52 | #ifdef OSD_VER1_SUPPORT | ||
53 | enum osd_std_version version; | ||
54 | #endif | ||
34 | }; | 55 | }; |
35 | 56 | ||
36 | /* Retrieve/return osd_dev(s) for use by Kernel clients */ | 57 | /* Retrieve/return osd_dev(s) for use by Kernel clients */ |
@@ -46,6 +67,14 @@ void osduld_unregister_test(unsigned ioctl); | |||
46 | void osd_dev_init(struct osd_dev *od, struct scsi_device *scsi_device); | 67 | void osd_dev_init(struct osd_dev *od, struct scsi_device *scsi_device); |
47 | void osd_dev_fini(struct osd_dev *od); | 68 | void osd_dev_fini(struct osd_dev *od); |
48 | 69 | ||
70 | /* we might want to use function vector in the future */ | ||
71 | static inline void osd_dev_set_ver(struct osd_dev *od, enum osd_std_version v) | ||
72 | { | ||
73 | #ifdef OSD_VER1_SUPPORT | ||
74 | od->version = v; | ||
75 | #endif | ||
76 | } | ||
77 | |||
49 | struct osd_request; | 78 | struct osd_request; |
50 | typedef void (osd_req_done_fn)(struct osd_request *or, void *private); | 79 | typedef void (osd_req_done_fn)(struct osd_request *or, void *private); |
51 | 80 | ||
@@ -82,6 +111,16 @@ struct osd_request { | |||
82 | int async_error; | 111 | int async_error; |
83 | }; | 112 | }; |
84 | 113 | ||
114 | /* OSD Version control */ | ||
115 | static inline bool osd_req_is_ver1(struct osd_request *or) | ||
116 | { | ||
117 | #ifdef OSD_VER1_SUPPORT | ||
118 | return or->osd_dev->version == OSD_VER1; | ||
119 | #else | ||
120 | return false; | ||
121 | #endif | ||
122 | } | ||
123 | |||
85 | /* | 124 | /* |
86 | * How to use the osd library: | 125 | * How to use the osd library: |
87 | * | 126 | * |
diff --git a/include/scsi/osd_protocol.h b/include/scsi/osd_protocol.h index ce1a8771ea71..cd3cbf764650 100644 --- a/include/scsi/osd_protocol.h +++ b/include/scsi/osd_protocol.h | |||
@@ -25,12 +25,16 @@ enum { | |||
25 | OSDv1_TOTAL_CDB_LEN = OSDv1_ADDITIONAL_CDB_LENGTH + 8, | 25 | OSDv1_TOTAL_CDB_LEN = OSDv1_ADDITIONAL_CDB_LENGTH + 8, |
26 | OSDv1_CAP_LEN = 80, | 26 | OSDv1_CAP_LEN = 80, |
27 | /* Latest supported version */ | 27 | /* Latest supported version */ |
28 | OSD_ADDITIONAL_CDB_LENGTH = OSDv1_ADDITIONAL_CDB_LENGTH, | 28 | /* OSD_ADDITIONAL_CDB_LENGTH = 216,*/ |
29 | OSD_TOTAL_CDB_LEN = OSDv1_TOTAL_CDB_LEN, | 29 | OSD_ADDITIONAL_CDB_LENGTH = |
30 | OSD_CAP_LEN = OSDv1_CAP_LEN, | 30 | OSDv1_ADDITIONAL_CDB_LENGTH, /* FIXME: Pete rev-001 sup */ |
31 | OSD_TOTAL_CDB_LEN = OSD_ADDITIONAL_CDB_LENGTH + 8, | ||
32 | /* OSD_CAP_LEN = 104,*/ | ||
33 | OSD_CAP_LEN = OSDv1_CAP_LEN,/* FIXME: Pete rev-001 sup */ | ||
31 | 34 | ||
32 | OSD_SYSTEMID_LEN = 20, | 35 | OSD_SYSTEMID_LEN = 20, |
33 | OSD_CRYPTO_KEYID_SIZE = 20, | 36 | OSD_CRYPTO_KEYID_SIZE = 20, |
37 | /*FIXME: OSDv2_CRYPTO_KEYID_SIZE = 32,*/ | ||
34 | OSD_CRYPTO_SEED_SIZE = 4, | 38 | OSD_CRYPTO_SEED_SIZE = 4, |
35 | OSD_CRYPTO_NONCE_SIZE = 12, | 39 | OSD_CRYPTO_NONCE_SIZE = 12, |
36 | OSD_MAX_SENSE_LEN = 252, /* from SPC-3 */ | 40 | OSD_MAX_SENSE_LEN = 252, /* from SPC-3 */ |
@@ -108,6 +112,7 @@ enum { | |||
108 | OSD_OFFSET_MAX_BITS = 28, | 112 | OSD_OFFSET_MAX_BITS = 28, |
109 | 113 | ||
110 | OSDv1_OFFSET_MIN_SHIFT = 8, | 114 | OSDv1_OFFSET_MIN_SHIFT = 8, |
115 | OSD_OFFSET_MIN_SHIFT = 3, | ||
111 | OSD_OFFSET_MAX_SHIFT = 16, | 116 | OSD_OFFSET_MAX_SHIFT = 16, |
112 | }; | 117 | }; |
113 | 118 | ||
@@ -129,6 +134,16 @@ static inline osd_cdb_offset osd_encode_offset_v1(u64 offset, unsigned *padding) | |||
129 | OSDv1_OFFSET_MIN_SHIFT, OSD_OFFSET_MAX_SHIFT); | 134 | OSDv1_OFFSET_MIN_SHIFT, OSD_OFFSET_MAX_SHIFT); |
130 | } | 135 | } |
131 | 136 | ||
137 | /* Minimum 8 bytes alignment | ||
138 | * Same as v1 but since exponent can be signed than a less than | ||
139 | * 256 alignment can be reached with small offsets (<2GB) | ||
140 | */ | ||
141 | static inline osd_cdb_offset osd_encode_offset_v2(u64 offset, unsigned *padding) | ||
142 | { | ||
143 | return __osd_encode_offset(offset, padding, | ||
144 | OSD_OFFSET_MIN_SHIFT, OSD_OFFSET_MAX_SHIFT); | ||
145 | } | ||
146 | |||
132 | /* osd2r03: 5.2.1 Overview */ | 147 | /* osd2r03: 5.2.1 Overview */ |
133 | struct osd_cdb_head { | 148 | struct osd_cdb_head { |
134 | struct scsi_varlen_cdb_hdr varlen_cdb; | 149 | struct scsi_varlen_cdb_hdr varlen_cdb; |
@@ -144,6 +159,13 @@ struct osd_cdb_head { | |||
144 | /*36*/ __be64 length; | 159 | /*36*/ __be64 length; |
145 | /*44*/ __be64 start_address; | 160 | /*44*/ __be64 start_address; |
146 | } __packed v1; | 161 | } __packed v1; |
162 | |||
163 | struct __osdv2_cdb_addr_len { | ||
164 | /* called allocation_length in some commands */ | ||
165 | /*32*/ __be64 length; | ||
166 | /*40*/ __be64 start_address; | ||
167 | /*48*/ __be32 list_identifier;/* Rarely used */ | ||
168 | } __packed v2; | ||
147 | }; | 169 | }; |
148 | /*52*/ union { /* selected attributes mode Page/List/Single */ | 170 | /*52*/ union { /* selected attributes mode Page/List/Single */ |
149 | struct osd_attributes_page_mode { | 171 | struct osd_attributes_page_mode { |
@@ -182,6 +204,7 @@ struct osd_cdb_head { | |||
182 | /*80*/ | 204 | /*80*/ |
183 | 205 | ||
184 | /*160 v1*/ | 206 | /*160 v1*/ |
207 | /*184 v2*/ | ||
185 | struct osd_security_parameters { | 208 | struct osd_security_parameters { |
186 | /*160*/u8 integrity_check_value[OSD_CRYPTO_KEYID_SIZE]; | 209 | /*160*/u8 integrity_check_value[OSD_CRYPTO_KEYID_SIZE]; |
187 | /*180*/u8 request_nonce[OSD_CRYPTO_NONCE_SIZE]; | 210 | /*180*/u8 request_nonce[OSD_CRYPTO_NONCE_SIZE]; |
@@ -189,6 +212,9 @@ struct osd_security_parameters { | |||
189 | /*196*/osd_cdb_offset data_out_integrity_check_offset; | 212 | /*196*/osd_cdb_offset data_out_integrity_check_offset; |
190 | } __packed; | 213 | } __packed; |
191 | /*200 v1*/ | 214 | /*200 v1*/ |
215 | /*224 v2*/ | ||
216 | |||
217 | /* FIXME: osdv2_security_parameters */ | ||
192 | 218 | ||
193 | struct osdv1_cdb { | 219 | struct osdv1_cdb { |
194 | struct osd_cdb_head h; | 220 | struct osd_cdb_head h; |
@@ -196,9 +222,17 @@ struct osdv1_cdb { | |||
196 | struct osd_security_parameters sec_params; | 222 | struct osd_security_parameters sec_params; |
197 | } __packed; | 223 | } __packed; |
198 | 224 | ||
225 | struct osdv2_cdb { | ||
226 | struct osd_cdb_head h; | ||
227 | u8 caps[OSD_CAP_LEN]; | ||
228 | struct osd_security_parameters sec_params; | ||
229 | /* FIXME: osdv2_security_parameters */ | ||
230 | } __packed; | ||
231 | |||
199 | struct osd_cdb { | 232 | struct osd_cdb { |
200 | union { | 233 | union { |
201 | struct osdv1_cdb v1; | 234 | struct osdv1_cdb v1; |
235 | struct osdv2_cdb v2; | ||
202 | u8 buff[OSD_TOTAL_CDB_LEN]; | 236 | u8 buff[OSD_TOTAL_CDB_LEN]; |
203 | }; | 237 | }; |
204 | } __packed; | 238 | } __packed; |
@@ -269,6 +303,7 @@ struct osd_attributes_list_attrid { | |||
269 | /* | 303 | /* |
270 | * osd2r03: 7.1.3.3 List entry format for retrieved attributes and | 304 | * osd2r03: 7.1.3.3 List entry format for retrieved attributes and |
271 | * for setting attributes | 305 | * for setting attributes |
306 | * NOTE: v2 is 8-bytes aligned, v1 is not aligned. | ||
272 | */ | 307 | */ |
273 | struct osd_attributes_list_element { | 308 | struct osd_attributes_list_element { |
274 | __be32 attr_page; | 309 | __be32 attr_page; |
@@ -279,6 +314,7 @@ struct osd_attributes_list_element { | |||
279 | 314 | ||
280 | enum { | 315 | enum { |
281 | OSDv1_ATTRIBUTES_ELEM_ALIGN = 1, | 316 | OSDv1_ATTRIBUTES_ELEM_ALIGN = 1, |
317 | OSD_ATTRIBUTES_ELEM_ALIGN = 8, | ||
282 | }; | 318 | }; |
283 | 319 | ||
284 | enum { | 320 | enum { |
@@ -292,6 +328,12 @@ static inline unsigned osdv1_attr_list_elem_size(unsigned len) | |||
292 | OSDv1_ATTRIBUTES_ELEM_ALIGN); | 328 | OSDv1_ATTRIBUTES_ELEM_ALIGN); |
293 | } | 329 | } |
294 | 330 | ||
331 | static inline unsigned osdv2_attr_list_elem_size(unsigned len) | ||
332 | { | ||
333 | return ALIGN(len + sizeof(struct osd_attributes_list_element), | ||
334 | OSD_ATTRIBUTES_ELEM_ALIGN); | ||
335 | } | ||
336 | |||
295 | /* | 337 | /* |
296 | * osd2r03: 7.1.3 OSD attributes lists (Table 184) — List type values | 338 | * osd2r03: 7.1.3 OSD attributes lists (Table 184) — List type values |
297 | */ | 339 | */ |
@@ -326,6 +368,21 @@ static inline unsigned osdv1_list_size(struct osdv1_attributes_list_header *h) | |||
326 | return be16_to_cpu(h->list_bytes); | 368 | return be16_to_cpu(h->list_bytes); |
327 | } | 369 | } |
328 | 370 | ||
371 | struct osdv2_attributes_list_header { | ||
372 | u8 type; /* lower 4-bits only */ | ||
373 | u8 pad[3]; | ||
374 | /*4*/ __be32 list_bytes; /* Initiator shall set to zero. Only set by target */ | ||
375 | /* | ||
376 | * type=9 followed by struct osd_attributes_list_element's | ||
377 | * type=E followed by struct osd_attributes_list_multi_header's | ||
378 | */ | ||
379 | } __packed; | ||
380 | |||
381 | static inline unsigned osdv2_list_size(struct osdv2_attributes_list_header *h) | ||
382 | { | ||
383 | return be32_to_cpu(h->list_bytes); | ||
384 | } | ||
385 | |||
329 | /* (osd-r10 6.13) | 386 | /* (osd-r10 6.13) |
330 | * osd2r03: 6.15 LIST (Table 79) LIST command parameter data. | 387 | * osd2r03: 6.15 LIST (Table 79) LIST command parameter data. |
331 | * for root_lstchg below | 388 | * for root_lstchg below |
@@ -469,11 +526,36 @@ struct osdv1_cap_object_descriptor { | |||
469 | } __packed; | 526 | } __packed; |
470 | /*80 v1*/ | 527 | /*80 v1*/ |
471 | 528 | ||
472 | struct osd_capability { | 529 | /*56 v2*/ |
530 | struct osd_cap_object_descriptor { | ||
531 | union { | ||
532 | struct { | ||
533 | /*56*/ __be32 allowed_attributes_access; | ||
534 | /*60*/ __be32 policy_access_tag; | ||
535 | /*64*/ __be16 boot_epoch; | ||
536 | /*66*/ u8 reserved[6]; | ||
537 | /*72*/ __be64 allowed_partition_id; | ||
538 | /*80*/ __be64 allowed_object_id; | ||
539 | /*88*/ __be64 allowed_range_length; | ||
540 | /*96*/ __be64 allowed_range_start; | ||
541 | } __packed obj_desc; | ||
542 | |||
543 | /*56*/ u8 object_descriptor[48]; | ||
544 | }; | ||
545 | } __packed; | ||
546 | /*104 v2*/ | ||
547 | |||
548 | struct osdv1_capability { | ||
473 | struct osd_capability_head h; | 549 | struct osd_capability_head h; |
474 | struct osdv1_cap_object_descriptor od; | 550 | struct osdv1_cap_object_descriptor od; |
475 | } __packed; | 551 | } __packed; |
476 | 552 | ||
553 | struct osd_capability { | ||
554 | struct osd_capability_head h; | ||
555 | /* struct osd_cap_object_descriptor od;*/ | ||
556 | struct osdv1_cap_object_descriptor od; /* FIXME: Pete rev-001 sup */ | ||
557 | } __packed; | ||
558 | |||
477 | /** | 559 | /** |
478 | * osd_sec_set_caps - set cap-bits into the capabilities header | 560 | * osd_sec_set_caps - set cap-bits into the capabilities header |
479 | * | 561 | * |