Khem Raj has uploaded this change for review. ( https://review.coreboot.org/c/flashrom/+/51960 )
Change subject: flashrom: Mark RISCV as non memory-mapped I/O architecture
......................................................................
flashrom: Mark RISCV as non memory-mapped I/O architecture
Signed-off-by: Khem Raj <raj.khem(a)gmail.com>
Change-Id: I55c4e8529d36f0850dd56441c3fb8602c5d889fd
---
M Makefile
M hwaccess.h
2 files changed, 5 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/60/51960/1
diff --git a/Makefile b/Makefile
index 6d37d55..203e04b 100644
--- a/Makefile
+++ b/Makefile
@@ -559,7 +559,7 @@
# Disable all drivers needing raw access (memory, PCI, port I/O) on
# architectures with unknown raw access properties.
# Right now those architectures are alpha hppa m68k sh s390
-ifneq ($(ARCH),$(filter $(ARCH),x86 mips ppc arm sparc arc))
+ifneq ($(ARCH),$(filter $(ARCH),x86 mips ppc arm sparc arc riscv))
ifeq ($(CONFIG_RAYER_SPI), yes)
UNSUPPORTED_FEATURES += CONFIG_RAYER_SPI=yes
else
diff --git a/hwaccess.h b/hwaccess.h
index 5602c15..e79988a 100644
--- a/hwaccess.h
+++ b/hwaccess.h
@@ -295,6 +295,10 @@
/* Non memory mapped I/O is not supported on ARC. */
+#elif IS_RISCV
+
+/* Non memory mapped I/O is not supported on RISCV. */
+
#else
#error Unknown architecture, please check if it supports PCI port IO.
--
To view, visit https://review.coreboot.org/c/flashrom/+/51960
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-Change-Id: I55c4e8529d36f0850dd56441c3fb8602c5d889fd
Gerrit-Change-Number: 51960
Gerrit-PatchSet: 1
Gerrit-Owner: Khem Raj
Gerrit-MessageType: newchange
Attention is currently required from: David Hendricks, Edward O'Callaghan, Angel Pons, Anastasia Klimchuk.
Nico Huber has posted comments on this change. ( https://review.coreboot.org/c/flashrom/+/51243 )
Change subject: Enable dynamic memory allocation checks for cmocka unit tests
......................................................................
Patch Set 6: Code-Review+1
(5 comments)
Patchset:
PS6:
> Even better news: now after adding includes in meson. […]
This looks quite nice now, thank you!
Only one remark, the -DUNIT_TESt_ENV. Do we still need it?
About `unittest.h`, I'm not sure if I fully understood its role. Maybe
the idea is to not test allocations that are done by the tests itself?
i.e. the tests itself wouldn't have to be error free, only the tested
code has to be. As long as the tests work, that's fine. Just something
to keep in mind if the tests ever get more complex.
File meson.build:
https://review.coreboot.org/c/flashrom/+/51243/comment/7097eb6b_0bc3a179
PS6, Line 477: -include
Can we have spaces after -include? That should work, I guess :)
File tests/flashrom.c:
https://review.coreboot.org/c/flashrom/+/51243/comment/4b97477c_1f95e59c
PS2, Line 27: #define assert_string_not_equal_with_free(text, expected) \
> I tried to make it better, dropped _string (7 chars) and replaced free->and (1 char) so in total I r […]
Looks better indeed.
File tests/helpers.c:
https://review.coreboot.org/c/flashrom/+/51243/comment/038b3d6e_0dca9457
PS6, Line 21: #include <stdlib.h>
I'm not sure if we should remove this. The files under tests/
shouldn't have the -include arguments, right? It's probably
indirectly included by one of the header files above.
File tests/meson.build:
https://review.coreboot.org/c/flashrom/+/51243/comment/5b850bfb_8cc9a3bc
PS6, Line 38: '-DUNIT_TEST_ENV',
Is this still needed? Now that `unittest_env.h` is only when building
for tests, it seems redundant.
--
To view, visit https://review.coreboot.org/c/flashrom/+/51243
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-Change-Id: I0c6b6b8dc17aaee28640e3fca3d1fc9f7feabf5f
Gerrit-Change-Number: 51243
Gerrit-PatchSet: 6
Gerrit-Owner: Anastasia Klimchuk <aklm(a)chromium.org>
Gerrit-Reviewer: Angel Pons <th3fanbus(a)gmail.com>
Gerrit-Reviewer: Daniel Kurtz <djkurtz(a)google.com>
Gerrit-Reviewer: David Hendricks <david.hendricks(a)gmail.com>
Gerrit-Reviewer: Edward O'Callaghan <quasisec(a)chromium.org>
Gerrit-Reviewer: Nico Huber <nico.h(a)gmx.de>
Gerrit-Reviewer: build bot (Jenkins) <no-reply(a)coreboot.org>
Gerrit-CC: Daniel Kurtz <djkurtz(a)chromium.org>
Gerrit-CC: Paul Menzel <paulepanter(a)users.sourceforge.net>
Gerrit-CC: Thomas Heijligen <src(a)posteo.de>
Gerrit-CC: Victor Ding <victording(a)chromium.org>
Gerrit-Attention: David Hendricks <david.hendricks(a)gmail.com>
Gerrit-Attention: Edward O'Callaghan <quasisec(a)chromium.org>
Gerrit-Attention: Angel Pons <th3fanbus(a)gmail.com>
Gerrit-Attention: Anastasia Klimchuk <aklm(a)chromium.org>
Gerrit-Comment-Date: Tue, 30 Mar 2021 22:15:20 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: Yes
Comment-In-Reply-To: Nico Huber <nico.h(a)gmx.de>
Comment-In-Reply-To: Anastasia Klimchuk <aklm(a)chromium.org>
Gerrit-MessageType: comment
Attention is currently required from: Nico Huber, Edward O'Callaghan, Daniel Campello.
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/flashrom/+/51930 )
Change subject: Makefile,meson.build: Fix dependency issues with raiden_debug_spi
......................................................................
Patch Set 1: Code-Review+1
(1 comment)
Commit Message:
https://review.coreboot.org/c/flashrom/+/51930/comment/6444aae5_d762504f
PS1, Line 10: gnu make
I'm not sure if our Makefile is GNU-specific. I'd just say `Makefile` instead
--
To view, visit https://review.coreboot.org/c/flashrom/+/51930
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-Change-Id: I2d6a8c33a2228abf006a9b278bcb7133765c7074
Gerrit-Change-Number: 51930
Gerrit-PatchSet: 1
Gerrit-Owner: Edward O'Callaghan <quasisec(a)chromium.org>
Gerrit-Reviewer: Angel Pons <th3fanbus(a)gmail.com>
Gerrit-Reviewer: Daniel Campello <campello(a)chromium.org>
Gerrit-Reviewer: Nico Huber <nico.h(a)gmx.de>
Gerrit-Reviewer: build bot (Jenkins) <no-reply(a)coreboot.org>
Gerrit-Attention: Nico Huber <nico.h(a)gmx.de>
Gerrit-Attention: Edward O'Callaghan <quasisec(a)chromium.org>
Gerrit-Attention: Daniel Campello <campello(a)chromium.org>
Gerrit-Comment-Date: Tue, 30 Mar 2021 08:20:50 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: Yes
Gerrit-MessageType: comment
Attention is currently required from: Nico Huber, Edward O'Callaghan.
Anastasia Klimchuk has posted comments on this change. ( https://review.coreboot.org/c/flashrom/+/51731 )
Change subject: tree: Remove forward-declarations of structs for spi masters
......................................................................
Patch Set 2:
(1 comment)
Patchset:
PS1:
> +1 to Nico's suggestion, that is precisely how we check these things. […]
Thank you! I will test like this in future.
What I got comparing before and after:
objdump -d is identical
objdump -s only difference is version number
30362,30363c30362,30363
< 00d0 76312e32 2d323233 2d676138 33303136 v1.2-223-ga83016
< 00e0 3600 6.
---
> 00d0 76312e32 2d323234 2d673062 63306631 v1.2-224-g0bc0f1
> 00e0 6500 e.
I don't see the difference in .note.gnu.build-id , do you know why (the difference Nico sees and I don't have it)?
--
To view, visit https://review.coreboot.org/c/flashrom/+/51731
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-Change-Id: I256bd7c763efc010fc1f29f7c5853f150ac10739
Gerrit-Change-Number: 51731
Gerrit-PatchSet: 2
Gerrit-Owner: Anastasia Klimchuk <aklm(a)chromium.org>
Gerrit-Reviewer: Angel Pons <th3fanbus(a)gmail.com>
Gerrit-Reviewer: Edward O'Callaghan <quasisec(a)chromium.org>
Gerrit-Reviewer: Nico Huber <nico.h(a)gmx.de>
Gerrit-Reviewer: build bot (Jenkins) <no-reply(a)coreboot.org>
Gerrit-Attention: Nico Huber <nico.h(a)gmx.de>
Gerrit-Attention: Edward O'Callaghan <quasisec(a)chromium.org>
Gerrit-Comment-Date: Tue, 30 Mar 2021 05:28:46 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Nico Huber <nico.h(a)gmx.de>
Comment-In-Reply-To: Edward O'Callaghan <quasisec(a)chromium.org>
Gerrit-MessageType: comment
Attention is currently required from: Nico Huber, Anastasia Klimchuk.
Hello build bot (Jenkins), Nico Huber, Edward O'Callaghan, Angel Pons,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/flashrom/+/51731
to look at the new patch set (#2).
Change subject: tree: Remove forward-declarations of structs for spi masters
......................................................................
tree: Remove forward-declarations of structs for spi masters
Reorder functions to avoid forward-declarations of structs. Similar
thing was done earlier for functions declarations, this patch takes
care of structs declarations.
BUG=b:140394053
TEST=builds
objdump -d is identical
objdump -s only difference is version number
Change-Id: I256bd7c763efc010fc1f29f7c5853f150ac10739
Signed-off-by: Anastasia Klimchuk <aklm(a)chromium.org>
---
M mstarddc_spi.c
M ni845x_spi.c
M usbblaster_spi.c
3 files changed, 218 insertions(+), 225 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/31/51731/2
--
To view, visit https://review.coreboot.org/c/flashrom/+/51731
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-Change-Id: I256bd7c763efc010fc1f29f7c5853f150ac10739
Gerrit-Change-Number: 51731
Gerrit-PatchSet: 2
Gerrit-Owner: Anastasia Klimchuk <aklm(a)chromium.org>
Gerrit-Reviewer: Angel Pons <th3fanbus(a)gmail.com>
Gerrit-Reviewer: Edward O'Callaghan <quasisec(a)chromium.org>
Gerrit-Reviewer: Nico Huber <nico.h(a)gmx.de>
Gerrit-Reviewer: build bot (Jenkins) <no-reply(a)coreboot.org>
Gerrit-Attention: Nico Huber <nico.h(a)gmx.de>
Gerrit-Attention: Anastasia Klimchuk <aklm(a)chromium.org>
Gerrit-MessageType: newpatchset
Edward O'Callaghan has uploaded this change for review. ( https://review.coreboot.org/c/flashrom/+/38209 )
Change subject: raiden_debug: Upstream ChromiumOS servo debug board prog
......................................................................
raiden_debug: Upstream ChromiumOS servo debug board prog
Initial check-in of the Raiden debugger programmer.
Squash in,
usb_device: needed for raiden_debug prog
BUG=b:143389556
BRANCH=none
TEST=builds
Change-Id: Ifad273a708acea4de797a0808be58960635a8864
Signed-off-by: Edward O'Callaghan <quasisec(a)google.com>
---
M Makefile
M flashrom.c
M meson.build
M meson_options.txt
M programmer.h
A raiden_debug_spi.c
A usb_device.c
A usb_device.h
8 files changed, 977 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/09/38209/1
diff --git a/Makefile b/Makefile
index 7242b09..e8ca7a8 100644
--- a/Makefile
+++ b/Makefile
@@ -226,6 +226,11 @@
else
override CONFIG_RAYER_SPI = no
endif
+ifeq ($(CONFIG_RAIDEN), yes)
+UNSUPPORTED_FEATURES += CONFIG_RAIDEN=yes
+else
+override CONFIG_RAIDEN = no
+endif
ifeq ($(CONFIG_NIC3COM), yes)
UNSUPPORTED_FEATURES += CONFIG_NIC3COM=yes
else
@@ -607,6 +612,9 @@
# RayeR SPIPGM hardware support
CONFIG_RAYER_SPI ?= yes
+# ChromiumOS servo DUT debug board hardware support
+CONFIG_RAIDEN ?= yes
+
# PonyProg2000 SPI hardware support
CONFIG_PONY_SPI ?= yes
@@ -817,6 +825,11 @@
NEED_RAW_ACCESS += CONFIG_RAYER_SPI
endif
+ifeq ($(CONFIG_RAIDEN), yes)
+FEATURE_CFLAGS += -D'CONFIG_RAIDEN=1'
+PROGRAMMER_OBJS += raiden_debug_spi.o usb_device.o
+endif
+
ifeq ($(CONFIG_PONY_SPI), yes)
FEATURE_CFLAGS += -D'CONFIG_PONY_SPI=1'
PROGRAMMER_OBJS += pony_spi.o
diff --git a/flashrom.c b/flashrom.c
index e540027..e541b68 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -133,6 +133,18 @@
},
#endif
+#if CONFIG_RAIDEN == 1
+ {
+ .name = "raiden_debug",
+ .type = USB,
+ .devs.note = "All programmer devices speaking the raiden protocol\n",
+ .init = raiden_debug_spi_init,
+ .map_flash_region = fallback_map,
+ .unmap_flash_region = fallback_unmap,
+ .delay = internal_delay,
+ },
+#endif
+
#if CONFIG_DRKAISER == 1
{
.name = "drkaiser",
diff --git a/meson.build b/meson.build
index 375089c..88b14cf 100644
--- a/meson.build
+++ b/meson.build
@@ -42,6 +42,7 @@
config_dummy = get_option('config_dummy')
config_ft2232_spi = get_option('config_ft2232_spi')
config_gfxnvidia = get_option('config_gfxnvidia')
+config_raiden = get_option('config_raiden')
config_internal = get_option('config_internal')
config_it8212 = get_option('config_it8212')
config_linux_mtd = get_option('config_linux_mtd')
@@ -104,6 +105,7 @@
config_atavia = false
config_drkaiser = false
config_gfxnvidia = false
+ config_raiden = false
config_internal = false
config_it8212 = false
config_nic3com = false
@@ -170,6 +172,11 @@
srcs += 'gfxnvidia.c'
cargs += '-DCONFIG_GFXNVIDIA=1'
endif
+if config_raiden
+ srcs += 'raiden_debug_spi.c'
+ srcs += 'usb_device.c'
+ cargs += '-DCONFIG_RAIDEN=1'
+endif
if config_internal
srcs += 'board_enable.c'
srcs += 'cbtable.c'
diff --git a/meson_options.txt b/meson_options.txt
index b7633d0..4334814 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -13,6 +13,7 @@
option('config_dummy', type : 'boolean', value : true, description : 'dummy tracing')
option('config_ft2232_spi', type : 'boolean', value : true, description : 'FT2232 SPI dongles')
option('config_gfxnvidia', type : 'boolean', value : true, description : 'NVIDIA graphics cards')
+option('config_raiden', type : 'boolean', value : true, description : 'ChromiumOS Servo DUT debug board')
option('config_internal', type : 'boolean', value : true, description : 'internal/onboard')
option('config_internal_dmi', type : 'boolean', value : true, description : 'Use internal DMI parser')
option('config_it8212', type : 'boolean', value : true, description : 'ITE IT8212F PATA')
diff --git a/programmer.h b/programmer.h
index 3cf53b9..08500c6 100644
--- a/programmer.h
+++ b/programmer.h
@@ -43,6 +43,9 @@
#if CONFIG_GFXNVIDIA == 1
PROGRAMMER_GFXNVIDIA,
#endif
+#if CONFIG_RAIDEN == 1
+ PROGRAMMER_RAIDEN,
+#endif
#if CONFIG_DRKAISER == 1
PROGRAMMER_DRKAISER,
#endif
@@ -401,6 +404,11 @@
extern const struct dev_entry gfx_nvidia[];
#endif
+/* raiden_debug_spi.c */
+#if CONFIG_RAIDEN == 1
+int raiden_debug_spi_init(void);
+#endif
+
/* drkaiser.c */
#if CONFIG_DRKAISER == 1
int drkaiser_init(void);
diff --git a/raiden_debug_spi.c b/raiden_debug_spi.c
new file mode 100644
index 0000000..9af0f7d
--- /dev/null
+++ b/raiden_debug_spi.c
@@ -0,0 +1,369 @@
+/*
+ * This file is part of the flashrom project.
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ */
+
+/*
+ * This SPI flash programming interface is designed to talk to a Chromium OS
+ * device over a Raiden USB connection. The USB connection is routed to a
+ * microcontroller running an image compiled from:
+ *
+ * https://chromium.googlesource.com/chromiumos/platform/ec
+ *
+ * The protocol for the USB-SPI bridge is documented in the following file in
+ * that respository:
+ *
+ * chip/stm32/usb_spi.c
+ */
+
+#include "programmer.h"
+#include "spi.h"
+#include "usb_device.h"
+
+#include <libusb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define GOOGLE_VID 0x18D1
+#define GOOGLE_RAIDEN_SPI_SUBCLASS 0x51
+#define GOOGLE_RAIDEN_SPI_PROTOCOL 0x01
+
+enum raiden_debug_spi_request {
+ RAIDEN_DEBUG_SPI_REQ_ENABLE = 0x0000,
+ RAIDEN_DEBUG_SPI_REQ_DISABLE = 0x0001,
+ RAIDEN_DEBUG_SPI_REQ_ENABLE_AP = 0x0002,
+ RAIDEN_DEBUG_SPI_REQ_ENABLE_EC = 0x0003,
+};
+
+#define PACKET_HEADER_SIZE 2
+#define MAX_PACKET_SIZE 64
+
+/*
+ * This timeout is so large because the Raiden SPI timeout is 800ms.
+ */
+#define TRANSFER_TIMEOUT_MS 1000
+
+struct usb_device *device = NULL;
+uint8_t in_endpoint = 0;
+uint8_t out_endpoint = 0;
+
+static int send_command(struct flashctx *flash,
+ unsigned int write_count,
+ unsigned int read_count,
+ const unsigned char *write_buffer,
+ unsigned char *read_buffer)
+{
+ uint8_t buffer[MAX_PACKET_SIZE];
+ int transferred;
+
+ if (write_count > MAX_PACKET_SIZE - PACKET_HEADER_SIZE) {
+ msg_perr("Raiden: invalid write_count of %d\n", write_count);
+ return SPI_INVALID_LENGTH;
+ }
+
+ if (read_count > MAX_PACKET_SIZE - PACKET_HEADER_SIZE) {
+ msg_perr("Raiden: invalid read_count of %d\n", read_count);
+ return SPI_INVALID_LENGTH;
+ }
+
+ buffer[0] = write_count;
+ buffer[1] = read_count;
+
+ memcpy(buffer + PACKET_HEADER_SIZE, write_buffer, write_count);
+
+ CHECK(LIBUSB(libusb_bulk_transfer(device->handle,
+ out_endpoint,
+ buffer,
+ write_count + PACKET_HEADER_SIZE,
+ &transferred,
+ TRANSFER_TIMEOUT_MS)),
+ "Raiden: OUT transfer failed\n"
+ " write_count = %d\n"
+ " read_count = %d\n",
+ write_count,
+ read_count);
+
+ if ((unsigned) transferred != write_count + PACKET_HEADER_SIZE) {
+ msg_perr("Raiden: Write failure (wrote %d, expected %d)\n",
+ transferred, write_count + PACKET_HEADER_SIZE);
+ return 0x10001;
+ }
+
+ CHECK(LIBUSB(libusb_bulk_transfer(device->handle,
+ in_endpoint,
+ buffer,
+ read_count + PACKET_HEADER_SIZE,
+ &transferred,
+ TRANSFER_TIMEOUT_MS)),
+ "Raiden: IN transfer failed\n"
+ " write_count = %d\n"
+ " read_count = %d\n",
+ write_count,
+ read_count);
+
+ if ((unsigned) transferred != read_count + PACKET_HEADER_SIZE) {
+ msg_perr("Raiden: Read failure (read %d, expected %d)\n",
+ transferred, read_count + PACKET_HEADER_SIZE);
+ return 0x10002;
+ }
+
+ memcpy(read_buffer, buffer + PACKET_HEADER_SIZE, read_count);
+
+ return buffer[0] | (buffer[1] << 8);
+}
+
+/*
+ * Unfortunately there doesn't seem to be a way to specify the maximum number
+ * of bytes that your SPI device can read/write, these values are the maximum
+ * data chunk size that flashrom will package up with an additional five bytes
+ * of command for the flash device, resulting in a 62 byte packet, that we then
+ * add two bytes to in either direction, making our way up to the 64 byte
+ * maximum USB packet size for the device.
+ *
+ * The largest command that flashrom generates is the byte program command, so
+ * we use that command header maximum size here.
+ */
+#define MAX_DATA_SIZE (MAX_PACKET_SIZE - \
+ PACKET_HEADER_SIZE - \
+ JEDEC_BYTE_PROGRAM_OUTSIZE)
+
+static const struct spi_master spi_master_raiden_debug = {
+ .features = SPI_MASTER_4BA,
+ .max_data_read = MAX_DATA_SIZE,
+ .max_data_write = MAX_DATA_SIZE,
+ .command = send_command,
+ .multicommand = default_spi_send_multicommand,
+ .read = default_spi_read,
+ .write_256 = default_spi_write_256,
+};
+
+static int match_endpoint(struct libusb_endpoint_descriptor const *descriptor,
+ enum libusb_endpoint_direction direction)
+{
+ return (((descriptor->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) ==
+ direction) &&
+ ((descriptor->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) ==
+ LIBUSB_TRANSFER_TYPE_BULK));
+}
+
+static int find_endpoints(struct usb_device *dev, uint8_t *in_ep, uint8_t *out_ep)
+{
+ int i;
+ int in_count = 0;
+ int out_count = 0;
+
+ for (i = 0; i < dev->interface_descriptor->bNumEndpoints; i++) {
+ struct libusb_endpoint_descriptor const *endpoint =
+ &dev->interface_descriptor->endpoint[i];
+
+ if (match_endpoint(endpoint, LIBUSB_ENDPOINT_IN)) {
+ in_count++;
+ *in_ep = endpoint->bEndpointAddress;
+ } else if (match_endpoint(endpoint, LIBUSB_ENDPOINT_OUT)) {
+ out_count++;
+ *out_ep = endpoint->bEndpointAddress;
+ }
+ }
+
+ if (in_count != 1 || out_count != 1) {
+ msg_perr("Raiden: Failed to find one IN and one OUT endpoint\n"
+ " found %d IN and %d OUT endpoints\n",
+ in_count,
+ out_count);
+ return 1;
+ }
+
+ msg_pdbg("Raiden: Found IN endpoint = 0x%02x\n", *in_ep);
+ msg_pdbg("Raiden: Found OUT endpoint = 0x%02x\n", *out_ep);
+
+ return 0;
+}
+
+static int shutdown(void * data)
+{
+ CHECK(LIBUSB(libusb_control_transfer(
+ device->handle,
+ LIBUSB_ENDPOINT_OUT |
+ LIBUSB_REQUEST_TYPE_VENDOR |
+ LIBUSB_RECIPIENT_INTERFACE,
+ RAIDEN_DEBUG_SPI_REQ_DISABLE,
+ 0,
+ device->interface_descriptor->bInterfaceNumber,
+ NULL,
+ 0,
+ TRANSFER_TIMEOUT_MS)),
+ "Raiden: Failed to disable SPI bridge\n");
+
+ usb_device_free(device);
+
+ device = NULL;
+ libusb_exit(NULL);
+
+ return 0;
+}
+
+static int get_target()
+{
+ int request_enable = RAIDEN_DEBUG_SPI_REQ_ENABLE;
+
+ char *target_str = extract_programmer_param("target");
+ if (target_str) {
+ if (!strcasecmp(target_str, "ap"))
+ request_enable = RAIDEN_DEBUG_SPI_REQ_ENABLE_AP;
+ else if (!strcasecmp(target_str, "ec"))
+ request_enable = RAIDEN_DEBUG_SPI_REQ_ENABLE_EC;
+ else {
+ msg_perr("Invalid target: %s\n", target_str);
+ request_enable = -1;
+ }
+ }
+ free(target_str);
+
+ return request_enable;
+}
+
+static void free_dev_list(struct usb_device **dev_lst)
+{
+ struct usb_device *dev = *dev_lst;
+ /* free devices we don't care about */
+ dev = dev->next;
+ while (dev)
+ dev = usb_device_free(dev);
+}
+
+int raiden_debug_spi_init(void)
+{
+ struct usb_match match;
+ char *serial = extract_programmer_param("serial");
+ struct usb_device *current;
+ int found = 0;
+
+ int request_enable = get_target();
+ if (request_enable < 0)
+ return 1;
+
+ usb_match_init(&match);
+
+ usb_match_value_default(&match.vid, GOOGLE_VID);
+ usb_match_value_default(&match.class, LIBUSB_CLASS_VENDOR_SPEC);
+ usb_match_value_default(&match.subclass, GOOGLE_RAIDEN_SPI_SUBCLASS);
+ usb_match_value_default(&match.protocol, GOOGLE_RAIDEN_SPI_PROTOCOL);
+
+ CHECK(LIBUSB(libusb_init(NULL)), "Raiden: libusb_init failed\n");
+
+ CHECK(usb_device_find(&match, ¤t),
+ "Raiden: Failed to find devices\n");
+
+ while (current) {
+ device = current;
+
+ if (find_endpoints(device, &in_endpoint, &out_endpoint)) {
+ msg_pdbg("Raiden: Failed to find valid endpoints on device");
+ usb_device_show(" ", current);
+ goto loop_end;
+ }
+
+ if (usb_device_claim(device)) {
+ msg_pdbg("Raiden: Failed to claim USB device");
+ usb_device_show(" ", current);
+ goto loop_end;
+ }
+
+ if (!serial) {
+ found = 1;
+ goto loop_end;
+ } else {
+ unsigned char dev_serial[32];
+ struct libusb_device_descriptor descriptor;
+ int rc;
+
+ memset(dev_serial, 0, sizeof(dev_serial));
+
+ if (libusb_get_device_descriptor(device->device, &descriptor)) {
+ msg_pdbg("USB: Failed to get device descriptor.\n");
+ goto loop_end;
+ }
+
+ rc = libusb_get_string_descriptor_ascii(device->handle,
+ descriptor.iSerialNumber,
+ dev_serial,
+ sizeof(dev_serial));
+ if (rc < 0) {
+ LIBUSB(rc);
+ } else {
+ if (strcmp(serial, (char *)dev_serial)) {
+ msg_pdbg("Raiden: Serial number %s did not match device", serial);
+ usb_device_show(" ", current);
+ } else {
+ msg_pinfo("Raiden: Serial number %s matched device", serial);
+ usb_device_show(" ", current);
+ found = 1;
+ }
+ }
+ }
+
+loop_end:
+ if (found)
+ break;
+ else
+ current = usb_device_free(current);
+ }
+
+ if (!device || !found) {
+ msg_perr("Raiden: No usable device found.\n");
+ return 1;
+ }
+
+ free_dev_list(¤t);
+
+ CHECK(LIBUSB(libusb_control_transfer(
+ device->handle,
+ LIBUSB_ENDPOINT_OUT |
+ LIBUSB_REQUEST_TYPE_VENDOR |
+ LIBUSB_RECIPIENT_INTERFACE,
+ request_enable,
+ 0,
+ device->interface_descriptor->bInterfaceNumber,
+ NULL,
+ 0,
+ TRANSFER_TIMEOUT_MS)),
+ "Raiden: Failed to enable SPI bridge\n");
+
+ register_spi_master(&spi_master_raiden_debug);
+ register_shutdown(shutdown, NULL);
+
+ return 0;
+}
diff --git a/usb_device.c b/usb_device.c
new file mode 100644
index 0000000..0909694
--- /dev/null
+++ b/usb_device.c
@@ -0,0 +1,366 @@
+/*
+ * This file is part of the flashrom project.
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ */
+
+#include "programmer.h"
+#include "spi.h"
+#include "usb_device.h"
+
+#include <assert.h>
+#include <libusb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+ * Possibly extract a programmer parameter and use it to initialize the given
+ * match value structure.
+ */
+static void usb_match_value_init(struct usb_match_value *match,
+ char const *parameter)
+{
+ char *string = extract_programmer_param(parameter);
+
+ match->name = parameter;
+
+ if (string) {
+ match->set = 1;
+ match->value = strtol(string, NULL, 0);
+ } else {
+ match->set = 0;
+ }
+
+ free(string);
+}
+
+#define USB_MATCH_VALUE_INIT(NAME) \
+ usb_match_value_init(&match->NAME, #NAME)
+
+void usb_match_init(struct usb_match *match)
+{
+ USB_MATCH_VALUE_INIT(vid);
+ USB_MATCH_VALUE_INIT(pid);
+ USB_MATCH_VALUE_INIT(bus);
+ USB_MATCH_VALUE_INIT(address);
+ USB_MATCH_VALUE_INIT(config);
+ USB_MATCH_VALUE_INIT(interface);
+ USB_MATCH_VALUE_INIT(altsetting);
+ USB_MATCH_VALUE_INIT(class);
+ USB_MATCH_VALUE_INIT(subclass);
+ USB_MATCH_VALUE_INIT(protocol);
+}
+
+void usb_match_value_default(struct usb_match_value *value,
+ long int default_value)
+{
+ if (value->set)
+ return;
+
+ value->set = 1;
+ value->value = default_value;
+}
+
+/*
+ * Match the value against a possible user supplied parameter.
+ *
+ * Return:
+ * 0: The user supplied the given parameter and it did not match the value.
+ * 1: Either the user didn't supply the parameter, or they did and it
+ * matches the given value.
+ */
+static int check_match(struct usb_match_value const *match_value, int value)
+{
+ int reject = match_value->set && (match_value->value != value);
+
+ if (reject)
+ msg_pdbg("USB: Rejecting device because %s = %d != %d\n",
+ match_value->name,
+ value,
+ match_value->value);
+
+ return !reject;
+}
+
+/*
+ * Allocate a copy of device and add it to the head of the devices list.
+ */
+static void add_device(struct usb_device *device,
+ struct usb_device **devices)
+{
+ struct usb_device *copy = malloc(sizeof(struct usb_device));
+
+ assert(copy != NULL);
+
+ *copy = *device;
+
+ copy->next = *devices;
+ *devices = copy;
+
+ libusb_ref_device(copy->device);
+}
+
+/*
+ * Look through the interfaces of the current device config for a match. Stop
+ * looking after the first valid match is found.
+ *
+ * Return:
+ * 0: No matching interface was found.
+ * 1: A complete match was found and added to the devices list.
+ */
+static int find_interface(struct usb_match const *match,
+ struct usb_device *current,
+ struct usb_device **devices)
+{
+ int i, j;
+
+ for (i = 0; i < current->config_descriptor->bNumInterfaces; ++i) {
+ struct libusb_interface const *interface;
+
+ interface = ¤t->config_descriptor->interface[i];
+
+ for (j = 0; j < interface->num_altsetting; ++j) {
+ struct libusb_interface_descriptor const *descriptor;
+
+ descriptor = &interface->altsetting[j];
+
+ if (check_match(&match->interface,
+ descriptor->bInterfaceNumber) &&
+ check_match(&match->altsetting,
+ descriptor->bAlternateSetting) &&
+ check_match(&match->class,
+ descriptor->bInterfaceClass) &&
+ check_match(&match->subclass,
+ descriptor->bInterfaceSubClass) &&
+ check_match(&match->protocol,
+ descriptor->bInterfaceProtocol)) {
+ current->interface_descriptor = descriptor;
+ add_device(current, devices);
+ msg_pdbg("USB: Found matching device\n");
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Look through the configs of the current device for a match. Stop looking
+ * after the first valid match is found.
+ *
+ * Return:
+ * 0: All configurations successfully checked, one may have been added to
+ * the list.
+ * non-zero: There was a failure while checking for a match.
+ */
+static int find_config(struct usb_match const *match,
+ struct usb_device *current,
+ struct libusb_device_descriptor const *device_descriptor,
+ struct usb_device **devices)
+{
+ int i;
+
+ for (i = 0; i < device_descriptor->bNumConfigurations; ++i) {
+ CHECK(LIBUSB(libusb_get_config_descriptor(
+ current->device,
+ i,
+ ¤t->config_descriptor)),
+ "USB: Failed to get config descriptor");
+
+ if (check_match(&match->config,
+ current->config_descriptor->
+ bConfigurationValue) &&
+ find_interface(match, current, devices))
+ break;
+
+ libusb_free_config_descriptor(current->config_descriptor);
+ }
+
+ return 0;
+}
+
+int usb_device_find(struct usb_match const *match, struct usb_device **devices)
+{
+ libusb_device **list;
+ size_t count;
+ size_t i;
+
+ *devices = NULL;
+
+ CHECK(LIBUSB(count = libusb_get_device_list(NULL, &list)),
+ "USB: Failed to get device list");
+
+ for (i = 0; i < count; ++i) {
+ struct libusb_device_descriptor descriptor;
+ struct usb_device current = {
+ .device = list[i],
+ .handle = NULL,
+ .next = NULL,
+ };
+
+ uint8_t bus = libusb_get_bus_number(list[i]);
+ uint8_t address = libusb_get_device_address(list[i]);
+
+ msg_pdbg("USB: Inspecting device (Bus %d, Address %d)\n",
+ bus,
+ address);
+
+ CHECK(LIBUSB(libusb_get_device_descriptor(list[i],
+ &descriptor)),
+ "USB: Failed to get device descriptor");
+
+ if (check_match(&match->vid, descriptor.idVendor) &&
+ check_match(&match->pid, descriptor.idProduct) &&
+ check_match(&match->bus, bus) &&
+ check_match(&match->address, address))
+ CHECK(find_config(match,
+ ¤t,
+ &descriptor,
+ devices),
+ "USB: Failed to find config");
+ }
+
+ libusb_free_device_list(list, 1);
+
+ return (*devices == NULL);
+}
+
+/*
+ * If the underlying libusb device is not open, open it.
+ *
+ * Return:
+ * 0: The device was already open or was successfully opened.
+ * non-zero: There was a failure while opening the device.
+ */
+static int usb_device_open(struct usb_device *device)
+{
+ if (device->handle == NULL)
+ CHECK(LIBUSB(libusb_open(device->device, &device->handle)),
+ "USB: Failed to open device\n");
+
+ return 0;
+}
+
+int usb_device_show(char const *prefix, struct usb_device *device)
+{
+ struct libusb_device_descriptor descriptor;
+ unsigned char product[256];
+
+ CHECK(usb_device_open(device), "USB: Failed to open device\n");
+
+ CHECK(LIBUSB(libusb_get_device_descriptor(device->device, &descriptor)),
+ "USB: Failed to get device descriptor\n");
+
+ CHECK(LIBUSB(libusb_get_string_descriptor_ascii(
+ device->handle,
+ descriptor.iProduct,
+ product,
+ sizeof(product))),
+ "USB: Failed to get device product string\n");
+
+ product[255] = '\0';
+
+ msg_perr("%sbus=0x%02x,address=0x%02x | %s\n",
+ prefix,
+ libusb_get_bus_number(device->device),
+ libusb_get_device_address(device->device),
+ product);
+
+ return 0;
+}
+
+int usb_device_claim(struct usb_device *device)
+{
+ int current_config;
+
+ CHECK(usb_device_open(device), "USB: Failed to open device\n");
+
+ CHECK(LIBUSB(libusb_get_configuration(device->handle,
+ ¤t_config)),
+ "USB: Failed to get current device configuration\n");
+
+ if (current_config != device->config_descriptor->bConfigurationValue)
+ CHECK(LIBUSB(libusb_set_configuration(
+ device->handle,
+ device->
+ config_descriptor->
+ bConfigurationValue)),
+ "USB: Failed to set new configuration from %d to %d\n",
+ current_config,
+ device->config_descriptor->bConfigurationValue);
+
+ CHECK(LIBUSB(libusb_set_auto_detach_kernel_driver(device->handle, 1)),
+ "USB: Failed to enable auto kernel driver detach\n");
+
+ CHECK(LIBUSB(libusb_claim_interface(device->handle,
+ device->
+ interface_descriptor->
+ bInterfaceNumber)),
+ "USB: Could not claim device interface %d\n",
+ device->interface_descriptor->bInterfaceNumber);
+
+ if (device->interface_descriptor->bAlternateSetting != 0)
+ CHECK(LIBUSB(libusb_set_interface_alt_setting(
+ device->handle,
+ device->
+ interface_descriptor->
+ bInterfaceNumber,
+ device->
+ interface_descriptor->
+ bAlternateSetting)),
+ "USB: Failed to set alternate setting %d\n",
+ device->interface_descriptor->bAlternateSetting);
+
+ return 0;
+}
+
+struct usb_device *usb_device_free(struct usb_device *device)
+{
+ struct usb_device *next = device->next;
+
+ if (device->handle != NULL)
+ libusb_close(device->handle);
+
+ /*
+ * This unref balances the ref added in the add_device function.
+ */
+ libusb_unref_device(device->device);
+ libusb_free_config_descriptor(device->config_descriptor);
+
+ free(device);
+
+ return next;
+}
diff --git a/usb_device.h b/usb_device.h
new file mode 100644
index 0000000..46d2458
--- /dev/null
+++ b/usb_device.h
@@ -0,0 +1,201 @@
+/*
+ * This file is part of the flashrom project.
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ */
+
+/*
+ * USB device matching framework
+ *
+ * This can be used to match a USB device by a number of different parameters.
+ * The parameters can be passed on the command line and defaults can be set
+ * by the programmer.
+ */
+
+#include <libusb.h>
+#include <stdint.h>
+
+/*
+ * Check Macro
+ *
+ * The check macro simplifies common return error code checking logic. If the
+ * expression does not evaluate to zero then the string error is printed and
+ * the expressions result is imediately returned, else the result is available
+ * as the value of the CHECK expression statement.
+ */
+
+#define CHECK(expression, string...) \
+ ({ \
+ int error__ = (expression); \
+ \
+ if (error__ != 0) { \
+ msg_perr(string); \
+ return error__; \
+ } \
+ \
+ error__; \
+ })
+
+/*
+ * The LIBUSB macro converts a libusb failure code into an error code that
+ * flashrom recognizes. It also displays additional libusb specific
+ * information about the failure.
+ */
+#define LIBUSB(expression) \
+ ({ \
+ int libusb_error__ = (expression); \
+ \
+ if (libusb_error__ < 0) { \
+ msg_perr("libusb error: %s:%d %s\n", \
+ __FILE__, \
+ __LINE__, \
+ libusb_error_name(libusb_error__)); \
+ libusb_error__ = 0x20000 | -libusb_error__; \
+ } else { \
+ libusb_error__ = 0; \
+ } \
+ \
+ libusb_error__; \
+ })
+
+/*
+ * A USB match and associated value struct are used to encode the information
+ * about a device against which we wish to match. If the value of a
+ * usb_match_value has been set then a device must match that value. The name
+ * of the usb_match_value is used to fetch the programmer parameter from the
+ * flashrom command line and is the same as the name of the corresponding
+ * field in usb_match.
+ */
+struct usb_match_value {
+ char const *name;
+ int value;
+ int set;
+};
+
+struct usb_match {
+ struct usb_match_value bus;
+ struct usb_match_value address;
+ struct usb_match_value vid;
+ struct usb_match_value pid;
+ struct usb_match_value serial;
+ struct usb_match_value config;
+ struct usb_match_value interface;
+ struct usb_match_value altsetting;
+ struct usb_match_value class;
+ struct usb_match_value subclass;
+ struct usb_match_value protocol;
+};
+
+/*
+ * Initialize a usb_match structure so that each value's name matches the
+ * values name in the usb_match structure (so bus.name == "bus"...), and
+ * look for each value in the flashrom command line via
+ * extract_programmer_param. If the value is found convert it to an integer
+ * using strtol, accepting hex, decimal and octal encoding.
+ */
+void usb_match_init(struct usb_match *match);
+
+/*
+ * Add a default value to a usb_match_value. This must be done after calling
+ * usb_match_init. If usb_match_init already set the value of a usb_match_value
+ * we do nothing, otherwise set the value to default_value. This ensures that
+ * parameters passed on the command line override defaults.
+ */
+void usb_match_value_default(struct usb_match_value *match,
+ long int default_value);
+
+/*
+ * The usb_device structure is an entry in a linked list of devices that were
+ * matched by usb_device_find.
+ */
+struct usb_device {
+ struct libusb_device *device;
+ struct libusb_config_descriptor *config_descriptor;
+ struct libusb_interface_descriptor const *interface_descriptor;
+
+ /*
+ * Initially NULL, the libusb_device_handle is only valid once the
+ * usb_device has been successfully passed to usb_device_show or
+ * usb_device_claim.
+ */
+ struct libusb_device_handle *handle;
+
+ /*
+ * Link to next device, or NULL
+ */
+ struct usb_device *next;
+};
+
+/*
+ * Find and return a list of all compatible devices. Each device is added to
+ * the list with its first valid configuration and interface. If an alternate
+ * configuration (config, interface, altsetting...) is desired the specifics
+ * can be supplied as programmer parameters.
+ *
+ * Return:
+ * 0: At least one matching device was found.
+ * 1: No matching devices were found.
+ */
+int usb_device_find(struct usb_match const *match, struct usb_device **devices);
+
+/*
+ * Display the devices bus and address as well as its product string. The
+ * underlying libusb device is opened if it is not already open.
+ *
+ * Return:
+ * 0: The device information was displayed.
+ * non-zero: There was a failure while displaying the device information.
+ */
+int usb_device_show(char const *prefix, struct usb_device *device);
+
+/*
+ * Open the underlying libusb device, set its config, claim the interface and
+ * select the correct alternate interface.
+ *
+ * Return:
+ * 0: The device was successfully claimed.
+ * non-zero: There was a failure while trying to claim the device.
+ */
+int usb_device_claim(struct usb_device *device);
+
+/*
+ * Free a usb_device structure.
+ *
+ * This ensures that the libusb device is closed and that all allocated
+ * handles and descriptors are freed.
+ *
+ * Return:
+ * The next device in the device list.
+ */
+struct usb_device *usb_device_free(struct usb_device *device);
--
To view, visit https://review.coreboot.org/c/flashrom/+/38209
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-Change-Id: Ifad273a708acea4de797a0808be58960635a8864
Gerrit-Change-Number: 38209
Gerrit-PatchSet: 1
Gerrit-Owner: Edward O'Callaghan <quasisec(a)chromium.org>
Gerrit-MessageType: newchange