aboutsummaryrefslogtreecommitdiffstats
path: root/include/scsi
diff options
context:
space:
mode:
authorBoaz Harrosh <bharrosh@panasas.com>2009-01-25 10:09:40 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-03-12 13:58:08 -0400
commitc6572c983726fe3f3bb5f07e9afe3a9b8e402d1b (patch)
treee5d1b19779db4d94dded752c2f8a940d9843ff5b /include/scsi
parentae30c994a4bb70510fdcb9e7223805bb2a8bc9ee (diff)
[SCSI] libosd: OSD version 2 Support
Add support for OSD2 at run time. It is now possible to run with both OSDv1 and OSDv2 targets at the same time. The actual detection should be preformed by the security manager, as the version is encoded in the capability structure. Signed-off-by: Boaz Harrosh <bharrosh@panasas.com> Reviewed-by: Benny Halevy <bhalevy@panasas.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'include/scsi')
-rw-r--r--include/scsi/osd_initiator.h39
-rw-r--r--include/scsi/osd_protocol.h90
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
35enum 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 @@
31struct osd_dev { 48struct 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);
46void osd_dev_init(struct osd_dev *od, struct scsi_device *scsi_device); 67void osd_dev_init(struct osd_dev *od, struct scsi_device *scsi_device);
47void osd_dev_fini(struct osd_dev *od); 68void osd_dev_fini(struct osd_dev *od);
48 69
70/* we might want to use function vector in the future */
71static 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
49struct osd_request; 78struct osd_request;
50typedef void (osd_req_done_fn)(struct osd_request *or, void *private); 79typedef 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 */
115static 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 */
141static 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 */
133struct osd_cdb_head { 148struct 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*/
185struct osd_security_parameters { 208struct 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
193struct osdv1_cdb { 219struct 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
225struct 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
199struct osd_cdb { 232struct 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 */
273struct osd_attributes_list_element { 308struct osd_attributes_list_element {
274 __be32 attr_page; 309 __be32 attr_page;
@@ -279,6 +314,7 @@ struct osd_attributes_list_element {
279 314
280enum { 315enum {
281 OSDv1_ATTRIBUTES_ELEM_ALIGN = 1, 316 OSDv1_ATTRIBUTES_ELEM_ALIGN = 1,
317 OSD_ATTRIBUTES_ELEM_ALIGN = 8,
282}; 318};
283 319
284enum { 320enum {
@@ -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
331static 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
371struct 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
381static 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
472struct osd_capability { 529/*56 v2*/
530struct 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
548struct 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
553struct 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 *