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