Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.13-rc4 535 lines 15 kB view raw
1/* 2 * Greybus manifest parsing 3 * 4 * Copyright 2014-2015 Google Inc. 5 * Copyright 2014-2015 Linaro Ltd. 6 * 7 * Released under the GPLv2 only. 8 */ 9 10#include "greybus.h" 11 12static const char *get_descriptor_type_string(u8 type) 13{ 14 switch (type) { 15 case GREYBUS_TYPE_INVALID: 16 return "invalid"; 17 case GREYBUS_TYPE_STRING: 18 return "string"; 19 case GREYBUS_TYPE_INTERFACE: 20 return "interface"; 21 case GREYBUS_TYPE_CPORT: 22 return "cport"; 23 case GREYBUS_TYPE_BUNDLE: 24 return "bundle"; 25 default: 26 WARN_ON(1); 27 return "unknown"; 28 } 29} 30 31/* 32 * We scan the manifest once to identify where all the descriptors 33 * are. The result is a list of these manifest_desc structures. We 34 * then pick through them for what we're looking for (starting with 35 * the interface descriptor). As each is processed we remove it from 36 * the list. When we're done the list should (probably) be empty. 37 */ 38struct manifest_desc { 39 struct list_head links; 40 41 size_t size; 42 void *data; 43 enum greybus_descriptor_type type; 44}; 45 46static void release_manifest_descriptor(struct manifest_desc *descriptor) 47{ 48 list_del(&descriptor->links); 49 kfree(descriptor); 50} 51 52static void release_manifest_descriptors(struct gb_interface *intf) 53{ 54 struct manifest_desc *descriptor; 55 struct manifest_desc *next; 56 57 list_for_each_entry_safe(descriptor, next, &intf->manifest_descs, links) 58 release_manifest_descriptor(descriptor); 59} 60 61static void release_cport_descriptors(struct list_head *head, u8 bundle_id) 62{ 63 struct manifest_desc *desc, *tmp; 64 struct greybus_descriptor_cport *desc_cport; 65 66 list_for_each_entry_safe(desc, tmp, head, links) { 67 desc_cport = desc->data; 68 69 if (desc->type != GREYBUS_TYPE_CPORT) 70 continue; 71 72 if (desc_cport->bundle == bundle_id) 73 release_manifest_descriptor(desc); 74 } 75} 76 77static struct manifest_desc *get_next_bundle_desc(struct gb_interface *intf) 78{ 79 struct manifest_desc *descriptor; 80 struct manifest_desc *next; 81 82 list_for_each_entry_safe(descriptor, next, &intf->manifest_descs, links) 83 if (descriptor->type == GREYBUS_TYPE_BUNDLE) 84 return descriptor; 85 86 return NULL; 87} 88 89/* 90 * Validate the given descriptor. Its reported size must fit within 91 * the number of bytes remaining, and it must have a recognized 92 * type. Check that the reported size is at least as big as what 93 * we expect to see. (It could be bigger, perhaps for a new version 94 * of the format.) 95 * 96 * Returns the (non-zero) number of bytes consumed by the descriptor, 97 * or a negative errno. 98 */ 99static int identify_descriptor(struct gb_interface *intf, 100 struct greybus_descriptor *desc, size_t size) 101{ 102 struct greybus_descriptor_header *desc_header = &desc->header; 103 struct manifest_desc *descriptor; 104 size_t desc_size; 105 size_t expected_size; 106 107 if (size < sizeof(*desc_header)) { 108 dev_err(&intf->dev, "manifest too small (%zu < %zu)\n", 109 size, sizeof(*desc_header)); 110 return -EINVAL; /* Must at least have header */ 111 } 112 113 desc_size = le16_to_cpu(desc_header->size); 114 if (desc_size > size) { 115 dev_err(&intf->dev, "descriptor too big (%zu > %zu)\n", 116 desc_size, size); 117 return -EINVAL; 118 } 119 120 /* Descriptor needs to at least have a header */ 121 expected_size = sizeof(*desc_header); 122 123 switch (desc_header->type) { 124 case GREYBUS_TYPE_STRING: 125 expected_size += sizeof(struct greybus_descriptor_string); 126 expected_size += desc->string.length; 127 128 /* String descriptors are padded to 4 byte boundaries */ 129 expected_size = ALIGN(expected_size, 4); 130 break; 131 case GREYBUS_TYPE_INTERFACE: 132 expected_size += sizeof(struct greybus_descriptor_interface); 133 break; 134 case GREYBUS_TYPE_BUNDLE: 135 expected_size += sizeof(struct greybus_descriptor_bundle); 136 break; 137 case GREYBUS_TYPE_CPORT: 138 expected_size += sizeof(struct greybus_descriptor_cport); 139 break; 140 case GREYBUS_TYPE_INVALID: 141 default: 142 dev_err(&intf->dev, "invalid descriptor type (%u)\n", 143 desc_header->type); 144 return -EINVAL; 145 } 146 147 if (desc_size < expected_size) { 148 dev_err(&intf->dev, "%s descriptor too small (%zu < %zu)\n", 149 get_descriptor_type_string(desc_header->type), 150 desc_size, expected_size); 151 return -EINVAL; 152 } 153 154 /* Descriptor bigger than what we expect */ 155 if (desc_size > expected_size) { 156 dev_warn(&intf->dev, "%s descriptor size mismatch (want %zu got %zu)\n", 157 get_descriptor_type_string(desc_header->type), 158 expected_size, desc_size); 159 } 160 161 descriptor = kzalloc(sizeof(*descriptor), GFP_KERNEL); 162 if (!descriptor) 163 return -ENOMEM; 164 165 descriptor->size = desc_size; 166 descriptor->data = (char *)desc + sizeof(*desc_header); 167 descriptor->type = desc_header->type; 168 list_add_tail(&descriptor->links, &intf->manifest_descs); 169 170 /* desc_size is positive and is known to fit in a signed int */ 171 172 return desc_size; 173} 174 175/* 176 * Find the string descriptor having the given id, validate it, and 177 * allocate a duplicate copy of it. The duplicate has an extra byte 178 * which guarantees the returned string is NUL-terminated. 179 * 180 * String index 0 is valid (it represents "no string"), and for 181 * that a null pointer is returned. 182 * 183 * Otherwise returns a pointer to a newly-allocated copy of the 184 * descriptor string, or an error-coded pointer on failure. 185 */ 186static char *gb_string_get(struct gb_interface *intf, u8 string_id) 187{ 188 struct greybus_descriptor_string *desc_string; 189 struct manifest_desc *descriptor; 190 bool found = false; 191 char *string; 192 193 /* A zero string id means no string (but no error) */ 194 if (!string_id) 195 return NULL; 196 197 list_for_each_entry(descriptor, &intf->manifest_descs, links) { 198 if (descriptor->type != GREYBUS_TYPE_STRING) 199 continue; 200 201 desc_string = descriptor->data; 202 if (desc_string->id == string_id) { 203 found = true; 204 break; 205 } 206 } 207 if (!found) 208 return ERR_PTR(-ENOENT); 209 210 /* Allocate an extra byte so we can guarantee it's NUL-terminated */ 211 string = kmemdup(&desc_string->string, desc_string->length + 1, 212 GFP_KERNEL); 213 if (!string) 214 return ERR_PTR(-ENOMEM); 215 string[desc_string->length] = '\0'; 216 217 /* Ok we've used this string, so we're done with it */ 218 release_manifest_descriptor(descriptor); 219 220 return string; 221} 222 223/* 224 * Find cport descriptors in the manifest associated with the given 225 * bundle, and set up data structures for the functions that use 226 * them. Returns the number of cports set up for the bundle, or 0 227 * if there is an error. 228 */ 229static u32 gb_manifest_parse_cports(struct gb_bundle *bundle) 230{ 231 struct gb_interface *intf = bundle->intf; 232 struct greybus_descriptor_cport *desc_cport; 233 struct manifest_desc *desc, *next, *tmp; 234 LIST_HEAD(list); 235 u8 bundle_id = bundle->id; 236 u16 cport_id; 237 u32 count = 0; 238 int i; 239 240 /* Set up all cport descriptors associated with this bundle */ 241 list_for_each_entry_safe(desc, next, &intf->manifest_descs, links) { 242 if (desc->type != GREYBUS_TYPE_CPORT) 243 continue; 244 245 desc_cport = desc->data; 246 if (desc_cport->bundle != bundle_id) 247 continue; 248 249 cport_id = le16_to_cpu(desc_cport->id); 250 if (cport_id > CPORT_ID_MAX) 251 goto exit; 252 253 /* Nothing else should have its cport_id as control cport id */ 254 if (cport_id == GB_CONTROL_CPORT_ID) { 255 dev_err(&bundle->dev, "invalid cport id found (%02u)\n", 256 cport_id); 257 goto exit; 258 } 259 260 /* 261 * Found one, move it to our temporary list after checking for 262 * duplicates. 263 */ 264 list_for_each_entry(tmp, &list, links) { 265 desc_cport = tmp->data; 266 if (cport_id == le16_to_cpu(desc_cport->id)) { 267 dev_err(&bundle->dev, 268 "duplicate CPort %u found\n", 269 cport_id); 270 goto exit; 271 } 272 } 273 list_move_tail(&desc->links, &list); 274 count++; 275 } 276 277 if (!count) 278 return 0; 279 280 bundle->cport_desc = kcalloc(count, sizeof(*bundle->cport_desc), 281 GFP_KERNEL); 282 if (!bundle->cport_desc) 283 goto exit; 284 285 bundle->num_cports = count; 286 287 i = 0; 288 list_for_each_entry_safe(desc, next, &list, links) { 289 desc_cport = desc->data; 290 memcpy(&bundle->cport_desc[i++], desc_cport, 291 sizeof(*desc_cport)); 292 293 /* Release the cport descriptor */ 294 release_manifest_descriptor(desc); 295 } 296 297 return count; 298exit: 299 release_cport_descriptors(&list, bundle_id); 300 /* 301 * Free all cports for this bundle to avoid 'excess descriptors' 302 * warnings. 303 */ 304 release_cport_descriptors(&intf->manifest_descs, bundle_id); 305 306 return 0; /* Error; count should also be 0 */ 307} 308 309/* 310 * Find bundle descriptors in the manifest and set up their data 311 * structures. Returns the number of bundles set up for the 312 * given interface. 313 */ 314static u32 gb_manifest_parse_bundles(struct gb_interface *intf) 315{ 316 struct manifest_desc *desc; 317 struct gb_bundle *bundle; 318 struct gb_bundle *bundle_next; 319 u32 count = 0; 320 u8 bundle_id; 321 u8 class; 322 323 while ((desc = get_next_bundle_desc(intf))) { 324 struct greybus_descriptor_bundle *desc_bundle; 325 326 /* Found one. Set up its bundle structure*/ 327 desc_bundle = desc->data; 328 bundle_id = desc_bundle->id; 329 class = desc_bundle->class; 330 331 /* Done with this bundle descriptor */ 332 release_manifest_descriptor(desc); 333 334 /* Ignore any legacy control bundles */ 335 if (bundle_id == GB_CONTROL_BUNDLE_ID) { 336 dev_dbg(&intf->dev, "%s - ignoring control bundle\n", 337 __func__); 338 release_cport_descriptors(&intf->manifest_descs, 339 bundle_id); 340 continue; 341 } 342 343 /* Nothing else should have its class set to control class */ 344 if (class == GREYBUS_CLASS_CONTROL) { 345 dev_err(&intf->dev, 346 "bundle %u cannot use control class\n", 347 bundle_id); 348 goto cleanup; 349 } 350 351 bundle = gb_bundle_create(intf, bundle_id, class); 352 if (!bundle) 353 goto cleanup; 354 355 /* 356 * Now go set up this bundle's functions and cports. 357 * 358 * A 'bundle' represents a device in greybus. It may require 359 * multiple cports for its functioning. If we fail to setup any 360 * cport of a bundle, we better reject the complete bundle as 361 * the device may not be able to function properly then. 362 * 363 * But, failing to setup a cport of bundle X doesn't mean that 364 * the device corresponding to bundle Y will not work properly. 365 * Bundles should be treated as separate independent devices. 366 * 367 * While parsing manifest for an interface, treat bundles as 368 * separate entities and don't reject entire interface and its 369 * bundles on failing to initialize a cport. But make sure the 370 * bundle which needs the cport, gets destroyed properly. 371 */ 372 if (!gb_manifest_parse_cports(bundle)) { 373 gb_bundle_destroy(bundle); 374 continue; 375 } 376 377 count++; 378 } 379 380 return count; 381cleanup: 382 /* An error occurred; undo any changes we've made */ 383 list_for_each_entry_safe(bundle, bundle_next, &intf->bundles, links) { 384 gb_bundle_destroy(bundle); 385 count--; 386 } 387 return 0; /* Error; count should also be 0 */ 388} 389 390static bool gb_manifest_parse_interface(struct gb_interface *intf, 391 struct manifest_desc *interface_desc) 392{ 393 struct greybus_descriptor_interface *desc_intf = interface_desc->data; 394 struct gb_control *control = intf->control; 395 char *str; 396 397 /* Handle the strings first--they can fail */ 398 str = gb_string_get(intf, desc_intf->vendor_stringid); 399 if (IS_ERR(str)) 400 return false; 401 control->vendor_string = str; 402 403 str = gb_string_get(intf, desc_intf->product_stringid); 404 if (IS_ERR(str)) 405 goto out_free_vendor_string; 406 control->product_string = str; 407 408 /* Assign feature flags communicated via manifest */ 409 intf->features = desc_intf->features; 410 411 /* Release the interface descriptor, now that we're done with it */ 412 release_manifest_descriptor(interface_desc); 413 414 /* An interface must have at least one bundle descriptor */ 415 if (!gb_manifest_parse_bundles(intf)) { 416 dev_err(&intf->dev, "manifest bundle descriptors not valid\n"); 417 goto out_err; 418 } 419 420 return true; 421out_err: 422 kfree(control->product_string); 423 control->product_string = NULL; 424out_free_vendor_string: 425 kfree(control->vendor_string); 426 control->vendor_string = NULL; 427 428 return false; 429} 430 431/* 432 * Parse a buffer containing an interface manifest. 433 * 434 * If we find anything wrong with the content/format of the buffer 435 * we reject it. 436 * 437 * The first requirement is that the manifest's version is 438 * one we can parse. 439 * 440 * We make an initial pass through the buffer and identify all of 441 * the descriptors it contains, keeping track for each its type 442 * and the location size of its data in the buffer. 443 * 444 * Next we scan the descriptors, looking for an interface descriptor; 445 * there must be exactly one of those. When found, we record the 446 * information it contains, and then remove that descriptor (and any 447 * string descriptors it refers to) from further consideration. 448 * 449 * After that we look for the interface's bundles--there must be at 450 * least one of those. 451 * 452 * Returns true if parsing was successful, false otherwise. 453 */ 454bool gb_manifest_parse(struct gb_interface *intf, void *data, size_t size) 455{ 456 struct greybus_manifest *manifest; 457 struct greybus_manifest_header *header; 458 struct greybus_descriptor *desc; 459 struct manifest_desc *descriptor; 460 struct manifest_desc *interface_desc = NULL; 461 u16 manifest_size; 462 u32 found = 0; 463 bool result; 464 465 /* Manifest descriptor list should be empty here */ 466 if (WARN_ON(!list_empty(&intf->manifest_descs))) 467 return false; 468 469 /* we have to have at _least_ the manifest header */ 470 if (size < sizeof(*header)) { 471 dev_err(&intf->dev, "short manifest (%zu < %zu)\n", 472 size, sizeof(*header)); 473 return false; 474 } 475 476 /* Make sure the size is right */ 477 manifest = data; 478 header = &manifest->header; 479 manifest_size = le16_to_cpu(header->size); 480 if (manifest_size != size) { 481 dev_err(&intf->dev, "manifest size mismatch (%zu != %u)\n", 482 size, manifest_size); 483 return false; 484 } 485 486 /* Validate major/minor number */ 487 if (header->version_major > GREYBUS_VERSION_MAJOR) { 488 dev_err(&intf->dev, "manifest version too new (%u.%u > %u.%u)\n", 489 header->version_major, header->version_minor, 490 GREYBUS_VERSION_MAJOR, GREYBUS_VERSION_MINOR); 491 return false; 492 } 493 494 /* OK, find all the descriptors */ 495 desc = manifest->descriptors; 496 size -= sizeof(*header); 497 while (size) { 498 int desc_size; 499 500 desc_size = identify_descriptor(intf, desc, size); 501 if (desc_size < 0) { 502 result = false; 503 goto out; 504 } 505 desc = (struct greybus_descriptor *)((char *)desc + desc_size); 506 size -= desc_size; 507 } 508 509 /* There must be a single interface descriptor */ 510 list_for_each_entry(descriptor, &intf->manifest_descs, links) { 511 if (descriptor->type == GREYBUS_TYPE_INTERFACE) 512 if (!found++) 513 interface_desc = descriptor; 514 } 515 if (found != 1) { 516 dev_err(&intf->dev, "manifest must have 1 interface descriptor (%u found)\n", 517 found); 518 result = false; 519 goto out; 520 } 521 522 /* Parse the manifest, starting with the interface descriptor */ 523 result = gb_manifest_parse_interface(intf, interface_desc); 524 525 /* 526 * We really should have no remaining descriptors, but we 527 * don't know what newer format manifests might leave. 528 */ 529 if (result && !list_empty(&intf->manifest_descs)) 530 dev_info(&intf->dev, "excess descriptors in interface manifest\n"); 531out: 532 release_manifest_descriptors(intf); 533 534 return result; 535}