• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * @file me_slist.c
3  *
4  * @brief Implements the subdevice list class.
5  * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6  * @author Guenter Gebhardt
7  */
8 
9 /*
10  * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11  *
12  * This file is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25  */
26 
27 #include "meerror.h"
28 #include "medefines.h"
29 
30 #include "meslist.h"
31 #include "medebug.h"
32 
me_slist_query_number_subdevices(struct me_slist * slist,int * number)33 int me_slist_query_number_subdevices(struct me_slist *slist, int *number)
34 {
35 	PDEBUG_LOCKS("called.\n");
36 	*number = slist->n;
37 	return ME_ERRNO_SUCCESS;
38 }
39 
me_slist_get_number_subdevices(struct me_slist * slist)40 unsigned int me_slist_get_number_subdevices(struct me_slist *slist)
41 {
42 	PDEBUG_LOCKS("called.\n");
43 	return slist->n;
44 }
45 
me_slist_get_subdevice(struct me_slist * slist,unsigned int index)46 me_subdevice_t *me_slist_get_subdevice(struct me_slist * slist,
47 				       unsigned int index)
48 {
49 
50 	struct list_head *pos;
51 	me_subdevice_t *subdevice = NULL;
52 	unsigned int i = 0;
53 
54 	PDEBUG_LOCKS("called.\n");
55 
56 	if (index >= slist->n) {
57 		PERROR("Index out of range.\n");
58 		return NULL;
59 	}
60 
61 	list_for_each(pos, &slist->head) {
62 		if (i == index) {
63 			subdevice = list_entry(pos, me_subdevice_t, list);
64 			break;
65 		}
66 
67 		++i;
68 	}
69 
70 	return subdevice;
71 }
72 
me_slist_get_subdevice_by_type(struct me_slist * slist,unsigned int start_subdevice,int type,int subtype,int * subdevice)73 int me_slist_get_subdevice_by_type(struct me_slist *slist,
74 				   unsigned int start_subdevice,
75 				   int type, int subtype, int *subdevice)
76 {
77 	me_subdevice_t *pos;
78 	int s_type, s_subtype;
79 	unsigned int index = 0;
80 
81 	PDEBUG_LOCKS("called.\n");
82 
83 	if (start_subdevice >= slist->n) {
84 		PERROR("Start index out of range.\n");
85 		return ME_ERRNO_NOMORE_SUBDEVICE_TYPE;
86 	}
87 
88 	list_for_each_entry(pos, &slist->head, list) {
89 		if (index < start_subdevice) {	// Go forward to start subdevice.
90 			++index;
91 			continue;
92 		}
93 
94 		pos->me_subdevice_query_subdevice_type(pos,
95 						       &s_type, &s_subtype);
96 
97 		if (subtype == ME_SUBTYPE_ANY) {
98 			if (s_type == type)
99 				break;
100 		} else {
101 			if ((s_type == type) && (s_subtype == subtype))
102 				break;
103 		}
104 
105 		++index;
106 	}
107 
108 	if (index >= slist->n) {
109 		return ME_ERRNO_NOMORE_SUBDEVICE_TYPE;
110 	}
111 
112 	*subdevice = index;
113 
114 	return ME_ERRNO_SUCCESS;
115 }
116 
me_slist_add_subdevice_tail(struct me_slist * slist,me_subdevice_t * subdevice)117 void me_slist_add_subdevice_tail(struct me_slist *slist,
118 				 me_subdevice_t * subdevice)
119 {
120 	PDEBUG_LOCKS("called.\n");
121 
122 	list_add_tail(&subdevice->list, &slist->head);
123 	++slist->n;
124 }
125 
me_slist_del_subdevice_tail(struct me_slist * slist)126 me_subdevice_t *me_slist_del_subdevice_tail(struct me_slist *slist)
127 {
128 
129 	struct list_head *last;
130 	me_subdevice_t *subdevice;
131 
132 	PDEBUG_LOCKS("called.\n");
133 
134 	if (list_empty(&slist->head))
135 		return NULL;
136 
137 	last = slist->head.prev;
138 
139 	subdevice = list_entry(last, me_subdevice_t, list);
140 
141 	list_del(last);
142 
143 	--slist->n;
144 
145 	return subdevice;
146 }
147 
me_slist_init(me_slist_t * slist)148 int me_slist_init(me_slist_t * slist)
149 {
150 	PDEBUG_LOCKS("called.\n");
151 
152 	INIT_LIST_HEAD(&slist->head);
153 	slist->n = 0;
154 	return 0;
155 }
156 
me_slist_deinit(me_slist_t * slist)157 void me_slist_deinit(me_slist_t * slist)
158 {
159 
160 	struct list_head *s;
161 	me_subdevice_t *subdevice;
162 
163 	PDEBUG_LOCKS("called.\n");
164 
165 	while (!list_empty(&slist->head)) {
166 		s = slist->head.next;
167 		list_del(s);
168 		subdevice = list_entry(s, me_subdevice_t, list);
169 		subdevice->me_subdevice_destructor(subdevice);
170 	}
171 
172 	slist->n = 0;
173 }
174