source: mainline/uspace/drv/vhc/addrmgm.c@ 9ca0013

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 9ca0013 was ce687bbe, checked in by Vojtech Horky <vojtechhorky@…>, 15 years ago

Virtual HC can bind address and resolve them

  • Property mode set to 100644
File size: 4.7 KB
RevLine 
[ad104e0]1/*
2 * Copyright (c) 2010 Vojtech Horky
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 usb
30 * @{
31 */
32/** @file
33 * @brief Address management.
34 */
35
36#include <usb/usb.h>
37#include <stdlib.h>
38#include <stdio.h>
39#include <errno.h>
40#include <str_error.h>
41#include <fibril_synch.h>
42
43#include "vhcd.h"
44#include "conn.h"
45
46#define ADDRESS_COUNT 100
47#define DEFAULT_ADDRESS 0
48
49typedef struct {
50 usb_address_t address;
[ce687bbe]51 devman_handle_t devman_handle;
[ad104e0]52 bool available;
53} address_info_t;
54
55static address_info_t dev_address[ADDRESS_COUNT];
56fibril_mutex_t address_guard;
57
58typedef struct {
59 fibril_mutex_t condvar_guard;
60 fibril_condvar_t condvar;
61 bool available;
62} reservable_address_info_t;
63
64static reservable_address_info_t default_address;
65
66void address_init(void)
67{
68 usb_address_t i;
69 for (i = 0; i < ADDRESS_COUNT; i++) {
70 dev_address[i].address = i + 1;
71 dev_address[i].available = true;
[ce687bbe]72 dev_address[i].devman_handle = 0;
[ad104e0]73 }
74
75 fibril_mutex_initialize(&address_guard);
76 fibril_mutex_initialize(&default_address.condvar_guard);
77 fibril_condvar_initialize(&default_address.condvar);
78}
79
80int reserve_default_address(device_t *dev)
81{
82 fibril_mutex_lock(&default_address.condvar_guard);
83 while (!default_address.available) {
84 fibril_condvar_wait(&default_address.condvar,
85 &default_address.condvar_guard);
86 }
87 fibril_mutex_unlock(&default_address.condvar_guard);
88
89 return EOK;
90}
91
92int release_default_address(device_t *dev)
93{
94 fibril_mutex_lock(&default_address.condvar_guard);
95 default_address.available = true;
96 fibril_condvar_signal(&default_address.condvar);
97 fibril_mutex_unlock(&default_address.condvar_guard);
98
99 return EOK;
100}
101
102int request_address(device_t *dev, usb_address_t *address)
103{
104 fibril_mutex_lock(&address_guard);
105 usb_address_t i;
106 bool found = false;
107 for (i = 0; i < ADDRESS_COUNT; i++) {
108 if (dev_address[i].available) {
109 dev_address[i].available = false;
110 *address = dev_address[i].address;
111 found = true;
112 break;
113 }
114 }
115 fibril_mutex_unlock(&address_guard);
116
117 if (!found) {
118 return ELIMIT;
119 } else {
120 return EOK;
121 }
122}
123
[ce687bbe]124int bind_address(device_t *dev, usb_address_t address, devman_handle_t handle)
125{
126 if (address == DEFAULT_ADDRESS) {
127 return EPERM;
128 }
129
130 int rc = EPERM;
131
132 fibril_mutex_lock(&address_guard);
133 usb_address_t i;
134 for (i = 0; i < ADDRESS_COUNT; i++) {
135 if (dev_address[i].address == address) {
136 if (dev_address[i].available) {
137 rc = ENOENT;
138 break;
139 }
140
141 dev_address[i].devman_handle = handle;
142 rc = EOK;
143 break;
144 }
145 }
146 fibril_mutex_unlock(&address_guard);
147
148 return rc;
149}
150
151int tell_address(device_t *dev, devman_handle_t handle, usb_address_t *address)
152{
153 int rc = ENOENT;
154
155 fibril_mutex_lock(&address_guard);
156 usb_address_t i;
157 for (i = 0; i < ADDRESS_COUNT; i++) {
158 if (dev_address[i].devman_handle == handle) {
159 *address = dev_address[i].address;
160 rc = EOK;
161 break;
162 }
163 }
164 fibril_mutex_unlock(&address_guard);
165
166 return rc;
167}
168
[ad104e0]169int release_address(device_t *dev, usb_address_t address)
170{
171 if (address == DEFAULT_ADDRESS) {
172 return EPERM;
173 }
174
175 int rc = EPERM;
176
177 fibril_mutex_lock(&address_guard);
178 usb_address_t i;
179 for (i = 0; i < ADDRESS_COUNT; i++) {
180 if (dev_address[i].address == address) {
181 if (dev_address[i].available) {
182 rc = ENOENT;
183 break;
184 }
185
186 dev_address[i].available = true;
[ce687bbe]187 dev_address[i].devman_handle = 0;
[ad104e0]188 rc = EOK;
189 break;
190 }
191 }
192 fibril_mutex_unlock(&address_guard);
193
194 return rc;
195}
196
197/**
198 * @}
199 */
Note: See TracBrowser for help on using the repository browser.