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