Hello,
I tested flashrom on an Attro G5G100-P industrial board.
Reading and writing the original BIOS were successful, both with the original
chip and a spare PLCC chip.
The logs are attached.
Christoph
remotely flashed, rebooted and worked
--
Gianluigi Tiesi <sherpya(a)netfarm.it>
EDP Project Leader
Netfarm S.r.l. - http://www.netfarm.it/
Free Software: http://oss.netfarm.it/
Q: Because it reverses the logical flow of conversation.
A: Why is putting a reply at the top of the message frowned upon?
Hello,
You have listed as a supported mainboard the x7spa-hf, it turns out
there is a very similar board that also works, the x7spe-hf-d525.
I just wanted to write to you to let you know so you could update your
supported mainboard page.
micah
On Sun, 24 Mar 2013 11:10:19 -0400
Justin Chevrier <jchevrier(a)gmail.com> wrote:
> From the 'You can never have enough programmers' file, comes support
> for another programmer type.
Supporting the internal one becomes more painful every day, so
expanding the support for external programmers is very welcomed, thanks!
> Specifically it's the PICkit2. This patch was inspired by the code in
> AVRDude (open source Atmel AVR
> programmer) to support the PICkit2 written by Doug Brown [1]. The
> Dediprog code in Flashrom was used
> as the template for this code with some reference to the ft2232 code
> as well. I left Carl-Daniel in
> the copyright assignment as I thought it made the most sense as I
> basically copied and pasted then
> modified the code as needed. Hopefully that was the right thing to do.
Sure, the copyright does not vanish when you copy some code to a new
file, so all previous copyright notices should be copied over too
(if one thinks they are useful at all... :)
> A few notes:
>
> 1) The code makes no provision for externally powered targets (where
> VDD from the PICkit can be connected to
> the device and an external power source and it will detect external
> power and not apply its own).
> I'm assuming that code needs to be written for this to work and that
> the PICkit itself doesn't make it happen
> automagically. Not sure on that one
I have *no* idea about that programmer or the protocol... but maybe
that's what the equivalent of voltage_selector = 0 is for?
>
> 2) I've tested with PICkit2 firmware version 2.32. I suspect that
> there are earlier versions of the
> firmware that are not capable of talking SPI, but I'm not sure. Should
> we include a warning if we detect
> that a user is running on older firmware and ask users to submit if
> their firmware version works
> for them?
Maybe... other programmers use their devices struct for such things. I
don't think dediprog is a good example in this regard.
> 3) I've only tested with the one easily accessible SPI chip I have on
> hand (GigaDevice GD25Q80)
>
> Connections are as follows:
>
> PICkit2 Pin 1 - VPP/MCLR -> CS
> PICkit2 Pin 2 - VDD -> Vcc
> PICkit2 Pin 3 - GND -> Vss
> PICkit2 Pin 4 - PGD -> SO
> PICkit2 Pin 5 - PDC -> SCLK
> PICkit2 Pin 6 - AUX -> SI
Creating a wiki page would be welcomed. If you want an account to do
that, just ask.
> Feedback welcomed! Hopefully this is useful to someone.
>
> Thanks for the great tools as always guys.
Thanks for your patch!
The following is not a full review, but I mention a few things I
spotted while skimming through. Feel free to ignore them (for now :) if
you don't agree.
> Index: Makefile
> ===================================================================
> --- Makefile (revision 1657)
> +++ Makefile (working copy)
> @@ -117,7 +117,7 @@
> else
> override CONFIG_PONY_SPI = no
> endif
> -# Dediprog and FT2232 are not supported under DOS (missing USB support).
> +# Dediprog, FT2232 and PICkit2 are not supported under DOS (missing USB support).
> ifeq ($(CONFIG_DEDIPROG), yes)
> UNSUPPORTED_FEATURES += CONFIG_DEDIPROG=yes
> else
> @@ -128,7 +128,12 @@
> else
> override CONFIG_FT2232_SPI = no
> endif
> +ifeq ($(CONFIG_PICKIT2_SPI), yes)
> +UNSUPPORTED_FEATURES += CONFIG_PICKIT2_SPI=yes
> +else
> +override CONFIG_PICKIT2_SPI = no
> endif
> +endif
>
> # FIXME: Should we check for Cygwin/MSVC as well?
> ifeq ($(TARGET_OS), MinGW)
> @@ -229,7 +234,7 @@
> else
> override CONFIG_SERPROG = no
> endif
> -# Dediprog and FT2232 are not supported with libpayload (missing libusb support)
> +# Dediprog, FT2232 and PICkit2 are not supported with libpayload (missing libusb support)
> ifeq ($(CONFIG_DEDIPROG), yes)
> UNSUPPORTED_FEATURES += CONFIG_DEDIPROG=yes
> else
> @@ -240,7 +245,12 @@
> else
> override CONFIG_FT2232_SPI = no
> endif
> +ifeq ($(CONFIG_PICKIT2_SPI), yes)
> +UNSUPPORTED_FEATURES += CONFIG_PICKIT2_SPI=yes
> +else
> +override CONFIG_PICKIT2_SPI = no
> endif
> +endif
>
> ifneq ($(TARGET_OS), Linux)
> ifeq ($(CONFIG_LINUX_SPI), yes)
> @@ -382,6 +392,9 @@
> # Enable Linux spidev interface by default. We disable it on non-Linux targets.
> CONFIG_LINUX_SPI ?= yes
>
> +# Always enable PICkit2 SPI dongles for now.
> +CONFIG_PICKIT2_SPI ?= yes
> +
> # Disable wiki printing by default. It is only useful if you have wiki access.
> CONFIG_PRINT_WIKI ?= no
>
> @@ -549,6 +562,12 @@
> PROGRAMMER_OBJS += linux_spi.o
> endif
>
> +ifeq ($(CONFIG_PICKIT2_SPI), yes)
> +FEATURE_CFLAGS += -D'CONFIG_PICKIT2_SPI=1'
> +PROGRAMMER_OBJS += pickit2_spi.o
> +NEED_USB := yes
> +endif
> +
> ifeq ($(NEED_SERIAL), yes)
> LIB_OBJS += serial.o
> endif
> Index: flashrom.8
> ===================================================================
> --- flashrom.8 (revision 1657)
> +++ flashrom.8 (working copy)
> @@ -220,6 +220,8 @@
> .sp
> .BR "* linux_spi" " (for SPI flash ROMs accessible via /dev/spidevX.Y on Linux)"
> .sp
> +.BR "* pickit2_spi" " (for SPI flash ROMs accessible via Microchip PICkit2 on Linux)"
Linux only? I guess that's a copy & paste error and it will work whereever flashrom and libusb work.
> +.sp
> Some programmers have optional or mandatory parameters which are described
> in detail in the
> .B PROGRAMMER SPECIFIC INFO
TODO: explanation of programmer parameters in an detailed section.
> Index: flashrom.c
> ===================================================================
> --- flashrom.c (revision 1657)
> +++ flashrom.c (working copy)
> @@ -308,6 +308,19 @@
> },
> #endif
>
> +#if CONFIG_PICKIT2_SPI == 1
> + {
> + .name = "pickit2_spi",
> + .type = OTHER,
> + /* FIXME */
> + .devs.note = "Microchip PICkit2\n",
> + .init = pickit2_spi_init,
> + .map_flash_region = fallback_map,
> + .unmap_flash_region = fallback_unmap,
> + .delay = internal_delay,
> + },
> +#endif
> +
> {0}, /* This entry corresponds to PROGRAMMER_INVALID. */
> };
>
> Index: pickit2_spi.c
> ===================================================================
> --- pickit2_spi.c (revision 0)
> +++ pickit2_spi.c (working copy)
> @@ -0,0 +1,519 @@
> +/*
> + * This file is part of the flashrom project.
> + *
> + * Copyright (C) 2010 Carl-Daniel Hailfinger
> + * Copyright (C) 2013 Justin Chevrier
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; version 2 of the License.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
Links to or citations of relevant documentation should go here (or the
to be written manpage section, if useful to users too), at least a
reference to avrdude should be given IMHO, but feel free to be as
verbose as the commit log.
> +#include <stdio.h>
> +#include <string.h>
> +#include <limits.h>
> +#include <errno.h>
> +#include <usb.h>
> +#include "flash.h"
> +#include "chipdrivers.h"
> +#include "programmer.h"
> +#include "spi.h"
> +
> +static usb_dev_handle *pickit2_handle;
> +
> +#define DEFAULT_TIMEOUT 10000
which unit? when is it used? etc.
> +
> +#define CMD_LENGTH 64
> +#define ENDPOINT_OUT 0x01
> +#define ENDPOINT_IN 0x81
> +
> +#define PICKIT2_VID 0x04D8
> +#define PICKIT2_PID 0x0033
> +
> +#define CMD_GET_VERSION 0x76
> +#define CMD_SET_VDD 0xA0
> +#define CMD_SET_VPP 0xA1
> +#define CMD_READ_VDD_VPP 0xA3
> +#define CMD_EXEC_SCRIPT 0xA6
> +#define CMD_CLR_DLOAD_BUFF 0xA7
> +#define CMD_DOWNLOAD_DATA 0xA8
> +#define CMD_CLR_ULOAD_BUFF 0xA9
> +#define CMD_UPLOAD_DATA 0xAA
> +#define CMD_END_OF_BUFFER 0xAD
> +
> +#define SCR_SPI_READ_BUF 0xC5
> +#define SCR_SPI_WRITE_BUF 0xC6
> +#define SCR_SET_AUX 0xCF
> +#define SCR_LOOP 0xE9
> +#define SCR_SET_ICSP_CLK_PERIOD 0xEA
> +#define SCR_SET_PINS 0xF3
> +#define SCR_BUSY_LED_OFF 0xF4
> +#define SCR_BUSY_LED_ON 0xF5
> +#define SCR_MCLR_GND_OFF 0xF6
> +#define SCR_MCLR_GND_ON 0xF7
> +#define SCR_VPP_PWM_OFF 0xF8
> +#define SCR_VPP_PWM_ON 0xF9
> +#define SCR_VPP_OFF 0xFA
> +#define SCR_VPP_ON 0xFB
> +#define SCR_VDD_OFF 0xFE
> +#define SCR_VDD_ON 0xFF
> +
> +/* Might be useful for other USB devices as well. static for now. */
We need to sort stuff like this out, but that's not your problem.
> +/* device parameter allows user to specify one device of multiple installed */
> +static struct usb_device *get_device_by_vid_pid(uint16_t vid, uint16_t pid, unsigned int device)
> +{
> + struct usb_bus *bus;
> + struct usb_device *dev;
> +
> + for (bus = usb_get_busses(); bus; bus = bus->next)
> + for (dev = bus->devices; dev; dev = dev->next)
> + if ((dev->descriptor.idVendor == vid) &&
> + (dev->descriptor.idProduct == pid)) {
> + if (device == 0)
> + return dev;
> + device--;
> + }
> +
> + return NULL;
> +}
> +
> +static int pickit2_get_firmware_version(void)
> +{
> + int ret;
> + unsigned char command[CMD_LENGTH] = {CMD_GET_VERSION, CMD_END_OF_BUFFER};
> +
> + ret = usb_interrupt_write(pickit2_handle, ENDPOINT_OUT, (char *)command, CMD_LENGTH, DEFAULT_TIMEOUT);
> + ret = usb_interrupt_read(pickit2_handle, ENDPOINT_IN, (char *)command, CMD_LENGTH, DEFAULT_TIMEOUT);
> +
> + msg_pdbg("PICkit2 Firmware Version: %d.%d\n", (int)command[0], (int)command[1]);
> + if (ret != CMD_LENGTH) {
> + msg_perr("Command Get Firmware Version failed (%s)!\n",
> + usb_strerror());
> + return 1;
> + }
> +
> + return 0;
> +}
> +
> +static int pickit2_set_spi_voltage(int millivolt)
> +{
> + int ret;
> + uint16_t voltage_selector;
> […]
> + voltage_selector = 1.8;
that would be in the best case some "creative" usage of floating point constants. ;)
> […]
> +
> + unsigned char command[CMD_LENGTH] = {
I personally favor uint8_t instead of unsigned chars...
> + CMD_SET_VDD,
> + (uint8_t)(voltage_selector * 2048+672),
... especially if you cast to them anyway :)
> + (uint8_t)((voltage_selector * 2048+672)/256),
We normally add spaces around all binary ops.
> + (uint8_t)(voltage_selector * 36),
> + CMD_SET_VPP,
> + 0x40,
> + (uint8_t)(voltage_selector * 18.61),
I am not sure I want to understand that protocol better, if this is correct. :)
> + (uint8_t)(voltage_selector * 13),
> + CMD_END_OF_BUFFER
> + };
> +
> + ret = usb_interrupt_write(pickit2_handle, ENDPOINT_OUT, (char *)command, CMD_LENGTH, DEFAULT_TIMEOUT);
> +
> + if (ret != CMD_LENGTH) {
> + msg_perr("Command Set Voltage failed (%s)!\n",
> + usb_strerror());
> + return 1;
> + }
> +
> + return 0;
> +}
> +
> +
> +struct pickit2_spispeeds {
> + const char *const name;
> + const int speed;
> +};
> +
> +static const struct pickit2_spispeeds spispeeds[] = {
> + { "1M", 0x1 },
> + { "500k", 0x2 },
> + { "333k", 0x3 },
> + { "250k", 0x4 },
> + { NULL, 0x0 },
> +};
> +
> +static int pickit2_set_spi_speed(unsigned int spispeed_idx)
> +{
> + int ret;
> +
> + msg_pdbg("SPI speed is %sHz\n", spispeeds[spispeed_idx].name);
> +
> + unsigned char command[CMD_LENGTH] = {
> + CMD_EXEC_SCRIPT,
> + 2,
> + SCR_SET_ICSP_CLK_PERIOD,
> + spispeed_idx,
> + CMD_END_OF_BUFFER
> + };
> +
> + ret = usb_interrupt_write(pickit2_handle, ENDPOINT_OUT, (char *)command, CMD_LENGTH, DEFAULT_TIMEOUT);
> +
> + if (ret != CMD_LENGTH) {
> + msg_perr("Command Set SPI Speed failed (%s)!\n",
> + usb_strerror());
> + return 1;
> + }
> +
> + return 0;
> +}
> +
> +static int pickit2_spi_send_command(struct flashctx *flash,
> + unsigned int writecnt,
> + unsigned int readcnt,
> + const unsigned char *writearr,
> + unsigned char *readarr)
> +{
> + int ret,i;
> +
> + unsigned char buf[CMD_LENGTH] = {CMD_DOWNLOAD_DATA, writecnt};
> +
> + /* Maximum number of bytes per transaction (including command overhead) is 64. Lets play it safe
> + * and always assume the worst case scenario of 20 bytes command overhead.
> + */
> + msg_pspew("%s, writecnt=%i, readcnt=%i\n", __func__, writecnt, readcnt);
> + if (writecnt + readcnt + 20 > CMD_LENGTH) {
> + msg_perr("\nTotal packetsize (%i) is greater than 64 supported, aborting.\n", writecnt + readcnt + 20);
> + return 1;
> + }
> +
> + for (i = 2; i < writecnt + 2; i++)
> + {
The curly brace should be at the end of the "for line" according to our style.
> + buf[i] = writearr[i - 2];
> + }
> +
> + buf[i++] = CMD_CLR_ULOAD_BUFF;
> + buf[i++] = CMD_EXEC_SCRIPT;
> +
> + /* Determine script length based on number of bytes to be read or written */
> + if (writecnt == 1 && readcnt == 1)
> + buf[i++] = 7;
> + else if (writecnt == 1 || readcnt == 1)
> + buf[i++] = 10;
> + else
> + buf[i++] = 13;
> +
> + /* Assert CS# */
> + buf[i++] = SCR_VPP_OFF;
> + buf[i++] = SCR_MCLR_GND_ON;
> +
> + buf[i++] = SCR_SPI_WRITE_BUF;
> +
> + if (writecnt > 1) {
> + buf[i++] = SCR_LOOP;
> + buf[i++] = 1; /* Loop back one instruction */
> + buf[i++] = writecnt - 1; /* Number of times to loop */
> + }
> +
> + if (readcnt)
> + buf[i++] = SCR_SPI_READ_BUF;
> +
> + if (readcnt > 1) {
> + buf[i++] = SCR_LOOP;
> + buf[i++] = 1; /* Loop back one instruction */
> + buf[i++] = readcnt - 1; /* Number of times to loop */
> + }
> +
> + /* De-assert CS# */
> + buf[i++] = SCR_MCLR_GND_OFF;
> + buf[i++] = SCR_VPP_PWM_ON;
> + buf[i++] = SCR_VPP_ON;
> +
> + buf[i++] = CMD_UPLOAD_DATA;
> + buf[i++] = CMD_END_OF_BUFFER;
> +
> + ret = usb_interrupt_write(pickit2_handle, ENDPOINT_OUT, (char *)buf, CMD_LENGTH, DEFAULT_TIMEOUT);
> +
> + if (ret != CMD_LENGTH) {
> + msg_perr("Send SPI failed, expected %i, got %i %s!\n",
> + writecnt, ret, usb_strerror());
> + return 1;
> + }
> +
> + if (readcnt) {
> + memset(readarr, 0, readcnt);
> + memset(buf, 0, sizeof(buf));
Is this really necessary?
> +
> + ret = usb_interrupt_read(pickit2_handle, ENDPOINT_IN, (char *)buf, CMD_LENGTH, DEFAULT_TIMEOUT);
> +
> + if (ret != CMD_LENGTH) {
> + msg_perr("Receive SPI failed, expected %i, got %i %s!\n",
> + readcnt, ret, usb_strerror());
> + return 1;
> + }
> +
> + /* First byte indicates number of bytes transferred from upload buffer */
> + if (buf[0] != readcnt) {
> + msg_perr("Unexpected number of bytes transferred, expected %i, got %i!\n",
> + readcnt, ret);
> + return 1;
> + }
> +
> + /* Actual data starts at byte number two */
> + memcpy(readarr, &buf[1], readcnt);
> + }
> +
> + return 0;
> +}
> +
This is a candidate for a ultity "class" too, please add the "might be useful" comment here too:
/* Might be useful for other USB devices as well. static for now. */
And maybe add a reference to dediprog (and likewise for other copied
functions) so that we know immediately that they have been copied.
> +static int parse_voltage(char *voltage)
> +{
> + char *tmp = NULL;
> + int i;
> + int millivolt = 0, fraction = 0;
> +
> + if (!voltage || !strlen(voltage)) {
> + msg_perr("Empty voltage= specified.\n");
> + return -1;
> + }
> + millivolt = (int)strtol(voltage, &tmp, 0);
> + voltage = tmp;
> + /* Handle "," and "." as decimal point. Everything after it is assumed
> + * to be in decimal notation.
> + */
> + if ((*voltage == '.') || (*voltage == ',')) {
> + voltage++;
> + for (i = 0; i < 3; i++) {
> + fraction *= 10;
> + /* Don't advance if the current character is invalid,
> + * but continue multiplying.
> + */
> + if ((*voltage < '0') || (*voltage > '9'))
> + continue;
> + fraction += *voltage - '0';
> + voltage++;
> + }
> + /* Throw away remaining digits. */
> + voltage += strspn(voltage, "0123456789");
> + }
> + /* The remaining string must be empty or "mV" or "V". */
> + tolower_string(voltage);
> +
> + /* No unit or "V". */
> + if ((*voltage == '\0') || !strncmp(voltage, "v", 1)) {
> + millivolt *= 1000;
> + millivolt += fraction;
> + } else if (!strncmp(voltage, "mv", 2) ||
> + !strncmp(voltage, "milliv", 6)) {
> + /* No adjustment. fraction is discarded. */
> + } else {
> + /* Garbage at the end of the string. */
> + msg_perr("Garbage voltage= specified.\n");
> + return -1;
> + }
> + return millivolt;
> +}
> +
I think this function can be inlined without disadvantages. The comment
is clear enough.
OTOH it might be worth it if you can generify a pickit2_teardown or
similar (the code in the shutdown function).
> +static int pickit2_setup(void)
> +{
> + int ret;
> + /* Configure pins for correct directions and logic levels,
> + * turn Vdd on, turn busy LED on and clear buffers
> + */
> + unsigned char buf[CMD_LENGTH] = {
> + CMD_EXEC_SCRIPT,
> + 10, /* Script length */
> + SCR_SET_PINS,
> + /* Bit-0=0(PDC Out), Bit-1=1(PGD In), Bit-2=0(PDC LL), Bit-3=0(PGD LL) */
> + 2,
> + SCR_SET_AUX,
> + /* Bit-0=0(Aux Out), Bit-1=0(Aux LL) */
> + 0,
> + SCR_VDD_ON,
> + SCR_MCLR_GND_OFF, /* Let CS# float */
> + SCR_VPP_PWM_ON,
> + SCR_VPP_ON, /* Pull CS# high */
> + SCR_BUSY_LED_ON,
> + CMD_CLR_DLOAD_BUFF,
> + CMD_CLR_ULOAD_BUFF,
> + CMD_END_OF_BUFFER
> + };
> +
> + ret = usb_interrupt_write(pickit2_handle, ENDPOINT_OUT, (char *)buf, CMD_LENGTH, DEFAULT_TIMEOUT);
> +
> + if (ret != CMD_LENGTH) {
> + msg_perr("Command Setup failed (%s)!\n",
> + usb_strerror());
> + return 1;
> + }
> +
> + return 0;
> +}
> +
> +[…]
> +
> +static int pickit2_shutdown(void *data)
> +{
> + int ret;
> + msg_pspew("%s\n", __func__);
> +
> + /* Set all pins to float and turn voltages off */
> + unsigned char command[CMD_LENGTH] = {
> + CMD_EXEC_SCRIPT,
> + 8,
> + SCR_SET_PINS,
> + /* Bit-0=1(PDC In), Bit-1=1(PGD In), Bit-2=0(PDC LL), Bit-3=0(PGD LL) */
> + 3,
> + SCR_SET_AUX,
> + /* Bit-0=1(Aux In), Bit-1=0(Aux LL) */
> + 1,
> + SCR_MCLR_GND_OFF,
> + SCR_VPP_OFF,
> + SCR_VDD_OFF,
> + SCR_BUSY_LED_OFF,
> + CMD_END_OF_BUFFER
> + };
> +
> + ret = usb_interrupt_write(pickit2_handle, ENDPOINT_OUT, (char *)command, CMD_LENGTH, DEFAULT_TIMEOUT);
> +
> + if (ret != CMD_LENGTH) {
> + msg_perr("Command Shutdown failed (%s)!\n",
> + usb_strerror());
> + return 1;
> + }
> +
> + if (usb_release_interface(pickit2_handle, 0)) {
> + msg_perr("Could not release USB interface!\n");
> + return 1;
> + }
> + if (usb_close(pickit2_handle)) {
> + msg_perr("Could not close USB device!\n");
> + return 1;
> + }
> + return 0;
> […]
--
Kind regards/Mit freundlichen Grüßen, Stefan Tauner
I've tried to run flashrom -V to see if it could identify the chip on my
new board (AsRock M3A-GLAN), and it got stuck while probing for the
first chip.
I've tried commenting out that specific chip (AMIC A25L05PT) and then it
gets stuck on the next one. Then commented out all AMIC chips, and it
got stuck on the next one (the first ATMEL on the list)
I've tried with an older flashrom (0.9.2-r1141). It skipped some AMD
chips, then got stuck on AMIC again.
Talked with "tlt" and "stefanct" on irc and they asked for a strace and
a gdb backtrace. Strace produced no results. Gdb log is attached.
"stefanct" tried and reproduced it on a machine with nicintel_spi, but
warned it was with an unsupported nic:
http://paste.flashrom.org/view.php?id=738
--
GatoLoko
I have a TUMPA Lite edition it is FTDI Based Board similar to TUMPA/FT232H, but single channel:
http://www.tiaowiki.com/w/TIAO_USB_Multi_Protocol_Adapter_Lite_User's_Manual
You can build one from upper link, or buy cheap on ebay.
And I added this to ft2232_spi.c
--- ../flashrom/ft2232_spi.c 2013-09-17 19:43:16.000000000 +0200
+++ ft2232_spi.c 2014-01-24 11:57:49.000000000 +0100
@@ -43,6 +43,7 @@
#define FTDI_FT4232H_PID 0x6011
#define FTDI_FT232H_PID 0x6014
#define TIAO_TUMPA_PID 0x8a98
+#define TIAO_TUMPA_LITE_PID 0x8a99
#define AMONTEC_JTAGKEY_PID 0xCFF8
#define GOEPEL_VID 0x096C
@@ -62,6 +63,7 @@
{FTDI_VID, FTDI_FT4232H_PID, OK, "FTDI", "FT4232H"},
{FTDI_VID, FTDI_FT232H_PID, OK, "FTDI", "FT232H"},
{FTDI_VID, TIAO_TUMPA_PID, OK, "TIAO", "USB Multi-Protocol Adapter"},
+ {FTDI_VID, TIAO_TUMPA_LITE_PID, OK, "TIAO", "USB Multi-Protocol Adapter Lite"},
{FTDI_VID, AMONTEC_JTAGKEY_PID, OK, "Amontec", "JTAGkey"},
{GOEPEL_VID, GOEPEL_PICOTAP_PID, OK, "GOEPEL", "PicoTAP"},
{FIC_VID, OPENMOKO_DBGBOARD_PID, OK, "FIC", "OpenMoko Neo1973 Debug board (V2+)"},
@@ -208,6 +210,10 @@
/* Interface A is SPI1, B is SPI2. */
ft2232_type = TIAO_TUMPA_PID;
channel_count = 2;
+ } else if (!strcasecmp(arg, "tumpalite")) {
+ /* Only one channel is used on lite edition */
+ ft2232_type = TIAO_TUMPA_LITE_PID;
+ channel_count = 1;
} else if (!strcasecmp(arg, "busblaster")) {
/* In its default configuration it is a jtagkey clone */
ft2232_type = FTDI_FT2232H_PID;
works as advertised.
BRGDS, Jadran Puharic
CID1130009: Resource leak
The system resource will not be reclaimed and reused, reducing the future
availability of the resource.
In sp_opensocket: Leak of memory or pointers to system resources
Signed-off-by: Stefan Reinauer <stefan.reinauer(a)coreboot.org>
Index: serprog.c
===================================================================
--- serprog.c (revision 1763)
+++ serprog.c (working copy)
@@ -100,6 +100,7 @@
if (NULL == hostPtr) {
hostPtr = gethostbyaddr(ip, strlen(ip), AF_INET);
if (NULL == hostPtr) {
+ close(sock);
msg_perr("Error: cannot resolve %s\n", ip);
return -1;
}