libusb01.c revision 189621
1/* $FreeBSD: head/lib/libusb/libusb20_compat01.c 189621 2009-03-10 14:29:34Z thompsa $ */
2/*-
3 * Copyright (c) 2008 Hans Petter Selasky. 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 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27/*
28 * This file contains the emulation layer for LibUSB v0.1 from sourceforge.
29 */
30
31#include <sys/queue.h>
32
33#include <stdlib.h>
34#include <stdio.h>
35#include <errno.h>
36
37#include "libusb20.h"
38#include "libusb20_desc.h"
39#include "libusb20_int.h"
40#include "usb.h"
41
42/*
43 * The two following macros were taken from the original LibUSB v0.1
44 * for sake of compatibility:
45 */
46#define	LIST_ADD(begin, ent)	   \
47  do {				   \
48    if (begin) {		   \
49      ent->next = begin;	   \
50      ent->next->prev = ent;	   \
51    } else {			   \
52      ent->next = NULL;		   \
53    }				   \
54    ent->prev = NULL;		   \
55    begin = ent;		   \
56  } while(0)
57
58#define	LIST_DEL(begin, ent)		 \
59  do {					 \
60    if (ent->prev) {			 \
61      ent->prev->next = ent->next;	 \
62    } else {				 \
63      begin = ent->next;		 \
64    }					 \
65    if (ent->next) {			 \
66      ent->next->prev = ent->prev;	 \
67    }					 \
68    ent->prev = NULL;			 \
69    ent->next = NULL;			 \
70  } while (0)
71
72struct usb_bus *usb_busses = NULL;
73
74static struct usb_bus usb_global_bus = {
75	.dirname = {"/dev/usb"},
76	.root_dev = NULL,
77	.devices = NULL,
78};
79
80static struct libusb20_backend *usb_backend = NULL;
81
82struct usb_parse_state {
83
84	struct {
85		struct libusb20_endpoint *currep;
86		struct libusb20_interface *currifc;
87		struct libusb20_config *currcfg;
88		struct libusb20_me_struct *currextra;
89	}	a;
90
91	struct {
92		struct usb_config_descriptor *currcfg;
93		struct usb_interface_descriptor *currifc;
94		struct usb_endpoint_descriptor *currep;
95		struct usb_interface *currifcw;
96		uint8_t *currextra;
97	}	b;
98
99	uint8_t	preparse;
100};
101
102static uint8_t
103usb_get_first_claimed_interface(usb_dev_handle * dev)
104{
105	struct libusb20_device *pdev = (void *)dev;
106	uint32_t x;
107	uint8_t y;
108
109	x = pdev->claimed_interfaces;
110
111	for (y = 0; y != 32; y++) {
112		if (x & (1 << y))
113			break;
114	}
115
116	if (y == 32)
117		y = 0xFF;		/* dummy */
118
119	return (y);
120}
121
122static struct libusb20_transfer *
123usb_get_transfer_by_ep_no(usb_dev_handle * dev, uint8_t ep_no)
124{
125	struct libusb20_device *pdev = (void *)dev;
126	struct libusb20_transfer *xfer;
127	int err;
128	uint32_t bufsize;
129	uint8_t x;
130	uint8_t speed;
131
132	x = (ep_no & LIBUSB20_ENDPOINT_ADDRESS_MASK) * 2;
133
134	if (ep_no & LIBUSB20_ENDPOINT_DIR_MASK) {
135		/* this is an IN endpoint */
136		x |= 1;
137	}
138	speed = libusb20_dev_get_speed(pdev);
139
140	/* select a sensible buffer size */
141	if (speed == LIBUSB20_SPEED_LOW) {
142		bufsize = 256;
143	} else if (speed == LIBUSB20_SPEED_FULL) {
144		bufsize = 4096;
145	} else {
146		bufsize = 16384;
147	}
148
149	xfer = libusb20_tr_get_pointer(pdev, x);
150
151	if (xfer == NULL)
152		return (xfer);
153
154	err = libusb20_tr_open(xfer, bufsize, 1, ep_no);
155	if (err == LIBUSB20_ERROR_BUSY) {
156		/* already opened */
157		return (xfer);
158	} else if (err) {
159		return (NULL);
160	}
161	/* success */
162	return (xfer);
163}
164
165usb_dev_handle *
166usb_open(struct usb_device *dev)
167{
168	int err;
169
170	err = libusb20_dev_open(dev->dev, 16 * 2);
171	if (err == LIBUSB20_ERROR_BUSY) {
172		/*
173		 * Workaround buggy USB applications which open the USB
174		 * device multiple times:
175		 */
176		return (dev->dev);
177	}
178	if (err)
179		return (NULL);
180
181	/*
182	 * Dequeue USB device from backend queue so that it does not get
183	 * freed when the backend is re-scanned:
184	 */
185	libusb20_be_dequeue_device(usb_backend, dev->dev);
186
187	return (dev->dev);
188}
189
190int
191usb_close(usb_dev_handle * udev)
192{
193	struct usb_device *dev;
194	int err;
195
196	err = libusb20_dev_close((void *)udev);
197
198	if (err)
199		return (-1);
200
201	if (usb_backend != NULL) {
202		/*
203		 * Enqueue USB device to backend queue so that it gets freed
204		 * when the backend is re-scanned:
205		 */
206		libusb20_be_enqueue_device(usb_backend, (void *)udev);
207	} else {
208		/*
209		 * The backend is gone. Free device data so that we
210		 * don't start leaking memory!
211		 */
212		dev = usb_device(udev);
213		libusb20_dev_free((void *)udev);
214		LIST_DEL(usb_global_bus.devices, dev);
215		free(dev);
216	}
217	return (0);
218}
219
220int
221usb_get_string(usb_dev_handle * dev, int strindex,
222    int langid, char *buf, size_t buflen)
223{
224	int err;
225
226	err = libusb20_dev_req_string_sync((void *)dev,
227	    strindex, langid, buf, buflen);
228
229	if (err)
230		return (-1);
231
232	return (0);
233}
234
235int
236usb_get_string_simple(usb_dev_handle * dev, int strindex,
237    char *buf, size_t buflen)
238{
239	int err;
240
241	err = libusb20_dev_req_string_simple_sync((void *)dev,
242	    strindex, buf, buflen);
243
244	if (err)
245		return (-1);
246
247	return (strlen(buf));
248}
249
250int
251usb_get_descriptor_by_endpoint(usb_dev_handle * udev, int ep, uint8_t type,
252    uint8_t ep_index, void *buf, int size)
253{
254	memset(buf, 0, size);
255
256	return (usb_control_msg(udev, ep | USB_ENDPOINT_IN,
257	    USB_REQ_GET_DESCRIPTOR, (type << 8) + ep_index, 0,
258	    buf, size, 1000));
259}
260
261int
262usb_get_descriptor(usb_dev_handle * udev, uint8_t type, uint8_t desc_index,
263    void *buf, int size)
264{
265	memset(buf, 0, size);
266
267	return (usb_control_msg(udev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR,
268	    (type << 8) + desc_index, 0, buf, size, 1000));
269}
270
271int
272usb_parse_descriptor(uint8_t *source, char *description, void *dest)
273{
274	uint8_t *sp = source;
275	uint8_t *dp = dest;
276	uint16_t w;
277	uint32_t d;
278	char *cp;
279
280	for (cp = description; *cp; cp++) {
281		switch (*cp) {
282		case 'b':		/* 8-bit byte */
283			*dp++ = *sp++;
284			break;
285			/*
286			 * 16-bit word, convert from little endian to CPU
287			 */
288		case 'w':
289			w = (sp[1] << 8) | sp[0];
290			sp += 2;
291			/* Align to word boundary */
292			dp += ((dp - (uint8_t *)0) & 1);
293			*((uint16_t *)dp) = w;
294			dp += 2;
295			break;
296			/*
297			 * 32-bit dword, convert from little endian to CPU
298			 */
299		case 'd':
300			d = (sp[3] << 24) | (sp[2] << 16) |
301			    (sp[1] << 8) | sp[0];
302			sp += 4;
303			/* Align to word boundary */
304			dp += ((dp - (uint8_t *)0) & 1);
305			/* Align to double word boundary */
306			dp += ((dp - (uint8_t *)0) & 2);
307			*((uint32_t *)dp) = d;
308			dp += 4;
309			break;
310		}
311	}
312	return (sp - source);
313}
314
315static void
316usb_parse_extra(struct usb_parse_state *ps, uint8_t **pptr, int *plen)
317{
318	void *ptr;
319	uint16_t len;
320
321	ptr = ps->a.currextra->ptr;
322	len = ps->a.currextra->len;
323
324	if (ps->preparse == 0) {
325		memcpy(ps->b.currextra, ptr, len);
326		*pptr = ps->b.currextra;
327		*plen = len;
328	}
329	ps->b.currextra += len;
330	return;
331}
332
333static void
334usb_parse_endpoint(struct usb_parse_state *ps)
335{
336	struct usb_endpoint_descriptor *bep;
337	struct libusb20_endpoint *aep;
338
339	aep = ps->a.currep;
340	bep = ps->b.currep++;
341
342	if (ps->preparse == 0) {
343		/* copy descriptor fields */
344		bep->bLength = aep->desc.bLength;
345		bep->bDescriptorType = aep->desc.bDescriptorType;
346		bep->bEndpointAddress = aep->desc.bEndpointAddress;
347		bep->bmAttributes = aep->desc.bmAttributes;
348		bep->wMaxPacketSize = aep->desc.wMaxPacketSize;
349		bep->bInterval = aep->desc.bInterval;
350		bep->bRefresh = aep->desc.bRefresh;
351		bep->bSynchAddress = aep->desc.bSynchAddress;
352	}
353	ps->a.currextra = &aep->extra;
354	usb_parse_extra(ps, &bep->extra, &bep->extralen);
355	return;
356}
357
358static void
359usb_parse_iface_sub(struct usb_parse_state *ps)
360{
361	struct libusb20_interface *aifc;
362	struct usb_interface_descriptor *bifc;
363	uint8_t x;
364
365	aifc = ps->a.currifc;
366	bifc = ps->b.currifc++;
367
368	if (ps->preparse == 0) {
369		/* copy descriptor fields */
370		bifc->bLength = aifc->desc.bLength;
371		bifc->bDescriptorType = aifc->desc.bDescriptorType;
372		bifc->bInterfaceNumber = aifc->desc.bInterfaceNumber;
373		bifc->bAlternateSetting = aifc->desc.bAlternateSetting;
374		bifc->bNumEndpoints = aifc->num_endpoints;
375		bifc->bInterfaceClass = aifc->desc.bInterfaceClass;
376		bifc->bInterfaceSubClass = aifc->desc.bInterfaceSubClass;
377		bifc->bInterfaceProtocol = aifc->desc.bInterfaceProtocol;
378		bifc->iInterface = aifc->desc.iInterface;
379		bifc->endpoint = ps->b.currep;
380	}
381	for (x = 0; x != aifc->num_endpoints; x++) {
382		ps->a.currep = aifc->endpoints + x;
383		usb_parse_endpoint(ps);
384	}
385
386	ps->a.currextra = &aifc->extra;
387	usb_parse_extra(ps, &bifc->extra, &bifc->extralen);
388	return;
389}
390
391static void
392usb_parse_iface(struct usb_parse_state *ps)
393{
394	struct libusb20_interface *aifc;
395	struct usb_interface *bifc;
396	uint8_t x;
397
398	aifc = ps->a.currifc;
399	bifc = ps->b.currifcw++;
400
401	if (ps->preparse == 0) {
402		/* initialise interface wrapper */
403		bifc->altsetting = ps->b.currifc;
404		bifc->num_altsetting = aifc->num_altsetting + 1;
405	}
406	usb_parse_iface_sub(ps);
407
408	for (x = 0; x != aifc->num_altsetting; x++) {
409		ps->a.currifc = aifc->altsetting + x;
410		usb_parse_iface_sub(ps);
411	}
412	return;
413}
414
415static void
416usb_parse_config(struct usb_parse_state *ps)
417{
418	struct libusb20_config *acfg;
419	struct usb_config_descriptor *bcfg;
420	uint8_t x;
421
422	acfg = ps->a.currcfg;
423	bcfg = ps->b.currcfg;
424
425	if (ps->preparse == 0) {
426		/* initialise config wrapper */
427		bcfg->bLength = acfg->desc.bLength;
428		bcfg->bDescriptorType = acfg->desc.bDescriptorType;
429		bcfg->wTotalLength = acfg->desc.wTotalLength;
430		bcfg->bNumInterfaces = acfg->num_interface;
431		bcfg->bConfigurationValue = acfg->desc.bConfigurationValue;
432		bcfg->iConfiguration = acfg->desc.iConfiguration;
433		bcfg->bmAttributes = acfg->desc.bmAttributes;
434		bcfg->MaxPower = acfg->desc.bMaxPower;
435		bcfg->interface = ps->b.currifcw;
436	}
437	for (x = 0; x != acfg->num_interface; x++) {
438		ps->a.currifc = acfg->interface + x;
439		usb_parse_iface(ps);
440	}
441
442	ps->a.currextra = &acfg->extra;
443	usb_parse_extra(ps, &bcfg->extra, &bcfg->extralen);
444	return;
445}
446
447int
448usb_parse_configuration(struct usb_config_descriptor *config,
449    uint8_t *buffer)
450{
451	struct usb_parse_state ps;
452	uint8_t *ptr;
453	uint32_t a;
454	uint32_t b;
455	uint32_t c;
456	uint32_t d;
457
458	if ((buffer == NULL) || (config == NULL)) {
459		return (-1);
460	}
461	memset(&ps, 0, sizeof(ps));
462
463	ps.a.currcfg = libusb20_parse_config_desc(buffer);
464	ps.b.currcfg = config;
465	if (ps.a.currcfg == NULL) {
466		/* could not parse config or out of memory */
467		return (-1);
468	}
469	/* do the pre-parse */
470	ps.preparse = 1;
471	usb_parse_config(&ps);
472
473	a = ((uint8_t *)(ps.b.currifcw) - ((uint8_t *)0));
474	b = ((uint8_t *)(ps.b.currifc) - ((uint8_t *)0));
475	c = ((uint8_t *)(ps.b.currep) - ((uint8_t *)0));
476	d = ((uint8_t *)(ps.b.currextra) - ((uint8_t *)0));
477
478	/* allocate memory for our configuration */
479	ptr = malloc(a + b + c + d);
480
481	/* "currifcw" must be first, hence this pointer is freed */
482	ps.b.currifcw = (void *)(ptr);
483	ps.b.currifc = (void *)(ptr + a);
484	ps.b.currep = (void *)(ptr + a + b);
485	ps.b.currextra = (void *)(ptr + a + b + c);
486
487	/* generate a libusb v0.1 compatible structure */
488	ps.preparse = 0;
489	usb_parse_config(&ps);
490
491	/* free config structure */
492	free(ps.a.currcfg);
493
494	return (0);			/* success */
495}
496
497void
498usb_destroy_configuration(struct usb_device *dev)
499{
500	uint8_t c;
501
502	if (dev->config == NULL) {
503		return;
504	}
505	for (c = 0; c != dev->descriptor.bNumConfigurations; c++) {
506		struct usb_config_descriptor *cf = &dev->config[c];
507
508		if (cf->interface != NULL) {
509			free(cf->interface);
510			cf->interface = NULL;
511		}
512	}
513
514	free(dev->config);
515	dev->config = NULL;
516	return;
517}
518
519void
520usb_fetch_and_parse_descriptors(usb_dev_handle * udev)
521{
522	struct usb_device *dev;
523	struct libusb20_device *pdev;
524	uint8_t *ptr;
525	int error;
526	uint32_t size;
527	uint16_t len;
528	uint8_t x;
529
530	if (udev == NULL) {
531		/* be NULL safe */
532		return;
533	}
534	dev = usb_device(udev);
535	pdev = (void *)udev;
536
537	if (dev->descriptor.bNumConfigurations == 0) {
538		/* invalid device */
539		return;
540	}
541	size = dev->descriptor.bNumConfigurations *
542	    sizeof(struct usb_config_descriptor);
543
544	dev->config = malloc(size);
545	if (dev->config == NULL) {
546		/* out of memory */
547		return;
548	}
549	memset(dev->config, 0, size);
550
551	for (x = 0; x != dev->descriptor.bNumConfigurations; x++) {
552
553		error = (pdev->methods->get_config_desc_full) (
554		    pdev, &ptr, &len, x);
555
556		if (error) {
557			usb_destroy_configuration(dev);
558			return;
559		}
560		usb_parse_configuration(dev->config + x, ptr);
561
562		/* free config buffer */
563		free(ptr);
564	}
565	return;
566}
567
568static int
569usb_std_io(usb_dev_handle * dev, int ep, char *bytes, int size,
570    int timeout, int is_intr)
571{
572	struct libusb20_transfer *xfer;
573	uint32_t temp;
574	uint32_t maxsize;
575	uint32_t actlen;
576	char *oldbytes;
577
578	xfer = usb_get_transfer_by_ep_no(dev, ep);
579	if (xfer == NULL)
580		return (-1);
581
582	if (libusb20_tr_pending(xfer)) {
583		/* there is already a transfer ongoing */
584		return (-1);
585	}
586	maxsize = libusb20_tr_get_max_total_length(xfer);
587	oldbytes = bytes;
588
589	/*
590	 * We allow transferring zero bytes which is the same
591	 * equivalent to a zero length USB packet.
592	 */
593	do {
594
595		temp = size;
596		if (temp > maxsize) {
597			/* find maximum possible length */
598			temp = maxsize;
599		}
600		if (is_intr)
601			libusb20_tr_setup_intr(xfer, bytes, temp, timeout);
602		else
603			libusb20_tr_setup_bulk(xfer, bytes, temp, timeout);
604
605		libusb20_tr_start(xfer);
606
607		while (1) {
608
609			if (libusb20_dev_process((void *)dev) != 0) {
610				/* device detached */
611				return (-1);
612			}
613			if (libusb20_tr_pending(xfer) == 0) {
614				/* transfer complete */
615				break;
616			}
617			/* wait for USB event from kernel */
618			libusb20_dev_wait_process((void *)dev, -1);
619		}
620
621		switch (libusb20_tr_get_status(xfer)) {
622		case 0:
623			/* success */
624			break;
625		case LIBUSB20_TRANSFER_TIMED_OUT:
626			/* transfer timeout */
627			return (-ETIMEDOUT);
628		default:
629			/* other transfer error */
630			return (-ENXIO);
631		}
632		actlen = libusb20_tr_get_actual_length(xfer);
633
634		bytes += actlen;
635		size -= actlen;
636
637		if (actlen != temp) {
638			/* short transfer */
639			break;
640		}
641	} while (size > 0);
642
643	return (bytes - oldbytes);
644}
645
646int
647usb_bulk_write(usb_dev_handle * dev, int ep, char *bytes,
648    int size, int timeout)
649{
650	return (usb_std_io(dev, ep & ~USB_ENDPOINT_DIR_MASK,
651	    bytes, size, timeout, 0));
652}
653
654int
655usb_bulk_read(usb_dev_handle * dev, int ep, char *bytes,
656    int size, int timeout)
657{
658	return (usb_std_io(dev, ep | USB_ENDPOINT_DIR_MASK,
659	    bytes, size, timeout, 0));
660}
661
662int
663usb_interrupt_write(usb_dev_handle * dev, int ep, char *bytes,
664    int size, int timeout)
665{
666	return (usb_std_io(dev, ep & ~USB_ENDPOINT_DIR_MASK,
667	    bytes, size, timeout, 1));
668}
669
670int
671usb_interrupt_read(usb_dev_handle * dev, int ep, char *bytes,
672    int size, int timeout)
673{
674	return (usb_std_io(dev, ep | USB_ENDPOINT_DIR_MASK,
675	    bytes, size, timeout, 1));
676}
677
678int
679usb_control_msg(usb_dev_handle * dev, int requesttype, int request,
680    int value, int wIndex, char *bytes, int size, int timeout)
681{
682	struct LIBUSB20_CONTROL_SETUP_DECODED req;
683	int err;
684	uint16_t actlen;
685
686	LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &req);
687
688	req.bmRequestType = requesttype;
689	req.bRequest = request;
690	req.wValue = value;
691	req.wIndex = wIndex;
692	req.wLength = size;
693
694	err = libusb20_dev_request_sync((void *)dev, &req, bytes,
695	    &actlen, timeout, 0);
696
697	if (err)
698		return (-1);
699
700	return (actlen);
701}
702
703int
704usb_set_configuration(usb_dev_handle * udev, int bConfigurationValue)
705{
706	struct usb_device *dev;
707	int err;
708	uint8_t i;
709
710	/*
711	 * Need to translate from "bConfigurationValue" to
712	 * configuration index:
713	 */
714
715	if (bConfigurationValue == 0) {
716		/* unconfigure */
717		i = 255;
718	} else {
719		/* lookup configuration index */
720		dev = usb_device(udev);
721
722		/* check if the configuration array is not there */
723		if (dev->config == NULL) {
724			return (-1);
725		}
726		for (i = 0;; i++) {
727			if (i == dev->descriptor.bNumConfigurations) {
728				/* "bConfigurationValue" not found */
729				return (-1);
730			}
731			if ((dev->config + i)->bConfigurationValue ==
732			    bConfigurationValue) {
733				break;
734			}
735		}
736	}
737
738	err = libusb20_dev_set_config_index((void *)udev, i);
739
740	if (err)
741		return (-1);
742
743	return (0);
744}
745
746int
747usb_claim_interface(usb_dev_handle * dev, int interface)
748{
749	int err;
750
751	err = libusb20_dev_claim_interface((void *)dev, interface);
752
753	if (err)
754		return (-1);
755
756	return (0);
757}
758
759int
760usb_release_interface(usb_dev_handle * dev, int interface)
761{
762	int err;
763
764	err = libusb20_dev_release_interface((void *)dev, interface);
765
766	if (err)
767		return (-1);
768
769	return (0);
770}
771
772int
773usb_set_altinterface(usb_dev_handle * dev, int alternate)
774{
775	int err;
776	uint8_t iface;
777
778	iface = usb_get_first_claimed_interface(dev);
779
780	err = libusb20_dev_set_alt_index((void *)dev, iface, alternate);
781
782	if (err)
783		return (-1);
784
785	return (0);
786}
787
788int
789usb_resetep(usb_dev_handle * dev, unsigned int ep)
790{
791	/* emulate an endpoint reset through clear-STALL */
792	return (usb_clear_halt(dev, ep));
793}
794
795int
796usb_clear_halt(usb_dev_handle * dev, unsigned int ep)
797{
798	struct libusb20_transfer *xfer;
799
800	xfer = usb_get_transfer_by_ep_no(dev, ep);
801	if (xfer == NULL)
802		return (-1);
803
804	libusb20_tr_clear_stall_sync(xfer);
805
806	return (0);
807}
808
809int
810usb_reset(usb_dev_handle * dev)
811{
812	int err;
813
814	err = libusb20_dev_reset((void *)dev);
815
816	if (err)
817		return (-1);
818
819	/*
820	 * Be compatible with LibUSB from sourceforge and close the
821	 * handle after reset!
822	 */
823	return (usb_close(dev));
824}
825
826const char *
827usb_strerror(void)
828{
829	/* TODO */
830	return ("Unknown error");
831}
832
833void
834usb_init(void)
835{
836	/* nothing to do */
837	return;
838}
839
840void
841usb_set_debug(int level)
842{
843	/* use kernel UGEN debugging if you need to see what is going on */
844	return;
845}
846
847int
848usb_find_busses(void)
849{
850	usb_busses = &usb_global_bus;
851	return (0);
852}
853
854int
855usb_find_devices(void)
856{
857	struct libusb20_device *pdev;
858	struct usb_device *udev;
859	struct LIBUSB20_DEVICE_DESC_DECODED *ddesc;
860	int err;
861
862	/* cleanup after last device search */
863	/* close all opened devices, if any */
864
865	while ((pdev = libusb20_be_device_foreach(usb_backend, NULL))) {
866		udev = pdev->priv01Data;
867		libusb20_be_dequeue_device(usb_backend, pdev);
868		libusb20_dev_free(pdev);
869		if (udev != NULL) {
870			LIST_DEL(usb_global_bus.devices, udev);
871			free(udev);
872		}
873	}
874
875	/* free old USB backend, if any */
876
877	libusb20_be_free(usb_backend);
878
879	/* do a new backend device search */
880	usb_backend = libusb20_be_alloc_default();
881	if (usb_backend == NULL) {
882		return (-1);
883	}
884	/* iterate all devices */
885
886	pdev = NULL;
887	while ((pdev = libusb20_be_device_foreach(usb_backend, pdev))) {
888		udev = malloc(sizeof(*udev));
889		if (udev == NULL)
890			break;
891
892		memset(udev, 0, sizeof(*udev));
893
894		udev->bus = &usb_global_bus;
895
896		snprintf(udev->filename, sizeof(udev->filename),
897		    "/dev/ugen%u.%u",
898		    libusb20_dev_get_bus_number(pdev),
899		    libusb20_dev_get_address(pdev));
900
901		ddesc = libusb20_dev_get_device_desc(pdev);
902
903		udev->descriptor.bLength = sizeof(udev->descriptor);
904		udev->descriptor.bDescriptorType = ddesc->bDescriptorType;
905		udev->descriptor.bcdUSB = ddesc->bcdUSB;
906		udev->descriptor.bDeviceClass = ddesc->bDeviceClass;
907		udev->descriptor.bDeviceSubClass = ddesc->bDeviceSubClass;
908		udev->descriptor.bDeviceProtocol = ddesc->bDeviceProtocol;
909		udev->descriptor.bMaxPacketSize0 = ddesc->bMaxPacketSize0;
910		udev->descriptor.idVendor = ddesc->idVendor;
911		udev->descriptor.idProduct = ddesc->idProduct;
912		udev->descriptor.bcdDevice = ddesc->bcdDevice;
913		udev->descriptor.iManufacturer = ddesc->iManufacturer;
914		udev->descriptor.iProduct = ddesc->iProduct;
915		udev->descriptor.iSerialNumber = ddesc->iSerialNumber;
916		udev->descriptor.bNumConfigurations =
917		    ddesc->bNumConfigurations;
918		if (udev->descriptor.bNumConfigurations > USB_MAXCONFIG) {
919			/* truncate number of configurations */
920			udev->descriptor.bNumConfigurations = USB_MAXCONFIG;
921		}
922		/* link together the two structures */
923		udev->dev = pdev;
924		pdev->priv01Data = udev;
925
926		err = libusb20_dev_open(pdev, 0);
927		if (err == 0) {
928			/* XXX get all config descriptors by default */
929			usb_fetch_and_parse_descriptors((void *)pdev);
930			libusb20_dev_close(pdev);
931		}
932		LIST_ADD(usb_global_bus.devices, udev);
933	}
934
935	return (0);			/* success */
936}
937
938struct usb_device *
939usb_device(usb_dev_handle * dev)
940{
941	struct libusb20_device *pdev;
942
943	pdev = (void *)dev;
944
945	return (pdev->priv01Data);
946}
947
948struct usb_bus *
949usb_get_busses(void)
950{
951	return (usb_busses);
952}
953