aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/scsi/osd/osd_initiator.c94
-rw-r--r--include/scsi/osd_initiator.h39
-rw-r--r--include/scsi/osd_protocol.h90
3 files changed, 205 insertions, 18 deletions
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c
index 3fd021a57e5..86a76cccfeb 100644
--- a/drivers/scsi/osd/osd_initiator.c
+++ b/drivers/scsi/osd/osd_initiator.c
@@ -59,36 +59,50 @@ static inline void build_test(void)
59{ 59{
60 /* structures were not packed */ 60 /* structures were not packed */
61 BUILD_BUG_ON(sizeof(struct osd_capability) != OSD_CAP_LEN); 61 BUILD_BUG_ON(sizeof(struct osd_capability) != OSD_CAP_LEN);
62 BUILD_BUG_ON(sizeof(struct osdv2_cdb) != OSD_TOTAL_CDB_LEN);
62 BUILD_BUG_ON(sizeof(struct osdv1_cdb) != OSDv1_TOTAL_CDB_LEN); 63 BUILD_BUG_ON(sizeof(struct osdv1_cdb) != OSDv1_TOTAL_CDB_LEN);
63} 64}
64 65
65static unsigned _osd_req_cdb_len(struct osd_request *or) 66static unsigned _osd_req_cdb_len(struct osd_request *or)
66{ 67{
67 return OSDv1_TOTAL_CDB_LEN; 68 return osd_req_is_ver1(or) ? OSDv1_TOTAL_CDB_LEN : OSD_TOTAL_CDB_LEN;
68} 69}
69 70
70static unsigned _osd_req_alist_elem_size(struct osd_request *or, unsigned len) 71static unsigned _osd_req_alist_elem_size(struct osd_request *or, unsigned len)
71{ 72{
72 return osdv1_attr_list_elem_size(len); 73 return osd_req_is_ver1(or) ?
74 osdv1_attr_list_elem_size(len) :
75 osdv2_attr_list_elem_size(len);
73} 76}
74 77
75static unsigned _osd_req_alist_size(struct osd_request *or, void *list_head) 78static unsigned _osd_req_alist_size(struct osd_request *or, void *list_head)
76{ 79{
77 return osdv1_list_size(list_head); 80 return osd_req_is_ver1(or) ?
81 osdv1_list_size(list_head) :
82 osdv2_list_size(list_head);
78} 83}
79 84
80static unsigned _osd_req_sizeof_alist_header(struct osd_request *or) 85static unsigned _osd_req_sizeof_alist_header(struct osd_request *or)
81{ 86{
82 return sizeof(struct osdv1_attributes_list_header); 87 return osd_req_is_ver1(or) ?
88 sizeof(struct osdv1_attributes_list_header) :
89 sizeof(struct osdv2_attributes_list_header);
83} 90}
84 91
85static void _osd_req_set_alist_type(struct osd_request *or, 92static void _osd_req_set_alist_type(struct osd_request *or,
86 void *list, int list_type) 93 void *list, int list_type)
87{ 94{
88 struct osdv1_attributes_list_header *attr_list = list; 95 if (osd_req_is_ver1(or)) {
96 struct osdv1_attributes_list_header *attr_list = list;
97
98 memset(attr_list, 0, sizeof(*attr_list));
99 attr_list->type = list_type;
100 } else {
101 struct osdv2_attributes_list_header *attr_list = list;
89 102
90 memset(attr_list, 0, sizeof(*attr_list)); 103 memset(attr_list, 0, sizeof(*attr_list));
91 attr_list->type = list_type; 104 attr_list->type = list_type;
105 }
92} 106}
93 107
94static bool _osd_req_is_alist_type(struct osd_request *or, 108static bool _osd_req_is_alist_type(struct osd_request *or,
@@ -97,10 +111,14 @@ static bool _osd_req_is_alist_type(struct osd_request *or,
97 if (!list) 111 if (!list)
98 return false; 112 return false;
99 113
100 if (1) { 114 if (osd_req_is_ver1(or)) {
101 struct osdv1_attributes_list_header *attr_list = list; 115 struct osdv1_attributes_list_header *attr_list = list;
102 116
103 return attr_list->type == list_type; 117 return attr_list->type == list_type;
118 } else {
119 struct osdv2_attributes_list_header *attr_list = list;
120
121 return attr_list->type == list_type;
104 } 122 }
105} 123}
106 124
@@ -110,15 +128,22 @@ static void _osd_req_encode_olist(struct osd_request *or,
110{ 128{
111 struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); 129 struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb);
112 130
113 cdbh->v1.list_identifier = list->list_identifier; 131 if (osd_req_is_ver1(or)) {
114 cdbh->v1.start_address = list->continuation_id; 132 cdbh->v1.list_identifier = list->list_identifier;
133 cdbh->v1.start_address = list->continuation_id;
134 } else {
135 cdbh->v2.list_identifier = list->list_identifier;
136 cdbh->v2.start_address = list->continuation_id;
137 }
115} 138}
116 139
117static osd_cdb_offset osd_req_encode_offset(struct osd_request *or, 140static osd_cdb_offset osd_req_encode_offset(struct osd_request *or,
118 u64 offset, unsigned *padding) 141 u64 offset, unsigned *padding)
119{ 142{
120 return __osd_encode_offset(offset, padding, 143 return __osd_encode_offset(offset, padding,
121 OSDv1_OFFSET_MIN_SHIFT, OSD_OFFSET_MAX_SHIFT); 144 osd_req_is_ver1(or) ?
145 OSDv1_OFFSET_MIN_SHIFT : OSD_OFFSET_MIN_SHIFT,
146 OSD_OFFSET_MAX_SHIFT);
122} 147}
123 148
124static struct osd_security_parameters * 149static struct osd_security_parameters *
@@ -126,7 +151,10 @@ _osd_req_sec_params(struct osd_request *or)
126{ 151{
127 struct osd_cdb *ocdb = &or->cdb; 152 struct osd_cdb *ocdb = &or->cdb;
128 153
129 return &ocdb->v1.sec_params; 154 if (osd_req_is_ver1(or))
155 return &ocdb->v1.sec_params;
156 else
157 return &ocdb->v2.sec_params;
130} 158}
131 159
132void osd_dev_init(struct osd_dev *osdd, struct scsi_device *scsi_device) 160void osd_dev_init(struct osd_dev *osdd, struct scsi_device *scsi_device)
@@ -134,6 +162,9 @@ void osd_dev_init(struct osd_dev *osdd, struct scsi_device *scsi_device)
134 memset(osdd, 0, sizeof(*osdd)); 162 memset(osdd, 0, sizeof(*osdd));
135 osdd->scsi_device = scsi_device; 163 osdd->scsi_device = scsi_device;
136 osdd->def_timeout = BLK_DEFAULT_SG_TIMEOUT; 164 osdd->def_timeout = BLK_DEFAULT_SG_TIMEOUT;
165#ifdef OSD_VER1_SUPPORT
166 osdd->version = OSD_VER2;
167#endif
137 /* TODO: Allocate pools for osd_request attributes ... */ 168 /* TODO: Allocate pools for osd_request attributes ... */
138} 169}
139EXPORT_SYMBOL(osd_dev_init); 170EXPORT_SYMBOL(osd_dev_init);
@@ -334,10 +365,30 @@ static void _osdv1_req_encode_common(struct osd_request *or,
334 ocdb->h.v1.start_address = cpu_to_be64(offset); 365 ocdb->h.v1.start_address = cpu_to_be64(offset);
335} 366}
336 367
368static void _osdv2_req_encode_common(struct osd_request *or,
369 __be16 act, const struct osd_obj_id *obj, u64 offset, u64 len)
370{
371 struct osdv2_cdb *ocdb = &or->cdb.v2;
372
373 OSD_DEBUG("OSDv2 execute opcode 0x%x\n", be16_to_cpu(act));
374
375 ocdb->h.varlen_cdb.opcode = VARIABLE_LENGTH_CMD;
376 ocdb->h.varlen_cdb.additional_cdb_length = OSD_ADDITIONAL_CDB_LENGTH;
377 ocdb->h.varlen_cdb.service_action = act;
378
379 ocdb->h.partition = cpu_to_be64(obj->partition);
380 ocdb->h.object = cpu_to_be64(obj->id);
381 ocdb->h.v2.length = cpu_to_be64(len);
382 ocdb->h.v2.start_address = cpu_to_be64(offset);
383}
384
337static void _osd_req_encode_common(struct osd_request *or, 385static void _osd_req_encode_common(struct osd_request *or,
338 __be16 act, const struct osd_obj_id *obj, u64 offset, u64 len) 386 __be16 act, const struct osd_obj_id *obj, u64 offset, u64 len)
339{ 387{
340 _osdv1_req_encode_common(or, act, obj, offset, len); 388 if (osd_req_is_ver1(or))
389 _osdv1_req_encode_common(or, act, obj, offset, len);
390 else
391 _osdv2_req_encode_common(or, act, obj, offset, len);
341} 392}
342 393
343/* 394/*
@@ -546,6 +597,12 @@ void osd_req_flush_object(struct osd_request *or,
546 const struct osd_obj_id *obj, enum osd_options_flush_scope_values op, 597 const struct osd_obj_id *obj, enum osd_options_flush_scope_values op,
547 /*V2*/ u64 offset, /*V2*/ u64 len) 598 /*V2*/ u64 offset, /*V2*/ u64 len)
548{ 599{
600 if (unlikely(osd_req_is_ver1(or) && (offset || len))) {
601 OSD_DEBUG("OSD Ver1 flush on specific range ignored\n");
602 offset = 0;
603 len = 0;
604 }
605
549 _osd_req_encode_common(or, OSD_ACT_FLUSH, obj, offset, len); 606 _osd_req_encode_common(or, OSD_ACT_FLUSH, obj, offset, len);
550 _osd_req_encode_flush(or, op); 607 _osd_req_encode_flush(or, op);
551} 608}
@@ -1169,6 +1226,10 @@ enum { OSD_SEC_CAP_V1_ALL_CAPS =
1169 OSD_SEC_CAP_GLOBAL | OSD_SEC_CAP_DEV_MGMT 1226 OSD_SEC_CAP_GLOBAL | OSD_SEC_CAP_DEV_MGMT
1170}; 1227};
1171 1228
1229enum { OSD_SEC_CAP_V2_ALL_CAPS =
1230 OSD_SEC_CAP_V1_ALL_CAPS | OSD_SEC_CAP_QUERY | OSD_SEC_CAP_M_OBJECT
1231};
1232
1172void osd_sec_init_nosec_doall_caps(void *caps, 1233void osd_sec_init_nosec_doall_caps(void *caps,
1173 const struct osd_obj_id *obj, bool is_collection, const bool is_v1) 1234 const struct osd_obj_id *obj, bool is_collection, const bool is_v1)
1174{ 1235{
@@ -1210,9 +1271,14 @@ void osd_sec_init_nosec_doall_caps(void *caps,
1210} 1271}
1211EXPORT_SYMBOL(osd_sec_init_nosec_doall_caps); 1272EXPORT_SYMBOL(osd_sec_init_nosec_doall_caps);
1212 1273
1274/* FIXME: Extract version from caps pointer.
1275 * Also Pete's target only supports caps from OSDv1 for now
1276 */
1213void osd_set_caps(struct osd_cdb *cdb, const void *caps) 1277void osd_set_caps(struct osd_cdb *cdb, const void *caps)
1214{ 1278{
1215 memcpy(&cdb->v1.caps, caps, OSDv1_CAP_LEN); 1279 bool is_ver1 = true;
1280 /* NOTE: They start at same address */
1281 memcpy(&cdb->v1.caps, caps, is_ver1 ? OSDv1_CAP_LEN : OSD_CAP_LEN);
1216} 1282}
1217 1283
1218bool osd_is_sec_alldata(struct osd_security_parameters *sec_parms __unused) 1284bool osd_is_sec_alldata(struct osd_security_parameters *sec_parms __unused)
diff --git a/include/scsi/osd_initiator.h b/include/scsi/osd_initiator.h
index e84dc7aa5e3..8482777416d 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 ce1a8771ea7..cd3cbf76465 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 *