/* Initialize hash table. Should be locked. */ int BCMINITFN(_nvram_init)(void *sih) { struct nvram_header *header; int ret; if (!(header = (struct nvram_header *) MALLOC(si_osh(sih), NVRAM_SPACE))) { printf("nvram_init: out of memory\n"); return -12; /* -ENOMEM */ } #if 0 if ((ret = _nvram_read(header)) == 0 && header->magic == NVRAM_MAGIC) nvram_rehash(header); #else // nvram_rehash - may corrupt correct header _nvram_read(header); if (header->magic != NVRAM_MAGIC) nvram_rehash(header); #endif MFREE(si_osh(sih), header, NVRAM_SPACE); return ret; }
/* Regenerate NVRAM. Should be locked. */ int _nvram_commit(struct nvram_header *header) { // char *init, *config, *refresh, *ncdl; char *ptr, *end; int i; struct nvram_tuple *t; struct nvram_header tmp; uint8 crc; /* Regenerate header */ header->magic = NVRAM_MAGIC; header->crc_ver_init = NVRAM_DEFAULT << NVRAM_OPT_SHIFT | NVRAM_VERSION << NVRAM_VER_SHIFT; /* Clear data area */ ptr = (char *)header + sizeof(struct nvram_header); bzero(ptr, NVRAM_SPACE - sizeof(struct nvram_header)); /* Leave space for a double NUL at the end */ end = (char *)header + NVRAM_SPACE - 2; /* Write out all tuples */ for (i = 0; i < ARRAYSIZE(nvram_hash); i++) { for (t = nvram_hash[i]; t; t = t->next) { if ((ptr + strlen(t->name) + 1 + strlen(t->value) + 1) > end) break; ptr += sprintf(ptr, "%s=%s", t->name, t->value) + 1; } } /* End with a double NUL */ ptr += 2; /* Set new length */ header->len = ROUNDUP(ptr - (char *)header, 4); /* Little-endian CRC8 over the last 11 bytes of the header */ tmp.crc_ver_init = htol32(header->crc_ver_init); tmp.config_refresh = htol32(header->config_refresh); tmp.config_ncdl = htol32(header->config_ncdl); crc = crc8((char *)&tmp + 12, sizeof(struct nvram_header) - 12, CRC8_INIT_VALUE); /* Continue CRC8 over data bytes */ crc = crc8((char *)&header[1], header->len - sizeof(struct nvram_header), crc); /* Set new CRC8 */ header->crc_ver_init |= crc; /* Reinitialize hash table */ return nvram_rehash(header); }
/* Initialize hash table. Should be locked. */ int _nvram_init(void) { struct nvram_header *header; int ret; if (!(header = (struct nvram_header *)MALLOC(NVRAM_SPACE))) { printk(KERN_INFO "nvram_init: out of memory\n"); return -12; /* -ENOMEM */ } if ((ret = _nvram_read(header)) == 0 && header->magic == NVRAM_MAGIC) nvram_rehash(header); MFREE(header, NVRAM_SPACE); return ret; }
/* XXX: not marking as RECLAIMTEXT allows this fucntion to be fc-sectioned out when not referenced */ int BCMINITFN(_nvram_commit)(struct nvram_header *header) { char *ptr, *end; int i; struct nvram_tuple *t; /* Regenerate header */ header->magic = NVRAM_MAGIC; header->crc_ver_init = (NVRAM_VERSION << 8); header->config_refresh = 0; /* for backward compatibility */ header->config_ncdl = 0; /* for backward compatibility */ /* Clear data area */ ptr = (char *) header + sizeof(struct nvram_header); bzero(ptr, NVRAM_SPACE - sizeof(struct nvram_header)); /* Leave space for a double NUL at the end */ end = (char *) header + NVRAM_SPACE - 2; /* Write out all tuples */ for (i = 0; i < ARRAYSIZE(nvram_hash); i++) { for (t = nvram_hash[i]; t; t = t->next) { if ((ptr + strlen(t->name) + 1 + strlen(t->value) + 1) > end) break; ptr += sprintf(ptr, "%s=%s", t->name, t->value) + 1; } } /* End with a double NUL */ ptr += 2; /* Set new length */ header->len = ROUNDUP(ptr - (char *) header, 4); /* Set new CRC8 */ header->crc_ver_init |= nvram_calc_crc(header); /* Reinitialize hash table */ return nvram_rehash(header); }