0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/greybus.h>
0010
0011 static const char *get_descriptor_type_string(u8 type)
0012 {
0013 switch (type) {
0014 case GREYBUS_TYPE_INVALID:
0015 return "invalid";
0016 case GREYBUS_TYPE_STRING:
0017 return "string";
0018 case GREYBUS_TYPE_INTERFACE:
0019 return "interface";
0020 case GREYBUS_TYPE_CPORT:
0021 return "cport";
0022 case GREYBUS_TYPE_BUNDLE:
0023 return "bundle";
0024 default:
0025 WARN_ON(1);
0026 return "unknown";
0027 }
0028 }
0029
0030
0031
0032
0033
0034
0035
0036
0037 struct manifest_desc {
0038 struct list_head links;
0039
0040 size_t size;
0041 void *data;
0042 enum greybus_descriptor_type type;
0043 };
0044
0045 static void release_manifest_descriptor(struct manifest_desc *descriptor)
0046 {
0047 list_del(&descriptor->links);
0048 kfree(descriptor);
0049 }
0050
0051 static void release_manifest_descriptors(struct gb_interface *intf)
0052 {
0053 struct manifest_desc *descriptor;
0054 struct manifest_desc *next;
0055
0056 list_for_each_entry_safe(descriptor, next, &intf->manifest_descs, links)
0057 release_manifest_descriptor(descriptor);
0058 }
0059
0060 static void release_cport_descriptors(struct list_head *head, u8 bundle_id)
0061 {
0062 struct manifest_desc *desc, *tmp;
0063 struct greybus_descriptor_cport *desc_cport;
0064
0065 list_for_each_entry_safe(desc, tmp, head, links) {
0066 desc_cport = desc->data;
0067
0068 if (desc->type != GREYBUS_TYPE_CPORT)
0069 continue;
0070
0071 if (desc_cport->bundle == bundle_id)
0072 release_manifest_descriptor(desc);
0073 }
0074 }
0075
0076 static struct manifest_desc *get_next_bundle_desc(struct gb_interface *intf)
0077 {
0078 struct manifest_desc *descriptor;
0079 struct manifest_desc *next;
0080
0081 list_for_each_entry_safe(descriptor, next, &intf->manifest_descs, links)
0082 if (descriptor->type == GREYBUS_TYPE_BUNDLE)
0083 return descriptor;
0084
0085 return NULL;
0086 }
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098 static int identify_descriptor(struct gb_interface *intf,
0099 struct greybus_descriptor *desc, size_t size)
0100 {
0101 struct greybus_descriptor_header *desc_header = &desc->header;
0102 struct manifest_desc *descriptor;
0103 size_t desc_size;
0104 size_t expected_size;
0105
0106 if (size < sizeof(*desc_header)) {
0107 dev_err(&intf->dev, "manifest too small (%zu < %zu)\n", size,
0108 sizeof(*desc_header));
0109 return -EINVAL;
0110 }
0111
0112 desc_size = le16_to_cpu(desc_header->size);
0113 if (desc_size > size) {
0114 dev_err(&intf->dev, "descriptor too big (%zu > %zu)\n",
0115 desc_size, size);
0116 return -EINVAL;
0117 }
0118
0119
0120 expected_size = sizeof(*desc_header);
0121
0122 switch (desc_header->type) {
0123 case GREYBUS_TYPE_STRING:
0124 expected_size += sizeof(struct greybus_descriptor_string);
0125 expected_size += desc->string.length;
0126
0127
0128 expected_size = ALIGN(expected_size, 4);
0129 break;
0130 case GREYBUS_TYPE_INTERFACE:
0131 expected_size += sizeof(struct greybus_descriptor_interface);
0132 break;
0133 case GREYBUS_TYPE_BUNDLE:
0134 expected_size += sizeof(struct greybus_descriptor_bundle);
0135 break;
0136 case GREYBUS_TYPE_CPORT:
0137 expected_size += sizeof(struct greybus_descriptor_cport);
0138 break;
0139 case GREYBUS_TYPE_INVALID:
0140 default:
0141 dev_err(&intf->dev, "invalid descriptor type (%u)\n",
0142 desc_header->type);
0143 return -EINVAL;
0144 }
0145
0146 if (desc_size < expected_size) {
0147 dev_err(&intf->dev, "%s descriptor too small (%zu < %zu)\n",
0148 get_descriptor_type_string(desc_header->type),
0149 desc_size, expected_size);
0150 return -EINVAL;
0151 }
0152
0153
0154 if (desc_size > expected_size) {
0155 dev_warn(&intf->dev, "%s descriptor size mismatch (want %zu got %zu)\n",
0156 get_descriptor_type_string(desc_header->type),
0157 expected_size, desc_size);
0158 }
0159
0160 descriptor = kzalloc(sizeof(*descriptor), GFP_KERNEL);
0161 if (!descriptor)
0162 return -ENOMEM;
0163
0164 descriptor->size = desc_size;
0165 descriptor->data = (char *)desc + sizeof(*desc_header);
0166 descriptor->type = desc_header->type;
0167 list_add_tail(&descriptor->links, &intf->manifest_descs);
0168
0169
0170
0171 return desc_size;
0172 }
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185 static char *gb_string_get(struct gb_interface *intf, u8 string_id)
0186 {
0187 struct greybus_descriptor_string *desc_string;
0188 struct manifest_desc *descriptor;
0189 bool found = false;
0190 char *string;
0191
0192
0193 if (!string_id)
0194 return NULL;
0195
0196 list_for_each_entry(descriptor, &intf->manifest_descs, links) {
0197 if (descriptor->type != GREYBUS_TYPE_STRING)
0198 continue;
0199
0200 desc_string = descriptor->data;
0201 if (desc_string->id == string_id) {
0202 found = true;
0203 break;
0204 }
0205 }
0206 if (!found)
0207 return ERR_PTR(-ENOENT);
0208
0209
0210 string = kmemdup(&desc_string->string, desc_string->length + 1,
0211 GFP_KERNEL);
0212 if (!string)
0213 return ERR_PTR(-ENOMEM);
0214 string[desc_string->length] = '\0';
0215
0216
0217 release_manifest_descriptor(descriptor);
0218
0219 return string;
0220 }
0221
0222
0223
0224
0225
0226
0227
0228 static u32 gb_manifest_parse_cports(struct gb_bundle *bundle)
0229 {
0230 struct gb_interface *intf = bundle->intf;
0231 struct greybus_descriptor_cport *desc_cport;
0232 struct manifest_desc *desc, *next, *tmp;
0233 LIST_HEAD(list);
0234 u8 bundle_id = bundle->id;
0235 u16 cport_id;
0236 u32 count = 0;
0237 int i;
0238
0239
0240 list_for_each_entry_safe(desc, next, &intf->manifest_descs, links) {
0241 if (desc->type != GREYBUS_TYPE_CPORT)
0242 continue;
0243
0244 desc_cport = desc->data;
0245 if (desc_cport->bundle != bundle_id)
0246 continue;
0247
0248 cport_id = le16_to_cpu(desc_cport->id);
0249 if (cport_id > CPORT_ID_MAX)
0250 goto exit;
0251
0252
0253 if (cport_id == GB_CONTROL_CPORT_ID) {
0254 dev_err(&bundle->dev, "invalid cport id found (%02u)\n",
0255 cport_id);
0256 goto exit;
0257 }
0258
0259
0260
0261
0262
0263 list_for_each_entry(tmp, &list, links) {
0264 desc_cport = tmp->data;
0265 if (cport_id == le16_to_cpu(desc_cport->id)) {
0266 dev_err(&bundle->dev,
0267 "duplicate CPort %u found\n", cport_id);
0268 goto exit;
0269 }
0270 }
0271 list_move_tail(&desc->links, &list);
0272 count++;
0273 }
0274
0275 if (!count)
0276 return 0;
0277
0278 bundle->cport_desc = kcalloc(count, sizeof(*bundle->cport_desc),
0279 GFP_KERNEL);
0280 if (!bundle->cport_desc)
0281 goto exit;
0282
0283 bundle->num_cports = count;
0284
0285 i = 0;
0286 list_for_each_entry_safe(desc, next, &list, links) {
0287 desc_cport = desc->data;
0288 memcpy(&bundle->cport_desc[i++], desc_cport,
0289 sizeof(*desc_cport));
0290
0291
0292 release_manifest_descriptor(desc);
0293 }
0294
0295 return count;
0296 exit:
0297 release_cport_descriptors(&list, bundle_id);
0298
0299
0300
0301
0302 release_cport_descriptors(&intf->manifest_descs, bundle_id);
0303
0304 return 0;
0305 }
0306
0307
0308
0309
0310
0311
0312 static u32 gb_manifest_parse_bundles(struct gb_interface *intf)
0313 {
0314 struct manifest_desc *desc;
0315 struct gb_bundle *bundle;
0316 struct gb_bundle *bundle_next;
0317 u32 count = 0;
0318 u8 bundle_id;
0319 u8 class;
0320
0321 while ((desc = get_next_bundle_desc(intf))) {
0322 struct greybus_descriptor_bundle *desc_bundle;
0323
0324
0325 desc_bundle = desc->data;
0326 bundle_id = desc_bundle->id;
0327 class = desc_bundle->class;
0328
0329
0330 release_manifest_descriptor(desc);
0331
0332
0333 if (bundle_id == GB_CONTROL_BUNDLE_ID) {
0334 dev_dbg(&intf->dev, "%s - ignoring control bundle\n",
0335 __func__);
0336 release_cport_descriptors(&intf->manifest_descs,
0337 bundle_id);
0338 continue;
0339 }
0340
0341
0342 if (class == GREYBUS_CLASS_CONTROL) {
0343 dev_err(&intf->dev,
0344 "bundle %u cannot use control class\n",
0345 bundle_id);
0346 goto cleanup;
0347 }
0348
0349 bundle = gb_bundle_create(intf, bundle_id, class);
0350 if (!bundle)
0351 goto cleanup;
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370 if (!gb_manifest_parse_cports(bundle)) {
0371 gb_bundle_destroy(bundle);
0372 continue;
0373 }
0374
0375 count++;
0376 }
0377
0378 return count;
0379 cleanup:
0380
0381 list_for_each_entry_safe(bundle, bundle_next, &intf->bundles, links) {
0382 gb_bundle_destroy(bundle);
0383 count--;
0384 }
0385 return 0;
0386 }
0387
0388 static bool gb_manifest_parse_interface(struct gb_interface *intf,
0389 struct manifest_desc *interface_desc)
0390 {
0391 struct greybus_descriptor_interface *desc_intf = interface_desc->data;
0392 struct gb_control *control = intf->control;
0393 char *str;
0394
0395
0396 str = gb_string_get(intf, desc_intf->vendor_stringid);
0397 if (IS_ERR(str))
0398 return false;
0399 control->vendor_string = str;
0400
0401 str = gb_string_get(intf, desc_intf->product_stringid);
0402 if (IS_ERR(str))
0403 goto out_free_vendor_string;
0404 control->product_string = str;
0405
0406
0407 intf->features = desc_intf->features;
0408
0409
0410 release_manifest_descriptor(interface_desc);
0411
0412
0413 if (!gb_manifest_parse_bundles(intf)) {
0414 dev_err(&intf->dev, "manifest bundle descriptors not valid\n");
0415 goto out_err;
0416 }
0417
0418 return true;
0419 out_err:
0420 kfree(control->product_string);
0421 control->product_string = NULL;
0422 out_free_vendor_string:
0423 kfree(control->vendor_string);
0424 control->vendor_string = NULL;
0425
0426 return false;
0427 }
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452 bool gb_manifest_parse(struct gb_interface *intf, void *data, size_t size)
0453 {
0454 struct greybus_manifest *manifest;
0455 struct greybus_manifest_header *header;
0456 struct greybus_descriptor *desc;
0457 struct manifest_desc *descriptor;
0458 struct manifest_desc *interface_desc = NULL;
0459 u16 manifest_size;
0460 u32 found = 0;
0461 bool result;
0462
0463
0464 if (WARN_ON(!list_empty(&intf->manifest_descs)))
0465 return false;
0466
0467
0468 if (size < sizeof(*header)) {
0469 dev_err(&intf->dev, "short manifest (%zu < %zu)\n",
0470 size, sizeof(*header));
0471 return false;
0472 }
0473
0474
0475 manifest = data;
0476 header = &manifest->header;
0477 manifest_size = le16_to_cpu(header->size);
0478 if (manifest_size != size) {
0479 dev_err(&intf->dev, "manifest size mismatch (%zu != %u)\n",
0480 size, manifest_size);
0481 return false;
0482 }
0483
0484
0485 if (header->version_major > GREYBUS_VERSION_MAJOR) {
0486 dev_err(&intf->dev, "manifest version too new (%u.%u > %u.%u)\n",
0487 header->version_major, header->version_minor,
0488 GREYBUS_VERSION_MAJOR, GREYBUS_VERSION_MINOR);
0489 return false;
0490 }
0491
0492
0493 desc = manifest->descriptors;
0494 size -= sizeof(*header);
0495 while (size) {
0496 int desc_size;
0497
0498 desc_size = identify_descriptor(intf, desc, size);
0499 if (desc_size < 0) {
0500 result = false;
0501 goto out;
0502 }
0503 desc = (struct greybus_descriptor *)((char *)desc + desc_size);
0504 size -= desc_size;
0505 }
0506
0507
0508 list_for_each_entry(descriptor, &intf->manifest_descs, links) {
0509 if (descriptor->type == GREYBUS_TYPE_INTERFACE)
0510 if (!found++)
0511 interface_desc = descriptor;
0512 }
0513 if (found != 1) {
0514 dev_err(&intf->dev, "manifest must have 1 interface descriptor (%u found)\n",
0515 found);
0516 result = false;
0517 goto out;
0518 }
0519
0520
0521 result = gb_manifest_parse_interface(intf, interface_desc);
0522
0523
0524
0525
0526
0527 if (result && !list_empty(&intf->manifest_descs))
0528 dev_info(&intf->dev, "excess descriptors in interface manifest\n");
0529 out:
0530 release_manifest_descriptors(intf);
0531
0532 return result;
0533 }