source: trunk/kitgen/8.x/libusb-win32/usb.c@ 182

Last change on this file since 182 was 175, checked in by demin, 12 years ago

initial commit

File size: 7.4 KB
Line 
1/*
2 * Main API entry point
3 *
4 * Copyright (c) 2000-2003 Johannes Erdfelt <johannes@erdfelt.com>
5 *
6 * This library is covered by the LGPL, read LICENSE for details.
7 */
8
9#include <stdlib.h> /* getenv */
10#include <stdio.h> /* stderr */
11#include <string.h> /* strcmp */
12#include <errno.h>
13
14#include "usbi.h"
15
16int usb_debug = 0;
17struct usb_bus *_usb_busses = NULL;
18
19int usb_find_busses(void)
20{
21 struct usb_bus *busses, *bus;
22 int ret, changes = 0;
23
24 ret = usb_os_find_busses(&busses);
25 if (ret < 0)
26 return ret;
27
28 /*
29 * Now walk through all of the busses we know about and compare against
30 * this new list. Any duplicates will be removed from the new list.
31 * If we don't find it in the new list, the bus was removed. Any
32 * busses still in the new list, are new to us.
33 */
34 bus = _usb_busses;
35 while (bus)
36 {
37 int found = 0;
38 struct usb_bus *nbus, *tbus = bus->next;
39
40 nbus = busses;
41 while (nbus)
42 {
43 struct usb_bus *tnbus = nbus->next;
44
45 if (!strcmp(bus->dirname, nbus->dirname))
46 {
47 /* Remove it from the new busses list */
48 LIST_DEL(busses, nbus);
49
50 usb_free_bus(nbus);
51 found = 1;
52 break;
53 }
54
55 nbus = tnbus;
56 }
57
58 if (!found)
59 {
60 /* The bus was removed from the system */
61 LIST_DEL(_usb_busses, bus);
62 usb_free_bus(bus);
63 changes++;
64 }
65
66 bus = tbus;
67 }
68
69 /*
70 * Anything on the *busses list is new. So add them to usb_busses and
71 * process them like the new bus it is.
72 */
73 bus = busses;
74 while (bus)
75 {
76 struct usb_bus *tbus = bus->next;
77
78 /*
79 * Remove it from the temporary list first and add it to the real
80 * usb_busses list.
81 */
82 LIST_DEL(busses, bus);
83
84 LIST_ADD(_usb_busses, bus);
85
86 changes++;
87
88 bus = tbus;
89 }
90
91 return changes;
92}
93
94int usb_find_devices(void)
95{
96 struct usb_bus *bus;
97 int ret, changes = 0;
98
99 for (bus = usb_busses; bus; bus = bus->next)
100 {
101 struct usb_device *devices, *dev;
102
103 /* Find all of the devices and put them into a temporary list */
104 ret = usb_os_find_devices(bus, &devices);
105 if (ret < 0)
106 return ret;
107
108 /*
109 * Now walk through all of the devices we know about and compare
110 * against this new list. Any duplicates will be removed from the new
111 * list. If we don't find it in the new list, the device was removed.
112 * Any devices still in the new list, are new to us.
113 */
114 dev = bus->devices;
115 while (dev)
116 {
117 int found = 0;
118 struct usb_device *ndev, *tdev = dev->next;
119
120 ndev = devices;
121 while (ndev)
122 {
123 struct usb_device *tndev = ndev->next;
124
125 if (!strcmp(dev->filename, ndev->filename))
126 {
127 /* Remove it from the new devices list */
128 LIST_DEL(devices, ndev);
129
130 usb_free_dev(ndev);
131 found = 1;
132 break;
133 }
134
135 ndev = tndev;
136 }
137
138 if (!found)
139 {
140 /* The device was removed from the system */
141 LIST_DEL(bus->devices, dev);
142 usb_free_dev(dev);
143 changes++;
144 }
145
146 dev = tdev;
147 }
148
149 /*
150 * Anything on the *devices list is new. So add them to bus->devices and
151 * process them like the new device it is.
152 */
153 dev = devices;
154 while (dev)
155 {
156 struct usb_device *tdev = dev->next;
157
158 /*
159 * Remove it from the temporary list first and add it to the real
160 * bus->devices list.
161 */
162 LIST_DEL(devices, dev);
163
164 /*
165 * Some ports fetch the descriptors on scanning (like Linux) so we don't
166 * need to fetch them again.
167 */
168 if (!dev->config)
169 {
170 usb_dev_handle *udev;
171
172 udev = usb_open(dev);
173 if (udev)
174 {
175 usb_fetch_and_parse_descriptors(udev);
176
177 usb_close(udev);
178 }
179 }
180
181 // [ID:2928293 Tim Green]
182 //
183 if (dev->config)
184 {
185 LIST_ADD(bus->devices, dev);
186 changes++;
187 }
188
189 dev = tdev;
190 }
191
192 usb_os_determine_children(bus);
193 }
194
195 return changes;
196}
197
198void usb_init(void)
199{
200 if (getenv("USB_DEBUG"))
201 usb_set_debug(atoi(getenv("USB_DEBUG")));
202
203 usb_os_init();
204}
205
206usb_dev_handle *usb_open(struct usb_device *dev)
207{
208 usb_dev_handle *udev;
209
210 udev = malloc(sizeof(*udev));
211 if (!udev)
212 return NULL;
213
214 udev->fd = -1;
215 udev->device = dev;
216 udev->bus = dev->bus;
217 udev->config = udev->interface = udev->altsetting = -1;
218
219 if (usb_os_open(udev) < 0)
220 {
221 free(udev);
222 return NULL;
223 }
224
225 return udev;
226}
227
228int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf,
229 size_t buflen)
230{
231 /*
232 * We can't use usb_get_descriptor() because it's lacking the index
233 * parameter. This will be fixed in libusb 1.0
234 */
235 return usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR,
236 (USB_DT_STRING << 8) + index, langid, buf, (int)buflen, 1000);
237}
238
239int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf, size_t buflen)
240{
241 char tbuf[255]; /* Some devices choke on size > 255 */
242 int ret, langid, si, di;
243
244 /*
245 * Asking for the zero'th index is special - it returns a string
246 * descriptor that contains all the language IDs supported by the
247 * device. Typically there aren't many - often only one. The
248 * language IDs are 16 bit numbers, and they start at the third byte
249 * in the descriptor. See USB 2.0 specification, section 9.6.7, for
250 * more information on this. */
251 ret = usb_get_string(dev, 0, 0, tbuf, sizeof(tbuf));
252 if (ret < 0)
253 return ret;
254
255 if (ret < 4)
256 return -EIO;
257
258 langid = tbuf[2] | (tbuf[3] << 8);
259
260 ret = usb_get_string(dev, index, langid, tbuf, sizeof(tbuf));
261 if (ret < 0)
262 return ret;
263
264 if (tbuf[1] != USB_DT_STRING)
265 return -EIO;
266
267 if (tbuf[0] > ret)
268 return -EFBIG;
269
270 for (di = 0, si = 2; si < tbuf[0]; si += 2)
271 {
272 if (di >= ((int)buflen - 1))
273 break;
274
275 if (tbuf[si + 1]) /* high byte */
276 buf[di++] = '?';
277 else
278 buf[di++] = tbuf[si];
279 }
280
281 buf[di] = 0;
282
283 return di;
284}
285
286int usb_close(usb_dev_handle *dev)
287{
288 int ret;
289
290 ret = usb_os_close(dev);
291 free(dev);
292
293 return ret;
294}
295
296struct usb_device *usb_device(usb_dev_handle *dev)
297{
298 return dev->device;
299}
300
301void usb_free_dev(struct usb_device *dev)
302{
303 usb_destroy_configuration(dev);
304 free(dev->children);
305 free(dev);
306}
307
308struct usb_bus *usb_get_busses(void)
309{
310 return _usb_busses;
311}
312
313void usb_free_bus(struct usb_bus *bus)
314{
315 free(bus);
316}
317
Note: See TracBrowser for help on using the repository browser.