16924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi/* 26924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi * libkmod - interface to kernel module operations 36924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi * 4e6b0e49b4ea7937a98b16f23d621244ee1a3e588Lucas De Marchi * Copyright (C) 2011-2013 ProFUSION embedded systems 56924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi * 66924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi * This library is free software; you can redistribute it and/or 76924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi * modify it under the terms of the GNU Lesser General Public 8cb451f35d9fe25ec1dee0628f8af23f022358f6bLucas De Marchi * License as published by the Free Software Foundation; either 9cb451f35d9fe25ec1dee0628f8af23f022358f6bLucas De Marchi * version 2.1 of the License, or (at your option) any later version. 106924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi * 116924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi * This library is distributed in the hope that it will be useful, 126924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi * but WITHOUT ANY WARRANTY; without even the implied warranty of 136924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 146924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi * Lesser General Public License for more details. 156924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi * 166924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi * You should have received a copy of the GNU Lesser General Public 17dea2dfee9b301da84dbb09cf510b8ebf2ef28fffLucas De Marchi * License along with this library; if not, see <http://www.gnu.org/licenses/>. 186924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi */ 196924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 206924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi#include <stdlib.h> 216924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 226924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi#include "libkmod.h" 2383b855a6ed7028173e231eab0a39c929a962ddf5Lucas De Marchi#include "libkmod-internal.h" 246924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 256681951bbeb04f7b5c08e49da81a0da6f2aca2d2Lucas De Marchi/** 266681951bbeb04f7b5c08e49da81a0da6f2aca2d2Lucas De Marchi * SECTION:libkmod-list 276681951bbeb04f7b5c08e49da81a0da6f2aca2d2Lucas De Marchi * @short_description: general purpose list 286681951bbeb04f7b5c08e49da81a0da6f2aca2d2Lucas De Marchi */ 296681951bbeb04f7b5c08e49da81a0da6f2aca2d2Lucas De Marchi 306924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchistatic inline struct list_node *list_node_init(struct list_node *node) 316924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi{ 326924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi node->next = node; 336924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi node->prev = node; 346924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 356924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi return node; 366924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi} 376924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 386924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchistatic inline void list_node_append(struct list_node *list, 396924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi struct list_node *node) 406924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi{ 416924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi if (list == NULL) { 426924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi list_node_init(node); 436924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi return; 446924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi } 456924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 466924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi node->prev = list->prev; 476924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi list->prev->next = node; 486924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi list->prev = node; 496924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi node->next = list; 506924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi} 516924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 526924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchistatic inline struct list_node *list_node_remove(struct list_node *node) 536924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi{ 546924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi if (node->prev == node || node->next == node) 556924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi return NULL; 566924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 576924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi node->prev->next = node->next; 586924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi node->next->prev = node->prev; 596924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 60e16e27f4a482540de5adc3c6f02e425c227fcf32Lucas De Marchi return node->next; 616924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi} 626924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 6386e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchistatic inline void list_node_insert_after(struct list_node *list, 6486e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi struct list_node *node) 6586e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi{ 6686e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi if (list == NULL) { 6786e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi list_node_init(node); 6886e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi return; 6986e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi } 7086e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi 7186e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi node->prev = list; 7286e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi node->next = list->next; 7386e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi list->next->prev = node; 7486e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi list->next = node; 7586e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi} 7686e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi 77b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchistatic inline void list_node_insert_before(struct list_node *list, 78b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi struct list_node *node) 79b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi{ 80b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi if (list == NULL) { 81b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi list_node_init(node); 82b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi return; 83b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi } 84b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi 85b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi node->next = list; 86b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi node->prev = list->prev; 87b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi list->prev->next = node; 88b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi list->prev = node; 89b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi} 90b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi 911965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchistatic inline void list_node_append_list(struct list_node *list1, 921965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi struct list_node *list2) 931965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi{ 941965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi struct list_node *list1_last; 951965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi 961965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi if (list1 == NULL) { 971965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi list_node_init(list2); 981965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi return; 991965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi } 1001965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi 1011965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi list1->prev->next = list2; 1021965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi list2->prev->next = list1; 1031965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi 1041965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi /* cache the last, because we will lose the pointer */ 1051965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi list1_last = list1->prev; 1061965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi 1071965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi list1->prev = list2->prev; 1081965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi list2->prev = list1_last; 1091965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi} 1101965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi 1111ce08a563e4ff4a9bcae7a1514f1159232a16f71Gustavo Sverzut Barbieristruct kmod_list *kmod_list_append(struct kmod_list *list, const void *data) 1126924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi{ 1136924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi struct kmod_list *new; 1146924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 1156924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi new = malloc(sizeof(*new)); 1166924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi if (new == NULL) 1176924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi return NULL; 1186924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 1191ce08a563e4ff4a9bcae7a1514f1159232a16f71Gustavo Sverzut Barbieri new->data = (void *)data; 1206924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi list_node_append(list ? &list->node : NULL, &new->node); 1216924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 1226924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi return list ? list : new; 1236924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi} 1246924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 125c35347f15cf0ed71a0929ddb0a0d8e2de5f73de8Lucas De Marchistruct kmod_list *kmod_list_insert_after(struct kmod_list *list, 126c35347f15cf0ed71a0929ddb0a0d8e2de5f73de8Lucas De Marchi const void *data) 12786e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi{ 12886e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi struct kmod_list *new; 12986e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi 13086e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi if (list == NULL) 13186e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi return kmod_list_append(list, data); 13286e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi 13386e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi new = malloc(sizeof(*new)); 13486e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi if (new == NULL) 13586e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi return NULL; 13686e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi 13786e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi new->data = (void *)data; 13886e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi list_node_insert_after(&list->node, &new->node); 13986e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi 14086e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi return list; 14186e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi} 14286e878857219d3b0ffc716ec3135258a9d5523f2Lucas De Marchi 143c35347f15cf0ed71a0929ddb0a0d8e2de5f73de8Lucas De Marchistruct kmod_list *kmod_list_insert_before(struct kmod_list *list, 144c35347f15cf0ed71a0929ddb0a0d8e2de5f73de8Lucas De Marchi const void *data) 145b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi{ 146b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi struct kmod_list *new; 147b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi 148b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi if (list == NULL) 149b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi return kmod_list_append(list, data); 150b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi 151b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi new = malloc(sizeof(*new)); 152b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi if (new == NULL) 153b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi return NULL; 154b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi 155b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi new->data = (void *)data; 156b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi list_node_insert_before(&list->node, &new->node); 157b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi 158b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi return new; 159b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi} 160b91a1c6d3d4780d59a63bafd89c42c1910022b54Lucas De Marchi 1611965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchistruct kmod_list *kmod_list_append_list(struct kmod_list *list1, 1621965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi struct kmod_list *list2) 1631965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi{ 1641965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi if (list1 == NULL) 1651965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi return list2; 1661965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi 167434f32ca8d2858568c1ef959ae3f3c24a1c9be2aLucas De Marchi if (list2 == NULL) 168434f32ca8d2858568c1ef959ae3f3c24a1c9be2aLucas De Marchi return list1; 169434f32ca8d2858568c1ef959ae3f3c24a1c9be2aLucas De Marchi 1701965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi list_node_append_list(&list1->node, &list2->node); 1711965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi 1721965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi return list1; 1731965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi} 1741965029cb08ed31aca48921bd0418033cc0b060aLucas De Marchi 1751ce08a563e4ff4a9bcae7a1514f1159232a16f71Gustavo Sverzut Barbieristruct kmod_list *kmod_list_prepend(struct kmod_list *list, const void *data) 1766924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi{ 1776924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi struct kmod_list *new; 1786924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 1796924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi new = malloc(sizeof(*new)); 1806924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi if (new == NULL) 1816924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi return NULL; 1826924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 1831ce08a563e4ff4a9bcae7a1514f1159232a16f71Gustavo Sverzut Barbieri new->data = (void *)data; 1846924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi list_node_append(list ? &list->node : NULL, &new->node); 1856924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 1866924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi return new; 1876924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi} 1886924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 1896924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchistruct kmod_list *kmod_list_remove(struct kmod_list *list) 1906924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi{ 1916924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi struct list_node *node; 1926924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 1936924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi if (list == NULL) 1946924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi return NULL; 1956924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 1966924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi node = list_node_remove(&list->node); 1976924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi free(list); 1986924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 1996924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi if (node == NULL) 2006924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi return NULL; 2016924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 2026924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi return container_of(node, struct kmod_list, node); 2036924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi} 2046924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 2056924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchistruct kmod_list *kmod_list_remove_data(struct kmod_list *list, 2066924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi const void *data) 2076924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi{ 2086924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi struct kmod_list *itr; 2096924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi struct list_node *node; 2106924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 2116924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi for (itr = list; itr != NULL; itr = kmod_list_next(list, itr)) { 2126924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi if (itr->data == data) 2136924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi break; 2146924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi } 2156924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 2166924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi if (itr == NULL) 2176924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi return list; 2186924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 2196924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi node = list_node_remove(&itr->node); 2206924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi free(itr); 2216924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 2226924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi if (node == NULL) 2236924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi return NULL; 2246924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 2256924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi return container_of(node, struct kmod_list, node); 2266924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi} 2276924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 22862be799554c468b483afdda36f6e9903662aab23Lucas De Marchi/* 22962be799554c468b483afdda36f6e9903662aab23Lucas De Marchi * n must be greater to or equal the number of elements (we don't check the 2307e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi * condition) 23162be799554c468b483afdda36f6e9903662aab23Lucas De Marchi */ 23262be799554c468b483afdda36f6e9903662aab23Lucas De Marchistruct kmod_list *kmod_list_remove_n_latest(struct kmod_list *list, 23362be799554c468b483afdda36f6e9903662aab23Lucas De Marchi unsigned int n) 23462be799554c468b483afdda36f6e9903662aab23Lucas De Marchi{ 235eb4ae531f7693c52fc42a612b99127e591575eedLucas De Marchi struct kmod_list *l = list; 23662be799554c468b483afdda36f6e9903662aab23Lucas De Marchi unsigned int i; 23762be799554c468b483afdda36f6e9903662aab23Lucas De Marchi 238eb4ae531f7693c52fc42a612b99127e591575eedLucas De Marchi for (i = 0; i < n; i++) { 239eb4ae531f7693c52fc42a612b99127e591575eedLucas De Marchi l = kmod_list_last(l); 24062be799554c468b483afdda36f6e9903662aab23Lucas De Marchi l = kmod_list_remove(l); 241eb4ae531f7693c52fc42a612b99127e591575eedLucas De Marchi } 24262be799554c468b483afdda36f6e9903662aab23Lucas De Marchi 243eb4ae531f7693c52fc42a612b99127e591575eedLucas De Marchi return l; 24462be799554c468b483afdda36f6e9903662aab23Lucas De Marchi} 245eb4ae531f7693c52fc42a612b99127e591575eedLucas De Marchi 2467e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi/** 2477e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi * kmod_list_prev: 2487e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi * @list: the head of the list 2497e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi * @curr: the current node in the list 2507e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi * 2517e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi * Get the previous node in @list relative to @curr as if @list was not a 2527e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi * circular list. I.e.: the previous of the head is NULL. It can be used to 2537e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi * iterate a list by checking for NULL return to know when all elements were 2547e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi * iterated. 2557e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi * 2567e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi * Returns: node previous to @curr or NULL if either this node is the head of 2577e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi * the list or the list is empty. 2587e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi */ 2591ce08a563e4ff4a9bcae7a1514f1159232a16f71Gustavo Sverzut BarbieriKMOD_EXPORT struct kmod_list *kmod_list_prev(const struct kmod_list *list, 260c35347f15cf0ed71a0929ddb0a0d8e2de5f73de8Lucas De Marchi const struct kmod_list *curr) 26179d77111dc4026effbbd3e7b60970b0b2ac6179cLucas De Marchi{ 26279d77111dc4026effbbd3e7b60970b0b2ac6179cLucas De Marchi if (list == NULL || curr == NULL) 26379d77111dc4026effbbd3e7b60970b0b2ac6179cLucas De Marchi return NULL; 26479d77111dc4026effbbd3e7b60970b0b2ac6179cLucas De Marchi 2652a70a5d4e0e62313a905378d463bc5857c5eef0bGustavo Sverzut Barbieri if (list == curr) 26679d77111dc4026effbbd3e7b60970b0b2ac6179cLucas De Marchi return NULL; 26779d77111dc4026effbbd3e7b60970b0b2ac6179cLucas De Marchi 26879d77111dc4026effbbd3e7b60970b0b2ac6179cLucas De Marchi return container_of(curr->node.prev, struct kmod_list, node); 26979d77111dc4026effbbd3e7b60970b0b2ac6179cLucas De Marchi} 27079d77111dc4026effbbd3e7b60970b0b2ac6179cLucas De Marchi 2717e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi/** 2727e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi * kmod_list_next: 2737e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi * @list: the head of the list 2747e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi * @curr: the current node in the list 2757e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi * 2767e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi * Get the next node in @list relative to @curr as if @list was not a circular 2777e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi * list. I.e. calling this function in the last node of the list returns 2787e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi * NULL.. It can be used to iterate a list by checking for NULL return to know 2797e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi * when all elements were iterated. 2807e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi * 2817e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi * Returns: node next to @curr or NULL if either this node is the last of or 2827e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi * list is empty. 2837e1b3ae2b902031d3ec042a7f87fd3ecc98a4018Lucas De Marchi */ 2841ce08a563e4ff4a9bcae7a1514f1159232a16f71Gustavo Sverzut BarbieriKMOD_EXPORT struct kmod_list *kmod_list_next(const struct kmod_list *list, 285c35347f15cf0ed71a0929ddb0a0d8e2de5f73de8Lucas De Marchi const struct kmod_list *curr) 2866924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi{ 2876924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi if (list == NULL || curr == NULL) 2886924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi return NULL; 2896924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 2906924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi if (curr->node.next == &list->node) 2916924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi return NULL; 2926924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi 2936924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi return container_of(curr->node.next, struct kmod_list, node); 2946924e47a8d1af9ed2d42709358802fbb43fff8d4Lucas De Marchi} 295d5ec60bc0c2fa92a05e766463761b6e22d6d67b4Gustavo Sverzut Barbieri 296d5ec60bc0c2fa92a05e766463761b6e22d6d67b4Gustavo Sverzut Barbieri/** 297d5ec60bc0c2fa92a05e766463761b6e22d6d67b4Gustavo Sverzut Barbieri * kmod_list_last: 298d5ec60bc0c2fa92a05e766463761b6e22d6d67b4Gustavo Sverzut Barbieri * @list: the head of the list 299d5ec60bc0c2fa92a05e766463761b6e22d6d67b4Gustavo Sverzut Barbieri * 300d5ec60bc0c2fa92a05e766463761b6e22d6d67b4Gustavo Sverzut Barbieri * Get the last element of the @list. As @list is a circular list, 301d5ec60bc0c2fa92a05e766463761b6e22d6d67b4Gustavo Sverzut Barbieri * this is a cheap operation O(1) with the last element being the 302d5ec60bc0c2fa92a05e766463761b6e22d6d67b4Gustavo Sverzut Barbieri * previous element. 303d5ec60bc0c2fa92a05e766463761b6e22d6d67b4Gustavo Sverzut Barbieri * 304d5ec60bc0c2fa92a05e766463761b6e22d6d67b4Gustavo Sverzut Barbieri * If the list has a single element it will return the list itself (as 305d5ec60bc0c2fa92a05e766463761b6e22d6d67b4Gustavo Sverzut Barbieri * expected, and this is what differentiates from kmod_list_prev()). 306d5ec60bc0c2fa92a05e766463761b6e22d6d67b4Gustavo Sverzut Barbieri * 307d5ec60bc0c2fa92a05e766463761b6e22d6d67b4Gustavo Sverzut Barbieri * Returns: last node at @list or NULL if the list is empty. 308d5ec60bc0c2fa92a05e766463761b6e22d6d67b4Gustavo Sverzut Barbieri */ 309d5ec60bc0c2fa92a05e766463761b6e22d6d67b4Gustavo Sverzut BarbieriKMOD_EXPORT struct kmod_list *kmod_list_last(const struct kmod_list *list) 310d5ec60bc0c2fa92a05e766463761b6e22d6d67b4Gustavo Sverzut Barbieri{ 311d5ec60bc0c2fa92a05e766463761b6e22d6d67b4Gustavo Sverzut Barbieri if (list == NULL) 312d5ec60bc0c2fa92a05e766463761b6e22d6d67b4Gustavo Sverzut Barbieri return NULL; 313d5ec60bc0c2fa92a05e766463761b6e22d6d67b4Gustavo Sverzut Barbieri return container_of(list->node.prev, struct kmod_list, node); 314d5ec60bc0c2fa92a05e766463761b6e22d6d67b4Gustavo Sverzut Barbieri} 315