xref: /aosp_15_r20/external/flashrom/include/usb_device.h (revision 0d6140be3aa665ecc836e8907834fcd3e3b018fc)
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