static int tb_switch_nvm_add()

in switch.c [384:451]


static int tb_switch_nvm_add(struct tb_switch *sw)
{
	struct tb_nvm *nvm;
	u32 val;
	int ret;

	if (!nvm_readable(sw))
		return 0;

	/*
	 * The NVM format of non-Intel hardware is not known so
	 * currently restrict NVM upgrade for Intel hardware. We may
	 * relax this in the future when we learn other NVM formats.
	 */
	if (sw->config.vendor_id != PCI_VENDOR_ID_INTEL &&
	    sw->config.vendor_id != 0x8087) {
		dev_info(&sw->dev,
			 "NVM format of vendor %#x is not known, disabling NVM upgrade\n",
			 sw->config.vendor_id);
		return 0;
	}

	nvm = tb_nvm_alloc(&sw->dev);
	if (IS_ERR(nvm))
		return PTR_ERR(nvm);

	/*
	 * If the switch is in safe-mode the only accessible portion of
	 * the NVM is the non-active one where userspace is expected to
	 * write new functional NVM.
	 */
	if (!sw->safe_mode) {
		u32 nvm_size, hdr_size;

		ret = nvm_read(sw, NVM_FLASH_SIZE, &val, sizeof(val));
		if (ret)
			goto err_nvm;

		hdr_size = sw->generation < 3 ? SZ_8K : SZ_16K;
		nvm_size = (SZ_1M << (val & 7)) / 8;
		nvm_size = (nvm_size - hdr_size) / 2;

		ret = nvm_read(sw, NVM_VERSION, &val, sizeof(val));
		if (ret)
			goto err_nvm;

		nvm->major = val >> 16;
		nvm->minor = val >> 8;

		ret = tb_nvm_add_active(nvm, nvm_size, tb_switch_nvm_read);
		if (ret)
			goto err_nvm;
	}

	if (!sw->no_nvm_upgrade) {
		ret = tb_nvm_add_non_active(nvm, NVM_MAX_SIZE,
					    tb_switch_nvm_write);
		if (ret)
			goto err_nvm;
	}

	sw->nvm = nvm;
	return 0;

err_nvm:
	tb_nvm_free(nvm);
	return ret;
}