1*0d6140beSAndroid Build Coastguard Worker /*
2*0d6140beSAndroid Build Coastguard Worker * This file is part of the flashrom project.
3*0d6140beSAndroid Build Coastguard Worker *
4*0d6140beSAndroid Build Coastguard Worker * Copyright (C) 2020, Google Inc. All rights reserved.
5*0d6140beSAndroid Build Coastguard Worker *
6*0d6140beSAndroid Build Coastguard Worker * This program is free software; you can redistribute it and/or modify
7*0d6140beSAndroid Build Coastguard Worker * it under the terms of the GNU General Public License as published by
8*0d6140beSAndroid Build Coastguard Worker * the Free Software Foundation; either version 2 of the License, or
9*0d6140beSAndroid Build Coastguard Worker * (at your option) any later version.
10*0d6140beSAndroid Build Coastguard Worker *
11*0d6140beSAndroid Build Coastguard Worker * This program is distributed in the hope that it will be useful,
12*0d6140beSAndroid Build Coastguard Worker * but WITHOUT ANY WARRANTY; without even the implied warranty of
13*0d6140beSAndroid Build Coastguard Worker * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14*0d6140beSAndroid Build Coastguard Worker * GNU General Public License for more details.
15*0d6140beSAndroid Build Coastguard Worker */
16*0d6140beSAndroid Build Coastguard Worker
17*0d6140beSAndroid Build Coastguard Worker #ifndef USB_DEVICE_H
18*0d6140beSAndroid Build Coastguard Worker #define USB_DEVICE_H
19*0d6140beSAndroid Build Coastguard Worker
20*0d6140beSAndroid Build Coastguard Worker /*
21*0d6140beSAndroid Build Coastguard Worker * USB device matching framework
22*0d6140beSAndroid Build Coastguard Worker *
23*0d6140beSAndroid Build Coastguard Worker * This can be used to match a USB device by a number of different parameters.
24*0d6140beSAndroid Build Coastguard Worker * The parameters can be passed on the command line and defaults can be set
25*0d6140beSAndroid Build Coastguard Worker * by the programmer.
26*0d6140beSAndroid Build Coastguard Worker */
27*0d6140beSAndroid Build Coastguard Worker
28*0d6140beSAndroid Build Coastguard Worker #include <libusb.h>
29*0d6140beSAndroid Build Coastguard Worker #include <stdint.h>
30*0d6140beSAndroid Build Coastguard Worker #include <stdbool.h>
31*0d6140beSAndroid Build Coastguard Worker
32*0d6140beSAndroid Build Coastguard Worker /*
33*0d6140beSAndroid Build Coastguard Worker * The LIBUSB_ERROR macro converts a libusb failure code into an error code that
34*0d6140beSAndroid Build Coastguard Worker * flashrom recognizes. It does so without displaying an error code allowing us
35*0d6140beSAndroid Build Coastguard Worker * to compare error codes against the library enumeration values.
36*0d6140beSAndroid Build Coastguard Worker */
37*0d6140beSAndroid Build Coastguard Worker #define LIBUSB_ERROR(error_code) (0x20000 | -(error_code))
38*0d6140beSAndroid Build Coastguard Worker
39*0d6140beSAndroid Build Coastguard Worker /*
40*0d6140beSAndroid Build Coastguard Worker * The LIBUSB macro converts a libusb failure code into an error code that
41*0d6140beSAndroid Build Coastguard Worker * flashrom recognizes. It also displays additional libusb specific
42*0d6140beSAndroid Build Coastguard Worker * information about the failure.
43*0d6140beSAndroid Build Coastguard Worker */
44*0d6140beSAndroid Build Coastguard Worker #define LIBUSB(expression) \
45*0d6140beSAndroid Build Coastguard Worker ({ \
46*0d6140beSAndroid Build Coastguard Worker int libusb_error__ = (expression); \
47*0d6140beSAndroid Build Coastguard Worker \
48*0d6140beSAndroid Build Coastguard Worker if (libusb_error__ < 0) { \
49*0d6140beSAndroid Build Coastguard Worker msg_perr("libusb error: %s:%d %s\n", \
50*0d6140beSAndroid Build Coastguard Worker __FILE__, \
51*0d6140beSAndroid Build Coastguard Worker __LINE__, \
52*0d6140beSAndroid Build Coastguard Worker libusb_error_name(libusb_error__)); \
53*0d6140beSAndroid Build Coastguard Worker libusb_error__ = LIBUSB_ERROR(libusb_error__); \
54*0d6140beSAndroid Build Coastguard Worker } else { \
55*0d6140beSAndroid Build Coastguard Worker libusb_error__ = 0; \
56*0d6140beSAndroid Build Coastguard Worker } \
57*0d6140beSAndroid Build Coastguard Worker \
58*0d6140beSAndroid Build Coastguard Worker libusb_error__; \
59*0d6140beSAndroid Build Coastguard Worker })
60*0d6140beSAndroid Build Coastguard Worker
61*0d6140beSAndroid Build Coastguard Worker /*
62*0d6140beSAndroid Build Coastguard Worker * Returns true if the error code falls within the range of valid libusb
63*0d6140beSAndroid Build Coastguard Worker * error codes.
64*0d6140beSAndroid Build Coastguard Worker */
usb_device_is_libusb_error(int error_code)65*0d6140beSAndroid Build Coastguard Worker static inline bool usb_device_is_libusb_error(int error_code)
66*0d6140beSAndroid Build Coastguard Worker {
67*0d6140beSAndroid Build Coastguard Worker return (0x20000 <= error_code && error_code < 0x20064);
68*0d6140beSAndroid Build Coastguard Worker }
69*0d6140beSAndroid Build Coastguard Worker
70*0d6140beSAndroid Build Coastguard Worker /*
71*0d6140beSAndroid Build Coastguard Worker * A USB match and associated value struct are used to encode the information
72*0d6140beSAndroid Build Coastguard Worker * about a device against which we wish to match. If the value of a
73*0d6140beSAndroid Build Coastguard Worker * usb_match_value has been set then a device must match that value. The name
74*0d6140beSAndroid Build Coastguard Worker * of the usb_match_value is used to fetch the programmer parameter from the
75*0d6140beSAndroid Build Coastguard Worker * flashrom command line and is the same as the name of the corresponding
76*0d6140beSAndroid Build Coastguard Worker * field in usb_match.
77*0d6140beSAndroid Build Coastguard Worker */
78*0d6140beSAndroid Build Coastguard Worker struct usb_match_value {
79*0d6140beSAndroid Build Coastguard Worker char const *name;
80*0d6140beSAndroid Build Coastguard Worker int value;
81*0d6140beSAndroid Build Coastguard Worker int set;
82*0d6140beSAndroid Build Coastguard Worker };
83*0d6140beSAndroid Build Coastguard Worker
84*0d6140beSAndroid Build Coastguard Worker struct usb_match {
85*0d6140beSAndroid Build Coastguard Worker struct usb_match_value bus;
86*0d6140beSAndroid Build Coastguard Worker struct usb_match_value address;
87*0d6140beSAndroid Build Coastguard Worker struct usb_match_value vid;
88*0d6140beSAndroid Build Coastguard Worker struct usb_match_value pid;
89*0d6140beSAndroid Build Coastguard Worker struct usb_match_value serial;
90*0d6140beSAndroid Build Coastguard Worker struct usb_match_value config;
91*0d6140beSAndroid Build Coastguard Worker struct usb_match_value interface;
92*0d6140beSAndroid Build Coastguard Worker struct usb_match_value altsetting;
93*0d6140beSAndroid Build Coastguard Worker struct usb_match_value class;
94*0d6140beSAndroid Build Coastguard Worker struct usb_match_value subclass;
95*0d6140beSAndroid Build Coastguard Worker struct usb_match_value protocol;
96*0d6140beSAndroid Build Coastguard Worker };
97*0d6140beSAndroid Build Coastguard Worker
98*0d6140beSAndroid Build Coastguard Worker /*
99*0d6140beSAndroid Build Coastguard Worker * Initialize a usb_match structure so that each value's name matches the
100*0d6140beSAndroid Build Coastguard Worker * values name in the usb_match structure (so bus.name == "bus"...), and
101*0d6140beSAndroid Build Coastguard Worker * look for each value in the flashrom command line via
102*0d6140beSAndroid Build Coastguard Worker * extract_programmer_param_str. If the value is found convert it to an integer
103*0d6140beSAndroid Build Coastguard Worker * using strtol, accepting hex, decimal and octal encoding.
104*0d6140beSAndroid Build Coastguard Worker */
105*0d6140beSAndroid Build Coastguard Worker void usb_match_init(const struct programmer_cfg *cfg, struct usb_match *match);
106*0d6140beSAndroid Build Coastguard Worker
107*0d6140beSAndroid Build Coastguard Worker /*
108*0d6140beSAndroid Build Coastguard Worker * Add a default value to a usb_match_value. This must be done after calling
109*0d6140beSAndroid Build Coastguard Worker * usb_match_init. If usb_match_init already set the value of a usb_match_value
110*0d6140beSAndroid Build Coastguard Worker * we do nothing, otherwise set the value to default_value. This ensures that
111*0d6140beSAndroid Build Coastguard Worker * parameters passed on the command line override defaults.
112*0d6140beSAndroid Build Coastguard Worker */
113*0d6140beSAndroid Build Coastguard Worker void usb_match_value_default(struct usb_match_value *match,
114*0d6140beSAndroid Build Coastguard Worker long int default_value);
115*0d6140beSAndroid Build Coastguard Worker
116*0d6140beSAndroid Build Coastguard Worker /*
117*0d6140beSAndroid Build Coastguard Worker * The usb_device structure is an entry in a linked list of devices that were
118*0d6140beSAndroid Build Coastguard Worker * matched by usb_device_find.
119*0d6140beSAndroid Build Coastguard Worker */
120*0d6140beSAndroid Build Coastguard Worker struct usb_device {
121*0d6140beSAndroid Build Coastguard Worker struct libusb_device *device;
122*0d6140beSAndroid Build Coastguard Worker struct libusb_config_descriptor *config_descriptor;
123*0d6140beSAndroid Build Coastguard Worker struct libusb_interface_descriptor const *interface_descriptor;
124*0d6140beSAndroid Build Coastguard Worker
125*0d6140beSAndroid Build Coastguard Worker /*
126*0d6140beSAndroid Build Coastguard Worker * Initially NULL, the libusb_device_handle is only valid once the
127*0d6140beSAndroid Build Coastguard Worker * usb_device has been successfully passed to usb_device_show or
128*0d6140beSAndroid Build Coastguard Worker * usb_device_claim.
129*0d6140beSAndroid Build Coastguard Worker */
130*0d6140beSAndroid Build Coastguard Worker struct libusb_device_handle *handle;
131*0d6140beSAndroid Build Coastguard Worker
132*0d6140beSAndroid Build Coastguard Worker /*
133*0d6140beSAndroid Build Coastguard Worker * Link to next device, or NULL
134*0d6140beSAndroid Build Coastguard Worker */
135*0d6140beSAndroid Build Coastguard Worker struct usb_device *next;
136*0d6140beSAndroid Build Coastguard Worker };
137*0d6140beSAndroid Build Coastguard Worker
138*0d6140beSAndroid Build Coastguard Worker /*
139*0d6140beSAndroid Build Coastguard Worker * Find and return a list of all compatible devices. Each device is added to
140*0d6140beSAndroid Build Coastguard Worker * the list with its first valid configuration and interface. If an alternate
141*0d6140beSAndroid Build Coastguard Worker * configuration (config, interface, altsetting...) is desired the specifics
142*0d6140beSAndroid Build Coastguard Worker * can be supplied as programmer parameters.
143*0d6140beSAndroid Build Coastguard Worker *
144*0d6140beSAndroid Build Coastguard Worker * Return:
145*0d6140beSAndroid Build Coastguard Worker * 0: At least one matching device was found.
146*0d6140beSAndroid Build Coastguard Worker * 1: No matching devices were found.
147*0d6140beSAndroid Build Coastguard Worker */
148*0d6140beSAndroid Build Coastguard Worker int usb_device_find(struct usb_match const *match, struct usb_device **devices);
149*0d6140beSAndroid Build Coastguard Worker
150*0d6140beSAndroid Build Coastguard Worker /*
151*0d6140beSAndroid Build Coastguard Worker * Display the devices bus and address as well as its product string. The
152*0d6140beSAndroid Build Coastguard Worker * underlying libusb device is opened if it is not already open.
153*0d6140beSAndroid Build Coastguard Worker *
154*0d6140beSAndroid Build Coastguard Worker * Return:
155*0d6140beSAndroid Build Coastguard Worker * 0: The device information was displayed.
156*0d6140beSAndroid Build Coastguard Worker * non-zero: There was a failure while displaying the device information.
157*0d6140beSAndroid Build Coastguard Worker */
158*0d6140beSAndroid Build Coastguard Worker int usb_device_show(char const *prefix, struct usb_device *device);
159*0d6140beSAndroid Build Coastguard Worker
160*0d6140beSAndroid Build Coastguard Worker /*
161*0d6140beSAndroid Build Coastguard Worker * Open the underlying libusb device, set its config, claim the interface and
162*0d6140beSAndroid Build Coastguard Worker * select the correct alternate interface.
163*0d6140beSAndroid Build Coastguard Worker *
164*0d6140beSAndroid Build Coastguard Worker * Return:
165*0d6140beSAndroid Build Coastguard Worker * 0: The device was successfully claimed.
166*0d6140beSAndroid Build Coastguard Worker * non-zero: There was a failure while trying to claim the device.
167*0d6140beSAndroid Build Coastguard Worker */
168*0d6140beSAndroid Build Coastguard Worker int usb_device_claim(struct usb_device *device);
169*0d6140beSAndroid Build Coastguard Worker
170*0d6140beSAndroid Build Coastguard Worker /*
171*0d6140beSAndroid Build Coastguard Worker * Free a usb_device structure.
172*0d6140beSAndroid Build Coastguard Worker *
173*0d6140beSAndroid Build Coastguard Worker * This ensures that the libusb device is closed and that all allocated
174*0d6140beSAndroid Build Coastguard Worker * handles and descriptors are freed.
175*0d6140beSAndroid Build Coastguard Worker *
176*0d6140beSAndroid Build Coastguard Worker * Return:
177*0d6140beSAndroid Build Coastguard Worker * The next device in the device list.
178*0d6140beSAndroid Build Coastguard Worker */
179*0d6140beSAndroid Build Coastguard Worker struct usb_device *usb_device_free(struct usb_device *device);
180*0d6140beSAndroid Build Coastguard Worker
181*0d6140beSAndroid Build Coastguard Worker #endif /* USB_DEVICE_H */
182