static int sbp2_scan_unit_dir()

in sbp2.c [1017:1066]


static int sbp2_scan_unit_dir(struct sbp2_target *tgt, const u32 *directory,
			      u32 *model, u32 *firmware_revision)
{
	struct fw_csr_iterator ci;
	int key, value;

	fw_csr_iterator_init(&ci, directory);
	while (fw_csr_iterator_next(&ci, &key, &value)) {
		switch (key) {

		case CSR_DEPENDENT_INFO | CSR_OFFSET:
			tgt->management_agent_address =
					CSR_REGISTER_BASE + 4 * value;
			break;

		case CSR_DIRECTORY_ID:
			tgt->directory_id = value;
			break;

		case CSR_MODEL:
			*model = value;
			break;

		case SBP2_CSR_FIRMWARE_REVISION:
			*firmware_revision = value;
			break;

		case SBP2_CSR_UNIT_CHARACTERISTICS:
			/* the timeout value is stored in 500ms units */
			tgt->mgt_orb_timeout = (value >> 8 & 0xff) * 500;
			break;

		case SBP2_CSR_LOGICAL_UNIT_NUMBER:
			if (sbp2_add_logical_unit(tgt, value) < 0)
				return -ENOMEM;
			break;

		case SBP2_CSR_UNIT_UNIQUE_ID:
			sbp2_get_unit_unique_id(tgt, ci.p - 1 + value);
			break;

		case SBP2_CSR_LOGICAL_UNIT_DIRECTORY:
			/* Adjust for the increment in the iterator */
			if (sbp2_scan_logical_unit_dir(tgt, ci.p - 1 + value) < 0)
				return -ENOMEM;
			break;
		}
	}
	return 0;
}