1 /*
2  * $Id$
3  *
4  * Link driver for accessing USB devices via libusb
5  *
6  * Copyright (C) 2008 K. Waschk
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21  * 02111-1307, USA.
22  *
23  * Written by Kolja Waschk, 2008
24  *
25  */
26 
27 #ifndef URJ_USBCONN_LIBUSB_H
28 #define URJ_USBCONN_LIBUSB_H 1
29 
30 #ifdef HAVE_LIBUSB1
31 # include <libusb.h>
32 #else
33 
34 /* Glue the libusb-0.x API to the libusb-1.x API */
35 # include <usb.h>
36 
37 # define LIBUSB_ENDPOINT_IN USB_ENDPOINT_IN
38 
39 # define LIBUSB_REQUEST_TYPE_STANDARD USB_TYPE_STANDARD
40 # define LIBUSB_REQUEST_TYPE_CLASS    USB_TYPE_CLASS
41 # define LIBUSB_REQUEST_TYPE_VENDOR   USB_TYPE_VENDOR
42 # define LIBUSB_REQUEST_TYPE_RESERVED USB_TYPE_RESERVED
43 
44 # define LIBUSB_RECIPIENT_DEVICE    USB_RECIP_DEVICE
45 # define LIBUSB_RECIPIENT_INTERFACE USB_RECIP_INTERFACE
46 # define LIBUSB_RECIPIENT_ENDPOINT  USB_RECIP_ENDPOINT
47 # define LIBUSB_RECIPIENT_OTHER     USB_RECIP_OTHER
48 
49 # define libusb_context void
50 typedef struct usb_device libusb_device;
51 # define libusb_device_handle usb_dev_handle
52 # define libusb_device_descriptor usb_device_descriptor
53 
54 # define libusb_ref_device(def) def
55 # define libusb_reset_device(dev) usb_reset (dev)
56 # define libusb_close(dev) usb_close (dev)
57 # define libusb_set_configuration(dev, cfg) usb_set_configuration (dev, cfg)
58 # define libusb_claim_interface(dev, iface) usb_claim_interface (dev, iface)
59 # define libusb_set_interface_alt_setting(dev, prev, alt) usb_set_altinterface (dev, alt)
60 # define libusb_release_interface(dev, iface) usb_release_interface (dev, iface)
61 
62 static inline int
libusb_init(libusb_context ** ctx)63 libusb_init (libusb_context **ctx)
64 {
65     int ret;
66 
67     *ctx = NULL;
68 
69     usb_init ();
70 
71     ret = usb_find_busses ();
72     if (ret < 0)
73         return ret;
74 
75     return usb_find_devices ();
76 }
77 
78 static inline ssize_t
libusb_get_device_list(libusb_context * ctx,libusb_device *** list)79 libusb_get_device_list (libusb_context *ctx, libusb_device ***list)
80 {
81     struct usb_bus *bus;
82     ssize_t ret = 0;
83 
84     *list = malloc (sizeof (**list));
85     for (bus = usb_get_busses (); bus; bus = bus->next)
86     {
87         libusb_device *dev;
88 
89         for (dev = bus->devices; dev; dev = dev->next)
90         {
91             *list = realloc (*list, sizeof (**list) * (ret + 2));
92             (*list)[ret] = malloc (sizeof (***list));
93             *(*list)[ret] = *dev;
94             ++ret;
95         }
96     }
97     (*list)[ret] = NULL;
98 
99     return ret;
100 }
101 
102 static inline void
libusb_free_device_list(libusb_device ** list,int unref_devices)103 libusb_free_device_list(libusb_device **list, int unref_devices)
104 {
105     size_t i;
106 
107     i = 0;
108     while (list[i])
109         free (list[i++]);
110 
111     free (list);
112 }
113 
114 static inline int
libusb_bulk_transfer(libusb_device_handle * dev_handle,unsigned char endpoint,unsigned char * data,int length,int * actual_length,unsigned int timeout)115 libusb_bulk_transfer (libusb_device_handle *dev_handle, unsigned char endpoint,
116                       unsigned char *data, int length, int *actual_length,
117                       unsigned int timeout)
118 {
119     char *cdata = (char *)data;
120     int ret;
121 
122     if (endpoint & LIBUSB_ENDPOINT_IN)
123         ret = usb_bulk_read (dev_handle, endpoint, cdata, length, timeout);
124     else
125         ret = usb_bulk_write (dev_handle, endpoint, cdata, length, timeout);
126 
127     if (ret < 0)
128     {
129         *actual_length = 0;
130         return -ret;
131     }
132     else
133     {
134         *actual_length = ret;
135         return 0;
136     }
137 }
138 # define usb_bulk_read(...)  use_libusb_1_api
139 # define usb_bulk_write(...) use_libusb_1_api
140 
141 static inline int
libusb_control_transfer(libusb_device_handle * dev_handle,uint8_t request_type,uint8_t request,uint16_t value,uint16_t index,unsigned char * data,uint16_t length,unsigned int timeout)142 libusb_control_transfer (libusb_device_handle *dev_handle, uint8_t request_type,
143                          uint8_t request, uint16_t value, uint16_t index,
144                          unsigned char *data, uint16_t length, unsigned int timeout)
145 {
146     char *cdata = (char *)data;
147     int ret;
148 
149     ret = usb_control_msg (dev_handle, request_type, request, value, index,
150                            cdata, length, timeout);
151 
152     if (ret < 0)
153         return -ret;
154     else
155         return ret;
156 }
157 # define usb_control_msg(...) use_libusb_1_api
158 
159 static inline int
libusb_open(libusb_device * dev,libusb_device_handle ** handle)160 libusb_open (libusb_device *dev, libusb_device_handle **handle)
161 {
162     *handle = usb_open (dev);
163     return *handle ? 0 : -99;
164 }
165 # define usb_open(...) use_libusb_1_api
166 
167 static inline int
libusb_get_string_descriptor_ascii(libusb_device_handle * dev,uint8_t index,unsigned char * data,int length)168 libusb_get_string_descriptor_ascii (libusb_device_handle *dev, uint8_t index,
169                                     unsigned char *data, int length)
170 {
171     return usb_get_string_simple (dev, index, (char *) data, length);
172 }
173 # define usb_get_string_simple(...) use_libusb_1_api
174 
175 #endif
176 
177 /* XXX: libusb-1.x doesn't have a replacement ? :( */
178 #define usb_strerror() dont_use_usb_strerror
179 
180 typedef struct
181 {
182     libusb_device *dev;
183     struct libusb_device_handle *handle;
184     void *data;
185 } urj_usbconn_libusb_param_t;
186 
187 #endif
188