1/**
2 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3 *
4 * This source file is released under GPL v2 license (no other versions).
5 * See the COPYING file included in the main directory of this source
6 * distribution for the license terms and conditions.
7 *
8 * @File	ctimap.c
9 *
10 * @Brief
11 * This file contains the implementation of generic input mapper operations
12 * for input mapper management.
13 *
14 * @Author	Liu Chun
15 * @Date 	May 23 2008
16 *
17 */
18
19#include "ctimap.h"
20#include <linux/slab.h>
21
22int input_mapper_add(struct list_head *mappers, struct imapper *entry,
23		     int (*map_op)(void *, struct imapper *), void *data)
24{
25	struct list_head *pos, *pre, *head;
26	struct imapper *pre_ent, *pos_ent;
27
28	head = mappers;
29
30	if (list_empty(head)) {
31		entry->next = entry->addr;
32		map_op(data, entry);
33		list_add(&entry->list, head);
34		return 0;
35	}
36
37	list_for_each(pos, head) {
38		pos_ent = list_entry(pos, struct imapper, list);
39		if (pos_ent->slot > entry->slot) {
40			/* found a position in list */
41			break;
42		}
43	}
44
45	if (pos != head) {
46		pre = pos->prev;
47		if (pre == head)
48			pre = head->prev;
49
50		__list_add(&entry->list, pos->prev, pos);
51	} else {
52		pre = head->prev;
53		pos = head->next;
54		list_add_tail(&entry->list, head);
55	}
56
57	pre_ent = list_entry(pre, struct imapper, list);
58	pos_ent = list_entry(pos, struct imapper, list);
59
60	entry->next = pos_ent->addr;
61	map_op(data, entry);
62	pre_ent->next = entry->addr;
63	map_op(data, pre_ent);
64
65	return 0;
66}
67
68int input_mapper_delete(struct list_head *mappers, struct imapper *entry,
69		     int (*map_op)(void *, struct imapper *), void *data)
70{
71	struct list_head *next, *pre, *head;
72	struct imapper *pre_ent, *next_ent;
73
74	head = mappers;
75
76	if (list_empty(head))
77		return 0;
78
79	pre = (entry->list.prev == head) ? head->prev : entry->list.prev;
80	next = (entry->list.next == head) ? head->next : entry->list.next;
81
82	if (pre == &entry->list) {
83		/* entry is the only one node in mappers list */
84		entry->next = entry->addr = entry->user = entry->slot = 0;
85		map_op(data, entry);
86		list_del(&entry->list);
87		return 0;
88	}
89
90	pre_ent = list_entry(pre, struct imapper, list);
91	next_ent = list_entry(next, struct imapper, list);
92
93	pre_ent->next = next_ent->addr;
94	map_op(data, pre_ent);
95	list_del(&entry->list);
96
97	return 0;
98}
99
100void free_input_mapper_list(struct list_head *head)
101{
102	struct imapper *entry;
103	struct list_head *pos;
104
105	while (!list_empty(head)) {
106		pos = head->next;
107		list_del(pos);
108		entry = list_entry(pos, struct imapper, list);
109		kfree(entry);
110	}
111}
112
113