source: mainline/uspace/lib/c/generic/device/hw_res_parsed.c@ 207e8880

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 207e8880 was 00d7e1b, checked in by Martin Decky <martin@…>, 14 years ago

networking improvements

  • start the networking stack from init
  • add loopback network interface driver (cherrypicked and sanitized from lp:~helenos-nicf/helenos/nicf)
  • add libnic and various small pieces from lp:~helenos-nicf/helenos/nicf
  • fix client side of NIC_GET_ADDRESS
  • net binary overhaul

Note: "ping 127.0.0.1" works, but the first three pings timeout for some reason

  • Property mode set to 100644
File size: 5.8 KB
Line 
1/*
2 * Copyright (c) 2011 Jiri Michalec
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libc
30 * @{
31 */
32/** @file
33 */
34
35#include <device/hw_res_parsed.h>
36#include <malloc.h>
37#include <assert.h>
38#include <errno.h>
39
40static void hw_res_parse_add_irq(hw_res_list_parsed_t *out, hw_resource_t *res,
41 int flags)
42{
43 assert(res && (res->type == INTERRUPT));
44
45 int irq = res->res.interrupt.irq;
46 size_t count = out->irqs.count;
47 int keep_duplicit = flags & HW_RES_KEEP_DUPLICIT;
48
49 if (!keep_duplicit) {
50 for (size_t i = 0; i < count; i++) {
51 if (out->irqs.irqs[i] == irq)
52 return;
53 }
54 }
55
56 out->irqs.irqs[count] = irq;
57 out->irqs.count++;
58}
59
60static void hw_res_parse_add_io_range(hw_res_list_parsed_t *out,
61 hw_resource_t *res, int flags)
62{
63 assert(res && (res->type == IO_RANGE));
64
65 uint64_t address = res->res.io_range.address;
66 endianness_t endianness = res->res.io_range.endianness;
67 size_t size = res->res.io_range.size;
68
69 if ((size == 0) && (!(flags & HW_RES_KEEP_ZERO_AREA)))
70 return;
71
72 int keep_duplicit = flags & HW_RES_KEEP_DUPLICIT;
73 size_t count = out->io_ranges.count;
74
75 if (!keep_duplicit) {
76 for (size_t i = 0; i < count; i++) {
77 uint64_t s_address = out->io_ranges.ranges[i].address;
78 size_t s_size = out->io_ranges.ranges[i].size;
79
80 if ((address == s_address) && (size == s_size))
81 return;
82 }
83 }
84
85 out->io_ranges.ranges[count].address = address;
86 out->io_ranges.ranges[count].endianness = endianness;
87 out->io_ranges.ranges[count].size = size;
88 out->io_ranges.count++;
89}
90
91static void hw_res_parse_add_mem_range(hw_res_list_parsed_t *out,
92 hw_resource_t *res, int flags)
93{
94 assert(res && (res->type == MEM_RANGE));
95
96 uint64_t address = res->res.mem_range.address;
97 endianness_t endianness = res->res.mem_range.endianness;
98 size_t size = res->res.mem_range.size;
99
100 if ((size == 0) && (!(flags & HW_RES_KEEP_ZERO_AREA)))
101 return;
102
103 int keep_duplicit = flags & HW_RES_KEEP_DUPLICIT;
104 size_t count = out->mem_ranges.count;
105
106 if (!keep_duplicit) {
107 for (size_t i = 0; i < count; ++i) {
108 uint64_t s_address = out->mem_ranges.ranges[i].address;
109 size_t s_size = out->mem_ranges.ranges[i].size;
110
111 if ((address == s_address) && (size == s_size))
112 return;
113 }
114 }
115
116 out->mem_ranges.ranges[count].address = address;
117 out->mem_ranges.ranges[count].endianness = endianness;
118 out->mem_ranges.ranges[count].size = size;
119 out->mem_ranges.count++;
120}
121
122/** Parse list of hardware resources
123 *
124 * @param hw_resources Original structure resource
125 * @param[out] out Output parsed resources
126 * @param flags Flags of the parsing.
127 * HW_RES_KEEP_ZERO_AREA for keeping
128 * zero-size areas, HW_RES_KEEP_DUPLICITIES
129 * for keep duplicit areas
130 *
131 * @return EOK if succeed, error code otherwise.
132 *
133 */
134int hw_res_list_parse(hw_resource_list_t *hw_resources,
135 hw_res_list_parsed_t *out, int flags)
136{
137 if ((!hw_resources) || (!out))
138 return EINVAL;
139
140 size_t res_count = hw_resources->count;
141 hw_res_list_parsed_clean(out);
142
143 out->irqs.irqs = malloc(res_count * sizeof(int));
144 out->io_ranges.ranges = malloc(res_count * sizeof(io_range_t));
145 out->mem_ranges.ranges = malloc(res_count * sizeof(mem_range_t));
146
147 for (size_t i = 0; i < res_count; ++i) {
148 hw_resource_t *resource = &(hw_resources->resources[i]);
149
150 switch (resource->type) {
151 case INTERRUPT:
152 hw_res_parse_add_irq(out, resource, flags);
153 break;
154 case IO_RANGE:
155 hw_res_parse_add_io_range(out, resource, flags);
156 break;
157 case MEM_RANGE:
158 hw_res_parse_add_mem_range(out, resource, flags);
159 break;
160 default:
161 return EINVAL;
162 }
163 }
164
165 return EOK;
166};
167
168/** Get hw_resources from the parent device.
169 *
170 * The output must be inited, will be cleared
171 *
172 * @see get_hw_resources
173 * @see hw_resources_parse
174 *
175 * @param sess Session to the parent device
176 * @param hw_resources_parsed Output list
177 * @param flags Parsing flags
178 *
179 * @return EOK if succeed, error code otherwise
180 *
181 */
182int hw_res_get_list_parsed(async_sess_t *sess,
183 hw_res_list_parsed_t *hw_res_parsed, int flags)
184{
185 if (!hw_res_parsed)
186 return EBADMEM;
187
188 hw_resource_list_t hw_resources;
189 hw_res_list_parsed_clean(hw_res_parsed);
190 bzero(&hw_resources, sizeof(hw_resource_list_t));
191
192 int rc = hw_res_get_resource_list(sess, &hw_resources);
193 if (rc != EOK)
194 return rc;
195
196 rc = hw_res_list_parse(&hw_resources, hw_res_parsed, flags);
197 hw_res_clean_resource_list(&hw_resources);
198
199 return rc;
200};
201
202/** @}
203 */
Note: See TracBrowser for help on using the repository browser.