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