usb_list.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. /**
  2. * @file usb_list.h
  3. * @brief
  4. *
  5. * Copyright (c) 2022 sakumisu
  6. *
  7. * Licensed to the Apache Software Foundation (ASF) under one or more
  8. * contributor license agreements. See the NOTICE file distributed with
  9. * this work for additional information regarding copyright ownership. The
  10. * ASF licenses this file to you under the Apache License, Version 2.0 (the
  11. * "License"); you may not use this file except in compliance with the
  12. * License. You may obtain a copy of the License at
  13. *
  14. * http://www.apache.org/licenses/LICENSE-2.0
  15. *
  16. * Unless required by applicable law or agreed to in writing, software
  17. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  18. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  19. * License for the specific language governing permissions and limitations
  20. * under the License.
  21. *
  22. */
  23. #ifndef __USB_LIST_H__
  24. #define __USB_LIST_H__
  25. #include <string.h>
  26. #include <stdint.h>
  27. #ifdef __cplusplus
  28. extern "C" {
  29. #endif
  30. /**
  31. * usb_container_of - return the member address of ptr, if the type of ptr is the
  32. * struct type.
  33. */
  34. #define usb_container_of(ptr, type, member) \
  35. ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
  36. /**
  37. * Single List structure
  38. */
  39. struct usb_slist_node {
  40. struct usb_slist_node *next; /**< point to next node. */
  41. };
  42. typedef struct usb_slist_node usb_slist_t; /**< Type for single list. */
  43. /**
  44. * @brief initialize a single list
  45. *
  46. * @param l the single list to be initialized
  47. */
  48. static inline void usb_slist_init(usb_slist_t *l)
  49. {
  50. l->next = NULL;
  51. }
  52. static inline void usb_slist_add_head(usb_slist_t *l, usb_slist_t *n)
  53. {
  54. n->next = l->next;
  55. l->next = n;
  56. }
  57. static inline void usb_slist_add_tail(usb_slist_t *l, usb_slist_t *n)
  58. {
  59. while (l->next) {
  60. l = l->next;
  61. }
  62. /* append the node to the tail */
  63. l->next = n;
  64. n->next = NULL;
  65. }
  66. static inline void usb_slist_insert(usb_slist_t *l, usb_slist_t *next, usb_slist_t *n)
  67. {
  68. if (!next) {
  69. usb_slist_add_tail(next, l);
  70. return;
  71. }
  72. while (l->next) {
  73. if (l->next == next) {
  74. l->next = n;
  75. n->next = next;
  76. }
  77. l = l->next;
  78. }
  79. }
  80. static inline usb_slist_t *usb_slist_remove(usb_slist_t *l, usb_slist_t *n)
  81. {
  82. /* remove slist head */
  83. while (l->next && l->next != n) {
  84. l = l->next;
  85. }
  86. /* remove node */
  87. if (l->next != (usb_slist_t *)0) {
  88. l->next = l->next->next;
  89. }
  90. return l;
  91. }
  92. static inline unsigned int usb_slist_len(const usb_slist_t *l)
  93. {
  94. unsigned int len = 0;
  95. const usb_slist_t *list = l->next;
  96. while (list != NULL) {
  97. list = list->next;
  98. len++;
  99. }
  100. return len;
  101. }
  102. static inline unsigned int usb_slist_contains(usb_slist_t *l, usb_slist_t *n)
  103. {
  104. while (l->next) {
  105. if (l->next == n) {
  106. return 0;
  107. }
  108. l = l->next;
  109. }
  110. return 1;
  111. }
  112. static inline usb_slist_t *usb_slist_head(usb_slist_t *l)
  113. {
  114. return l->next;
  115. }
  116. static inline usb_slist_t *usb_slist_tail(usb_slist_t *l)
  117. {
  118. while (l->next) {
  119. l = l->next;
  120. }
  121. return l;
  122. }
  123. static inline usb_slist_t *usb_slist_next(usb_slist_t *n)
  124. {
  125. return n->next;
  126. }
  127. static inline int usb_slist_isempty(usb_slist_t *l)
  128. {
  129. return l->next == NULL;
  130. }
  131. /**
  132. * @brief initialize a slist object
  133. */
  134. #define USB_SLIST_OBJECT_INIT(object) \
  135. { \
  136. NULL \
  137. }
  138. /**
  139. * @brief initialize a slist object
  140. */
  141. #define USB_SLIST_DEFINE(slist) \
  142. usb_slist_t slist = { NULL }
  143. /**
  144. * @brief get the struct for this single list node
  145. * @param node the entry point
  146. * @param type the type of structure
  147. * @param member the name of list in structure
  148. */
  149. #define usb_slist_entry(node, type, member) \
  150. usb_container_of(node, type, member)
  151. /**
  152. * usb_slist_first_entry - get the first element from a slist
  153. * @ptr: the slist head to take the element from.
  154. * @type: the type of the struct this is embedded in.
  155. * @member: the name of the slist_struct within the struct.
  156. *
  157. * Note, that slist is expected to be not empty.
  158. */
  159. #define usb_slist_first_entry(ptr, type, member) \
  160. usb_slist_entry((ptr)->next, type, member)
  161. /**
  162. * usb_slist_tail_entry - get the tail element from a slist
  163. * @ptr: the slist head to take the element from.
  164. * @type: the type of the struct this is embedded in.
  165. * @member: the name of the slist_struct within the struct.
  166. *
  167. * Note, that slist is expected to be not empty.
  168. */
  169. #define usb_slist_tail_entry(ptr, type, member) \
  170. usb_slist_entry(usb_slist_tail(ptr), type, member)
  171. /**
  172. * usb_slist_first_entry_or_null - get the first element from a slist
  173. * @ptr: the slist head to take the element from.
  174. * @type: the type of the struct this is embedded in.
  175. * @member: the name of the slist_struct within the struct.
  176. *
  177. * Note, that slist is expected to be not empty.
  178. */
  179. #define usb_slist_first_entry_or_null(ptr, type, member) \
  180. (usb_slist_isempty(ptr) ? NULL : usb_slist_first_entry(ptr, type, member))
  181. /**
  182. * usb_slist_for_each - iterate over a single list
  183. * @pos: the usb_slist_t * to use as a loop cursor.
  184. * @head: the head for your single list.
  185. */
  186. #define usb_slist_for_each(pos, head) \
  187. for (pos = (head)->next; pos != NULL; pos = pos->next)
  188. #define usb_slist_for_each_safe(pos, next, head) \
  189. for (pos = (head)->next, next = pos->next; pos; \
  190. pos = next, next = pos->next)
  191. /**
  192. * usb_slist_for_each_entry - iterate over single list of given type
  193. * @pos: the type * to use as a loop cursor.
  194. * @head: the head for your single list.
  195. * @member: the name of the list_struct within the struct.
  196. */
  197. #define usb_slist_for_each_entry(pos, head, member) \
  198. for (pos = usb_slist_entry((head)->next, typeof(*pos), member); \
  199. &pos->member != (NULL); \
  200. pos = usb_slist_entry(pos->member.next, typeof(*pos), member))
  201. #define usb_slist_for_each_entry_safe(pos, n, head, member) \
  202. for (pos = usb_slist_entry((head)->next, typeof(*pos), member), \
  203. n = usb_slist_entry(pos->member.next, typeof(*pos), member); \
  204. &pos->member != (NULL); \
  205. pos = n, n = usb_slist_entry(pos->member.next, typeof(*pos), member))
  206. /**
  207. * Double List structure
  208. */
  209. struct usb_dlist_node {
  210. struct usb_dlist_node *next; /**< point to next node. */
  211. struct usb_dlist_node *prev; /**< point to prev node. */
  212. };
  213. typedef struct usb_dlist_node usb_dlist_t; /**< Type for lists. */
  214. /**
  215. * @brief initialize a list
  216. *
  217. * @param l list to be initialized
  218. */
  219. static inline void usb_dlist_init(usb_dlist_t *l)
  220. {
  221. l->next = l->prev = l;
  222. }
  223. /**
  224. * @brief insert a node after a list
  225. *
  226. * @param l list to insert it
  227. * @param n new node to be inserted
  228. */
  229. static inline void usb_dlist_insert_after(usb_dlist_t *l, usb_dlist_t *n)
  230. {
  231. l->next->prev = n;
  232. n->next = l->next;
  233. l->next = n;
  234. n->prev = l;
  235. }
  236. /**
  237. * @brief insert a node before a list
  238. *
  239. * @param n new node to be inserted
  240. * @param l list to insert it
  241. */
  242. static inline void usb_dlist_insert_before(usb_dlist_t *l, usb_dlist_t *n)
  243. {
  244. l->prev->next = n;
  245. n->prev = l->prev;
  246. l->prev = n;
  247. n->next = l;
  248. }
  249. /**
  250. * @brief remove node from list.
  251. * @param n the node to remove from the list.
  252. */
  253. static inline void usb_dlist_remove(usb_dlist_t *n)
  254. {
  255. n->next->prev = n->prev;
  256. n->prev->next = n->next;
  257. n->next = n->prev = n;
  258. }
  259. /**
  260. * @brief move node from list.
  261. * @param n the node to remove from the list.
  262. */
  263. static inline void usb_dlist_move_head(usb_dlist_t *l, usb_dlist_t *n)
  264. {
  265. usb_dlist_remove(n);
  266. usb_dlist_insert_after(l, n);
  267. }
  268. /**
  269. * @brief move node from list.
  270. * @param n the node to remove from the list.
  271. */
  272. static inline void usb_dlist_move_tail(usb_dlist_t *l, usb_dlist_t *n)
  273. {
  274. usb_dlist_remove(n);
  275. usb_dlist_insert_before(l, n);
  276. }
  277. /**
  278. * @brief tests whether a list is empty
  279. * @param l the list to test.
  280. */
  281. static inline int usb_dlist_isempty(const usb_dlist_t *l)
  282. {
  283. return l->next == l;
  284. }
  285. /**
  286. * @brief get the list length
  287. * @param l the list to get.
  288. */
  289. static inline unsigned int usb_dlist_len(const usb_dlist_t *l)
  290. {
  291. unsigned int len = 0;
  292. const usb_dlist_t *p = l;
  293. while (p->next != l) {
  294. p = p->next;
  295. len++;
  296. }
  297. return len;
  298. }
  299. /**
  300. * @brief initialize a dlist object
  301. */
  302. #define USB_DLIST_OBJECT_INIT(object) \
  303. { \
  304. &(object), &(object) \
  305. }
  306. /**
  307. * @brief initialize a dlist object
  308. */
  309. #define USB_DLIST_DEFINE(list) \
  310. usb_dlist_t list = { &(list), &(list) }
  311. /**
  312. * @brief get the struct for this entry
  313. * @param node the entry point
  314. * @param type the type of structure
  315. * @param member the name of list in structure
  316. */
  317. #define usb_dlist_entry(node, type, member) \
  318. usb_container_of(node, type, member)
  319. /**
  320. * dlist_first_entry - get the first element from a list
  321. * @ptr: the list head to take the element from.
  322. * @type: the type of the struct this is embedded in.
  323. * @member: the name of the list_struct within the struct.
  324. *
  325. * Note, that list is expected to be not empty.
  326. */
  327. #define usb_dlist_first_entry(ptr, type, member) \
  328. usb_dlist_entry((ptr)->next, type, member)
  329. /**
  330. * dlist_first_entry_or_null - get the first element from a list
  331. * @ptr: the list head to take the element from.
  332. * @type: the type of the struct this is embedded in.
  333. * @member: the name of the list_struct within the struct.
  334. *
  335. * Note, that list is expected to be not empty.
  336. */
  337. #define usb_dlist_first_entry_or_null(ptr, type, member) \
  338. (usb_dlist_isempty(ptr) ? NULL : usb_dlist_first_entry(ptr, type, member))
  339. /**
  340. * usb_dlist_for_each - iterate over a list
  341. * @pos: the usb_dlist_t * to use as a loop cursor.
  342. * @head: the head for your list.
  343. */
  344. #define usb_dlist_for_each(pos, head) \
  345. for (pos = (head)->next; pos != (head); pos = pos->next)
  346. /**
  347. * usb_dlist_for_each_prev - iterate over a list
  348. * @pos: the dlist_t * to use as a loop cursor.
  349. * @head: the head for your list.
  350. */
  351. #define usb_dlist_for_each_prev(pos, head) \
  352. for (pos = (head)->prev; pos != (head); pos = pos->prev)
  353. /**
  354. * usb_dlist_for_each_safe - iterate over a list safe against removal of list entry
  355. * @pos: the dlist_t * to use as a loop cursor.
  356. * @n: another dlist_t * to use as temporary storage
  357. * @head: the head for your list.
  358. */
  359. #define usb_dlist_for_each_safe(pos, n, head) \
  360. for (pos = (head)->next, n = pos->next; pos != (head); \
  361. pos = n, n = pos->next)
  362. #define usb_dlist_for_each_prev_safe(pos, n, head) \
  363. for (pos = (head)->prev, n = pos->prev; pos != (head); \
  364. pos = n, n = pos->prev)
  365. /**
  366. * usb_dlist_for_each_entry - iterate over list of given type
  367. * @pos: the type * to use as a loop cursor.
  368. * @head: the head for your list.
  369. * @member: the name of the list_struct within the struct.
  370. */
  371. #define usb_dlist_for_each_entry(pos, head, member) \
  372. for (pos = usb_dlist_entry((head)->next, typeof(*pos), member); \
  373. &pos->member != (head); \
  374. pos = usb_dlist_entry(pos->member.next, typeof(*pos), member))
  375. /**
  376. * usb_usb_dlist_for_each_entry_reverse - iterate over list of given type
  377. * @pos: the type * to use as a loop cursor.
  378. * @head: the head for your list.
  379. * @member: the name of the list_struct within the struct.
  380. */
  381. #define usb_dlist_for_each_entry_reverse(pos, head, member) \
  382. for (pos = usb_dlist_entry((head)->prev, typeof(*pos), member); \
  383. &pos->member != (head); \
  384. pos = usb_dlist_entry(pos->member.prev, typeof(*pos), member))
  385. /**
  386. * usb_usb_dlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
  387. * @pos: the type * to use as a loop cursor.
  388. * @n: another type * to use as temporary storage
  389. * @head: the head for your list.
  390. * @member: the name of the list_struct within the struct.
  391. */
  392. #define usb_dlist_for_each_entry_safe(pos, n, head, member) \
  393. for (pos = usb_dlist_entry((head)->next, typeof(*pos), member), \
  394. n = usb_dlist_entry(pos->member.next, typeof(*pos), member); \
  395. &pos->member != (head); \
  396. pos = n, n = usb_dlist_entry(n->member.next, typeof(*n), member))
  397. /**
  398. * usb_usb_dlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
  399. * @pos: the type * to use as a loop cursor.
  400. * @n: another type * to use as temporary storage
  401. * @head: the head for your list.
  402. * @member: the name of the list_struct within the struct.
  403. */
  404. #define usb_dlist_for_each_entry_safe_reverse(pos, n, head, member) \
  405. for (pos = usb_dlist_entry((head)->prev, typeof(*pos), field), \
  406. n = usb_dlist_entry(pos->member.prev, typeof(*pos), member); \
  407. &pos->member != (head); \
  408. pos = n, n = usb_dlist_entry(pos->member.prev, typeof(*pos), member))
  409. #ifdef __cplusplus
  410. }
  411. #endif
  412. #endif