1 /***************************************************************************
2 * Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net> *
4 * Copyright (C) 2011 by Mauro Gamba <maurillo71@gmail.com> *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
20 ***************************************************************************/
26 #include "libusb1_common.h"
28 static struct libusb_context
*jtag_libusb_context
; /**< Libusb context **/
29 static libusb_device
**devs
; /**< The usb device list **/
31 static bool jtag_libusb_match(struct jtag_libusb_device
*dev
,
32 const uint16_t vids
[], const uint16_t pids
[])
34 struct libusb_device_descriptor dev_desc
;
36 for (unsigned i
= 0; vids
[i
]; i
++) {
37 if (libusb_get_device_descriptor(dev
, &dev_desc
) == 0) {
38 if (dev_desc
.idVendor
== vids
[i
] &&
39 dev_desc
.idProduct
== pids
[i
])
46 int jtag_libusb_open(const uint16_t vids
[], const uint16_t pids
[],
47 struct jtag_libusb_device_handle
**out
)
49 int cnt
, idx
, errCode
;
51 if (libusb_init(&jtag_libusb_context
) < 0)
54 cnt
= libusb_get_device_list(jtag_libusb_context
, &devs
);
56 for (idx
= 0; idx
< cnt
; idx
++) {
57 if (!jtag_libusb_match(devs
[idx
], vids
, pids
))
60 errCode
= libusb_open(devs
[idx
], out
);
62 /** Free the device list **/
63 libusb_free_device_list(devs
, 1);
66 LOG_ERROR("libusb_open() failed with %s",
67 libusb_error_name(errCode
));
75 void jtag_libusb_close(jtag_libusb_device_handle
*dev
)
80 libusb_exit(jtag_libusb_context
);
83 int jtag_libusb_control_transfer(jtag_libusb_device_handle
*dev
, uint8_t requestType
,
84 uint8_t request
, uint16_t wValue
, uint16_t wIndex
, char *bytes
,
85 uint16_t size
, unsigned int timeout
)
89 transferred
= libusb_control_transfer(dev
, requestType
, request
, wValue
, wIndex
,
90 (unsigned char *)bytes
, size
, timeout
);
98 int jtag_libusb_bulk_write(jtag_libusb_device_handle
*dev
, int ep
, char *bytes
,
99 int size
, int timeout
)
103 libusb_bulk_transfer(dev
, ep
, (unsigned char *)bytes
, size
,
104 &transferred
, timeout
);
108 int jtag_libusb_bulk_read(jtag_libusb_device_handle
*dev
, int ep
, char *bytes
,
109 int size
, int timeout
)
113 libusb_bulk_transfer(dev
, ep
, (unsigned char *)bytes
, size
,
114 &transferred
, timeout
);
118 int jtag_libusb_set_configuration(jtag_libusb_device_handle
*devh
,
121 struct jtag_libusb_device
*udev
= jtag_libusb_get_device(devh
);
124 struct libusb_config_descriptor
*config
= NULL
;
126 libusb_get_config_descriptor(udev
, configuration
, &config
);
127 retCode
= libusb_set_configuration(devh
, config
->bConfigurationValue
);
129 libusb_free_config_descriptor(config
);
134 int jtag_libusb_get_endpoints(struct jtag_libusb_device
*udev
,
135 unsigned int *usb_read_ep
,
136 unsigned int *usb_write_ep
)
138 const struct libusb_interface
*inter
;
139 const struct libusb_interface_descriptor
*interdesc
;
140 const struct libusb_endpoint_descriptor
*epdesc
;
141 struct libusb_config_descriptor
*config
;
143 libusb_get_config_descriptor(udev
, 0, &config
);
144 for (int i
= 0; i
< (int)config
->bNumInterfaces
; i
++) {
145 inter
= &config
->interface
[i
];
147 for (int j
= 0; j
< inter
->num_altsetting
; j
++) {
148 interdesc
= &inter
->altsetting
[j
];
150 k
< (int)interdesc
->bNumEndpoints
; k
++) {
151 epdesc
= &interdesc
->endpoint
[k
];
153 uint8_t epnum
= epdesc
->bEndpointAddress
;
154 bool is_input
= epnum
& 0x80;
155 LOG_DEBUG("usb ep %s %02x",
156 is_input
? "in" : "out", epnum
);
159 *usb_read_ep
= epnum
;
161 *usb_write_ep
= epnum
;
165 libusb_free_config_descriptor(config
);