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