| 307 | } |
| 308 | |
| 309 | int cb_parse_header(void *addr, int len, struct sysinfo_t *info) |
| 310 | { |
| 311 | struct cb_header *header; |
| 312 | unsigned char *ptr = addr; |
| 313 | void *forward; |
| 314 | int i; |
| 315 | |
| 316 | for (i = 0; i < len; i += 16, ptr += 16) { |
| 317 | header = (struct cb_header *)ptr; |
| 318 | if (!strncmp((const char *)header->signature, "LBIO", 4)) |
| 319 | break; |
| 320 | } |
| 321 | |
| 322 | /* We walked the entire space and didn't find anything. */ |
| 323 | if (i >= len) |
| 324 | return -1; |
| 325 | |
| 326 | /* Make sure the checksums match. */ |
| 327 | if (ipchksum((u16 *) header, sizeof(*header)) != 0) |
| 328 | return -1; |
| 329 | |
| 330 | if (!header->table_bytes) |
| 331 | return 0; |
| 332 | |
| 333 | if (ipchksum((u16 *) (ptr + sizeof(*header)), |
| 334 | header->table_bytes) != header->table_checksum) |
| 335 | return -1; |
| 336 | |
| 337 | info->cb_header = virt_to_phys(header); |
| 338 | |
| 339 | /* Initialize IDs as undefined in case they don't show up in table. */ |
| 340 | info->board_id = UNDEFINED_STRAPPING_ID; |
| 341 | info->ram_code = UNDEFINED_STRAPPING_ID; |
| 342 | info->sku_id = UNDEFINED_STRAPPING_ID; |
| 343 | info->fw_config = UNDEFINED_FW_CONFIG; |
| 344 | |
| 345 | /* Now, walk the tables. */ |
| 346 | ptr += header->header_bytes; |
| 347 | |
| 348 | for (i = 0; i < header->table_entries; i++) { |
| 349 | struct cb_record *rec = (struct cb_record *)ptr; |
| 350 | |
| 351 | /* We only care about a few tags here (maybe more later). */ |
| 352 | switch (rec->tag) { |
| 353 | case CB_TAG_FORWARD: |
| 354 | forward = phys_to_virt((void *)(unsigned long) |
| 355 | ((struct cb_forward *)rec)->forward); |
| 356 | return cb_parse_header(forward, len, info); |
| 357 | case CB_TAG_MEMORY: |
| 358 | cb_parse_memory(ptr, info); |
| 359 | break; |
| 360 | case CB_TAG_SERIAL: |
| 361 | cb_parse_serial(ptr, info); |
| 362 | break; |
| 363 | case CB_TAG_VERSION: |
| 364 | cb_parse_string(ptr, &info->cb_version); |
| 365 | break; |
| 366 | case CB_TAG_EXTRA_VERSION: |
no test coverage detected