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