int ia64_esi_call()

in kernel/esi.c [88:137]


int ia64_esi_call (efi_guid_t guid, struct ia64_sal_retval *isrvp,
		   enum esi_proc_type proc_type, u64 func,
		   u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6,
		   u64 arg7)
{
	struct ia64_fpreg fr[6];
	unsigned long flags = 0;
	int i;
	char *p;

	if (!esi_systab)
		return -1;

	p = (char *) (esi_systab + 1);
	for (i = 0; i < esi_systab->entry_count; i++) {
		if (*p == ESI_DESC_ENTRY_POINT) {
			ia64_esi_desc_entry_point_t *esi = (void *)p;
			if (!efi_guidcmp(guid, esi->guid)) {
				ia64_sal_handler esi_proc;
				struct pdesc pdesc;

				pdesc.addr = __va(esi->esi_proc);
				pdesc.gp = __va(esi->gp);

				esi_proc = (ia64_sal_handler) &pdesc;

				ia64_save_scratch_fpregs(fr);
				if (proc_type == ESI_PROC_SERIALIZED)
					spin_lock_irqsave(&sal_lock, flags);
				else if (proc_type == ESI_PROC_MP_SAFE)
					local_irq_save(flags);
				else
					preempt_disable();
				*isrvp = (*esi_proc)(func, arg1, arg2, arg3,
						     arg4, arg5, arg6, arg7);
				if (proc_type == ESI_PROC_SERIALIZED)
					spin_unlock_irqrestore(&sal_lock,
							       flags);
				else if (proc_type == ESI_PROC_MP_SAFE)
					local_irq_restore(flags);
				else
					preempt_enable();
				ia64_load_scratch_fpregs(fr);
				return 0;
			}
		}
		p += ESI_DESC_SIZE(*p);
	}
	return -1;
}