drivers/s390/char/keyboard.c

Source file repositories/reference/linux-study-clean/drivers/s390/char/keyboard.c

File Facts

System
Linux kernel
Corpus path
drivers/s390/char/keyboard.c
Extension
.c
Size
13245 bytes
Lines
581
Domain
Driver Families
Bucket
drivers/s390
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (ebc_key_maps[i]) {
			kbd->key_maps[i] = kmemdup(ebc_key_maps[i],
						   sizeof(u_short) * NR_KEYS,
						   GFP_KERNEL);
			if (!kbd->key_maps[i])
				goto out_maps;
		}
	}
	kbd->func_table = kzalloc(sizeof(ebc_func_table), GFP_KERNEL);
	if (!kbd->func_table)
		goto out_maps;
	for (i = 0; i < ARRAY_SIZE(ebc_func_table); i++) {
		if (ebc_func_table[i]) {
			kbd->func_table[i] = kstrdup(ebc_func_table[i],
						     GFP_KERNEL);
			if (!kbd->func_table[i])
				goto out_func;
		}
	}
	kbd->fn_handler =
		kzalloc_objs(fn_handler_fn *, NR_FN_HANDLER);
	if (!kbd->fn_handler)
		goto out_func;
	kbd->accent_table = kmemdup(ebc_accent_table,
				    sizeof(struct kbdiacruc) * MAX_DIACR,
				    GFP_KERNEL);
	if (!kbd->accent_table)
		goto out_fn_handler;
	kbd->accent_table_size = ebc_accent_table_size;
	return kbd;

out_fn_handler:
	kfree(kbd->fn_handler);
out_func:
	for (i = 0; i < ARRAY_SIZE(ebc_func_table); i++)
		kfree(kbd->func_table[i]);
	kfree(kbd->func_table);
out_maps:
	for (i = 0; i < ARRAY_SIZE(ebc_key_maps); i++)
		kfree(kbd->key_maps[i]);
	kfree(kbd->key_maps);
out_kbd:
	kfree(kbd);
out:
	return NULL;
}

void
kbd_free(struct kbd_data *kbd)
{
	int i;

	kfree(kbd->accent_table);
	kfree(kbd->fn_handler);
	for (i = 0; i < ARRAY_SIZE(ebc_func_table); i++)
		kfree(kbd->func_table[i]);
	kfree(kbd->func_table);
	for (i = 0; i < ARRAY_SIZE(ebc_key_maps); i++)
		kfree(kbd->key_maps[i]);
	kfree(kbd->key_maps);
	kfree(kbd);
}

/*
 * Generate ascii -> ebcdic translation table from kbd_data.
 */
void
kbd_ascebc(struct kbd_data *kbd, unsigned char *ascebc)
{
	unsigned short *keymap, keysym;
	int i, j, k;

	memset(ascebc, 0x40, 256);
	for (i = 0; i < ARRAY_SIZE(ebc_key_maps); i++) {
		keymap = kbd->key_maps[i];
		if (!keymap)
			continue;
		for (j = 0; j < NR_KEYS; j++) {
			k = ((i & 1) << 7) + j;
			keysym = keymap[j];
			if (KTYP(keysym) == (KT_LATIN | 0xf0) ||
			    KTYP(keysym) == (KT_LETTER | 0xf0))
				ascebc[KVAL(keysym)] = k;
			else if (KTYP(keysym) == (KT_DEAD | 0xf0))
				ascebc[ret_diacr[KVAL(keysym)]] = k;
		}
	}
}

#if 0

Annotation

Implementation Notes