summaryrefslogtreecommitdiffstats
path: root/kernel/include/linux/assoc_array.h
blob: a89df3be16863302dcedde84da6f0dbc278fde8c (plain)
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
/* Generic associative array implementation.
 *
 * See Documentation/assoc_array.txt for information.
 *
 * Copyright (C) 2013 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public Licence
 * as published by the Free Software Foundation; either version
 * 2 of the Licence, or (at your option) any later version.
 */

#ifndef _LINUX_ASSOC_ARRAY_H
#define _LINUX_ASSOC_ARRAY_H

#ifdef CONFIG_ASSOCIATIVE_ARRAY

#include <linux/types.h>

#define ASSOC_ARRAY_KEY_CHUNK_SIZE BITS_PER_LONG /* Key data retrieved in chunks of this size */

/*
 * Generic associative array.
 */
struct assoc_array {
	struct assoc_array_ptr	*root;		/* The node at the root of the tree */
	unsigned long		nr_leaves_on_tree;
};

/*
 * Operations on objects and index keys for use by array manipulation routines.
 */
struct assoc_array_ops {
	/* Method to get a chunk of an index key from caller-supplied data */
	unsigned long (*get_key_chunk)(const void *index_key, int level);

	/* Method to get a piece of an object's index key */
	unsigned long (*get_object_key_chunk)(const void *object, int level);

	/* Is this the object we're looking for? */
	bool (*compare_object)(const void *object, const void *index_key);

	/* How different is an object from an index key, to a bit position in
	 * their keys? (or -1 if they're the same)
	 */
	int (*diff_objects)(const void *object, const void *index_key);

	/* Method to free an object. */
	void (*free_object)(void *object);
};

/*
 * Access and manipulation functions.
 */
struct assoc_array_edit;

static inline void assoc_array_init(struct assoc_array *array)
{
	array->root = NULL;
	array->nr_leaves_on_tree = 0;
}

extern int assoc_array_iterate(const struct assoc_array *array,
			       int (*iterator)(const void *object,
					       void *iterator_data),
			       void *iterator_data);
extern void *assoc_array_find(const struct assoc_array *array,
			      const struct assoc_array_ops *ops,
			      const void *index_key);
extern void assoc_array_destroy(struct assoc_array *array,
				const struct assoc_array_ops *ops);
extern struct assoc_array_edit *assoc_array_insert(struct assoc_array *array,
						   const struct assoc_array_ops *ops,
						   const void *index_key,
						   void *object);
extern void assoc_array_insert_set_object(struct assoc_array_edit *edit,
					  void *object);
extern struct assoc_array_edit *assoc_array_delete(struct assoc_array *array,
						   const struct assoc_array_ops *ops,
						   const void *index_key);
extern struct assoc_array_edit *assoc_array_clear(struct assoc_array *array,
						  const struct assoc_array_ops *ops);
extern void assoc_array_apply_edit(struct assoc_array_edit *edit);
extern void assoc_array_cancel_edit(struct assoc_array_edit *edit);
extern int assoc_array_gc(struct assoc_array *array,
			  const struct assoc_array_ops *ops,
			  bool (*iterator)(void *object, void *iterator_data),
			  void *iterator_data);

#endif /* CONFIG_ASSOCIATIVE_ARRAY */
#endif /* _LINUX_ASSOC_ARRAY_H */
lass="n">rsparm); void (*incomp) (void *state, struct sk_buff *in,int proto); void (*stat) (void *state, struct compstat *stats); }; extern int isdn_ppp_register_compressor(struct isdn_ppp_compressor *); extern int isdn_ppp_unregister_compressor(struct isdn_ppp_compressor *); extern int isdn_ppp_dial_slave(char *); extern int isdn_ppp_hangup_slave(char *); typedef struct { unsigned long seqerrs; unsigned long frame_drops; unsigned long overflows; unsigned long max_queue_len; } isdn_mppp_stats; typedef struct { int mp_mrru; /* unused */ struct sk_buff * frags; /* fragments sl list -- use skb->next */ long frames; /* number of frames in the frame list */ unsigned int seq; /* last processed packet seq #: any packets * with smaller seq # will be dropped * unconditionally */ spinlock_t lock; int ref_ct; /* statistics */ isdn_mppp_stats stats; } ippp_bundle; #define NUM_RCV_BUFFS 64 struct ippp_buf_queue { struct ippp_buf_queue *next; struct ippp_buf_queue *last; char *buf; /* NULL here indicates end of queue */ int len; }; /* The data structure for one CCP reset transaction */ enum ippp_ccp_reset_states { CCPResetIdle, CCPResetSentReq, CCPResetRcvdReq, CCPResetSentAck, CCPResetRcvdAck }; struct ippp_ccp_reset_state { enum ippp_ccp_reset_states state; /* State of this transaction */ struct ippp_struct *is; /* Backlink to device stuff */ unsigned char id; /* Backlink id index */ unsigned char ta:1; /* The timer is active (flag) */ unsigned char expra:1; /* We expect a ResetAck at all */ int dlen; /* Databytes stored in data */ struct timer_list timer; /* For timeouts/retries */ /* This is a hack but seems sufficient for the moment. We do not want to have this be yet another allocation for some bytes, it is more memory management overhead than the whole mess is worth. */ unsigned char data[IPPP_RESET_MAXDATABYTES]; }; /* The data structure keeping track of the currently outstanding CCP Reset transactions. */ struct ippp_ccp_reset { struct ippp_ccp_reset_state *rs[256]; /* One per possible id */ unsigned char lastid; /* Last id allocated by the engine */ }; struct ippp_struct { struct ippp_struct *next_link; int state; spinlock_t buflock; struct ippp_buf_queue rq[NUM_RCV_BUFFS]; /* packet queue for isdn_ppp_read() */ struct ippp_buf_queue *first; /* pointer to (current) first packet */ struct ippp_buf_queue *last; /* pointer to (current) last used packet in queue */ wait_queue_head_t wq; struct task_struct *tk; unsigned int mpppcfg; unsigned int pppcfg; unsigned int mru; unsigned int mpmru; unsigned int mpmtu; unsigned int maxcid; struct isdn_net_local_s *lp; int unit; int minor; unsigned int last_link_seqno; long mp_seqno; #ifdef CONFIG_ISDN_PPP_VJ unsigned char *cbuf; struct slcompress *slcomp; #endif #ifdef CONFIG_IPPP_FILTER struct bpf_prog *pass_filter; /* filter for packets to pass */ struct bpf_prog *active_filter; /* filter for pkts to reset idle */ #endif unsigned long debug; struct isdn_ppp_compressor *compressor,*decompressor; struct isdn_ppp_compressor *link_compressor,*link_decompressor; void *decomp_stat,*comp_stat,*link_decomp_stat,*link_comp_stat; struct ippp_ccp_reset *reset; /* Allocated on demand, may never be needed */ unsigned long compflags; }; #endif /* _LINUX_ISDN_PPP_H */