Merge branch 'master'
This commit is contained in:
commit
55bed7e8cd
18 files changed
+223
-206
No files matched your search
+20
@@ -0,0 +1,20 @@
|
||||
language: c
|
||||
compiler:
|
||||
- gcc
|
||||
before_install:
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install -qq -y libusb-dev
|
||||
script: if [ ${COVERITY_SCAN_BRANCH} != 1 ]; then make ; fi
|
||||
|
||||
env:
|
||||
global:
|
||||
- secure: "JdUp+xFykPZoYA4aRfmYk2CtilLapniQllWPKo2dDdJd1vzdawfTvVxIAKjy7ac9RKwZzg3Chq3RsMEXPv8BtaLbssw266C7RDLMgjacl1eFLcmGRj/Gkk9peDSZ6vVdGEcA2j+6KDSfpCa/XjFjvOufZOgKw6m+3+d0A4G45SI="
|
||||
|
||||
addons:
|
||||
coverity_scan:
|
||||
project:
|
||||
name: "pali/0xFFFF"
|
||||
description: "Build submitted via Travis CI"
|
||||
notification_email: pali.rohar@gmail.com
|
||||
build_command: "make"
|
||||
branch_pattern: master
|
||||
@@ -1,4 +1,4 @@
|
||||
VERSION = 0.6
|
||||
VERSION = 0.6.1
|
||||
PREFIX = /usr/local
|
||||
|
||||
# NetBSD stuff
|
||||
|
||||
Vendored
-5
@@ -1,5 +0,0 @@
|
||||
0xffff (0.6-1) unstable; urgency=low
|
||||
|
||||
* This is new rewritten version of original 0xFFFF 0.5 tool
|
||||
|
||||
-- Pali Rohár <pali.rohar@gmail.com> Sun, 07 Apr 2013 15:01:50 +0200
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
7
|
||||
Vendored
-84
@@ -1,84 +0,0 @@
|
||||
Source: 0xffff
|
||||
Section: user/system
|
||||
Priority: extra
|
||||
Maintainer: Pali Rohár <pali.rohar@gmail.com>
|
||||
Build-Depends: debhelper (>= 7), libusb-dev
|
||||
Standards-Version: 3.9.3
|
||||
|
||||
Package: 0xffff
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, mtd-utils
|
||||
Description: Open Free Fiasco Firmware Flasher
|
||||
0xFFFF is Open Free Fiasco Firmware Flasher for Maemo devices. It support
|
||||
generating and unpacking FIASCO images on local computer. Useful for editing
|
||||
Maemo firmware package for future flash. It support via USB flashing any image
|
||||
type to Maemo device and also "cold" flashing which means flashing dead
|
||||
device with erased bootloader. There is support for booting kernel via USB
|
||||
without flashing to NAND and also changing configuration of Maemo device
|
||||
(enable/disable R&D mode, changing HW revision strings, ...).
|
||||
.
|
||||
0xFFFF is alternative tool to proprietary Nokia flasher-3.5 and fiasco-gen.
|
||||
0xFFFF generate compatible FIASCO images and also accept FIASCO images
|
||||
generated by Nokia fiasco-gen.
|
||||
.
|
||||
Supported Maemo devices:
|
||||
Nokia 770, Nokia N800, Nokia N810, Nokia N810 WiMAX, Nokia N900
|
||||
XSBC-Maemo-Display-Name: 0xFFFF
|
||||
XB-Maemo-Icon-26:
|
||||
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
|
||||
5l7y6xMAAAAASUVORK5CYII=
|
||||
Vendored
-29
@@ -1,29 +0,0 @@
|
||||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: 0xffff
|
||||
|
||||
Files: *
|
||||
Copyright: 2007-2012 pancake <pancake@youterm.com>
|
||||
2011 Michael Buesch <mb@bu3sch.de>
|
||||
2011-2013 Pali Rohár <pali.rohar@gmail.com>
|
||||
License: GPL-3.0+
|
||||
|
||||
Files: debian/*
|
||||
Copyright: 2013 Pali Rohár <pali.rohar@gmail.com>
|
||||
License: GPL-3.0+
|
||||
|
||||
License: GPL-3.0+
|
||||
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, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
.
|
||||
This package 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, see <http://www.gnu.org/licenses/>.
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
|
||||
Vendored
-2
@@ -1,2 +0,0 @@
|
||||
README
|
||||
doc/*
|
||||
Vendored
-11
@@ -1,11 +0,0 @@
|
||||
#!/usr/bin/make -f
|
||||
# -*- makefile -*-
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
%:
|
||||
dh $@
|
||||
|
||||
override_dh_auto_install:
|
||||
dh_auto_install -- PREFIX=/usr
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
3.0 (quilt)
|
||||
+2
-2
@@ -31,10 +31,10 @@ $(BIN).1: $(BIN) $(MANGEN) $(DEPENDS) ../doc/examples
|
||||
mv $@.tmp $@
|
||||
|
||||
libusb-sniff-32.so: libusb-sniff.c $(DEPENDS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -fPIC -ldl -shared -m32 -o $@ $<
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -fPIC $< -ldl -shared -m32 -o $@
|
||||
|
||||
libusb-sniff-64.so: libusb-sniff.c $(DEPENDS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -fPIC -ldl -shared -m64 -o $@ $<
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -fPIC $< -ldl -shared -m64 -o $@
|
||||
|
||||
%.o: %.c $(DEPENDS)
|
||||
$(CROSS_CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
|
||||
|
||||
+1
-1
@@ -130,7 +130,7 @@ struct xloader_msg {
|
||||
uint32_t size; /* 4 bytes - size of file */
|
||||
uint32_t crc1; /* 4 bytes - crc32 of file */
|
||||
uint32_t crc2; /* 4 bytes - crc32 of first 12 bytes of message */
|
||||
};
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define XLOADER_MSG_TYPE_PING 0x6301326E
|
||||
#define XLOADER_MSG_TYPE_SEND 0x6302326E
|
||||
|
||||
+43
-13
@@ -192,9 +192,12 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
|
||||
if ( ! hwrevs[0] )
|
||||
strcpy(hwrevs, hwrev);
|
||||
else {
|
||||
/* TODO: check if hwrevs has enough size */
|
||||
strcat(hwrevs, ",");
|
||||
strcat(hwrevs, hwrev);
|
||||
size_t len1 = strlen(hwrevs);
|
||||
size_t len2 = strlen(hwrev);
|
||||
if ( len1 + len2 + 2 < sizeof(hwrevs) ) {
|
||||
hwrevs[len1] = ',';
|
||||
memcpy(hwrevs+len1+1, hwrev, len2+1);
|
||||
}
|
||||
}
|
||||
VERBOSE(" hw revision: %s\n", hwrev);
|
||||
pbuf += strlen(hwrev) + 1;
|
||||
@@ -410,6 +413,7 @@ int fiasco_write_to_file(struct fiasco * fiasco, const char * file) {
|
||||
WRITE_OR_FAIL(file, fd, "2", 1); /* 2 - device & hwrevs */
|
||||
WRITE_OR_FAIL(file, fd, &device_hwrevs_bufs[i][0], 1);
|
||||
WRITE_OR_FAIL(file, fd, device_hwrevs_bufs[i]+1, ((uint8_t *)(device_hwrevs_bufs[i]))[0]);
|
||||
/* FIXME: memory leak: device_hwrevs_bufs */
|
||||
}
|
||||
free(device_hwrevs_bufs);
|
||||
|
||||
@@ -449,9 +453,9 @@ int fiasco_write_to_file(struct fiasco * fiasco, const char * file) {
|
||||
|
||||
int fiasco_unpack(struct fiasco * fiasco, const char * dir) {
|
||||
|
||||
int fd = -1;
|
||||
char * name = NULL;
|
||||
char * layout_name = NULL;
|
||||
int fd;
|
||||
char * name;
|
||||
char * layout_name;
|
||||
struct image * image;
|
||||
struct image_list * image_list;
|
||||
uint32_t size;
|
||||
@@ -480,6 +484,10 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) {
|
||||
|
||||
while ( image_list ) {
|
||||
|
||||
fd = -1;
|
||||
name = NULL;
|
||||
layout_name = NULL;
|
||||
|
||||
image = image_list->image;
|
||||
|
||||
name = image_name_alloc_from_values(image);
|
||||
@@ -492,9 +500,11 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) {
|
||||
|
||||
if ( image->layout ) {
|
||||
|
||||
layout_name = calloc(1, strlen(name) + strlen(".layout") + 1);
|
||||
if ( ! layout_name )
|
||||
layout_name = calloc(1, strlen(name) + sizeof(".layout")-1 + 1);
|
||||
if ( ! layout_name ) {
|
||||
free(name);
|
||||
ALLOC_ERROR_RETURN(-1);
|
||||
}
|
||||
|
||||
sprintf(layout_name, "%s.layout", name);
|
||||
|
||||
@@ -508,20 +518,31 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) {
|
||||
fd = open(name, O_RDWR|O_CREAT|O_TRUNC, 0644);
|
||||
if ( fd < 0 ) {
|
||||
ERROR_INFO("Cannot create output file %s", name);
|
||||
free(name);
|
||||
free(layout_name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
free(name);
|
||||
|
||||
image_seek(image, 0);
|
||||
while ( 1 ) {
|
||||
size = image_read(image, buf, sizeof(buf));
|
||||
if ( size == 0 )
|
||||
break;
|
||||
WRITE_OR_FAIL(name, fd, buf, size);
|
||||
if ( ! simulate ) {
|
||||
if ( write(fd, buf, size) != (ssize_t)size ) {
|
||||
ERROR_INFO_STR(name, "Cannot write %d bytes", size);
|
||||
close(fd);
|
||||
free(name);
|
||||
free(layout_name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(name);
|
||||
|
||||
if ( ! simulate )
|
||||
close(fd);
|
||||
|
||||
if ( image->layout ) {
|
||||
@@ -530,14 +551,23 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) {
|
||||
fd = open(layout_name, O_RDWR|O_CREAT|O_TRUNC, 0644);
|
||||
if ( fd < 0 ) {
|
||||
ERROR_INFO("Cannot create layout file %s", layout_name);
|
||||
free(layout_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
size = strlen(image->layout);
|
||||
|
||||
if ( write(fd, image->layout, size) != (ssize_t)size ) {
|
||||
ERROR_INFO_STR(layout_name, "Cannot write %d bytes", size);
|
||||
close(fd);
|
||||
free(layout_name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
free(layout_name);
|
||||
|
||||
WRITE_OR_FAIL(layout_name, fd, image->layout, (int)strlen(image->layout));
|
||||
|
||||
if ( ! simulate )
|
||||
close(fd);
|
||||
|
||||
}
|
||||
|
||||
+4
-3
@@ -88,14 +88,13 @@ static void image_missing_values_from_name(struct image * image, const char * na
|
||||
|
||||
if ( image->devices && image->devices->device && ! image->devices->hwrevs )
|
||||
image->devices->hwrevs = hwrevs_alloc_from_string(hwrevs);
|
||||
else
|
||||
free(hwrevs);
|
||||
|
||||
if ( ! image->version )
|
||||
image->version = version;
|
||||
else
|
||||
free(version);
|
||||
|
||||
free(hwrevs);
|
||||
free(str);
|
||||
|
||||
}
|
||||
@@ -135,8 +134,10 @@ char * image_name_alloc_from_values(struct image * image) {
|
||||
length += 1 + strlen(image->version);
|
||||
|
||||
name = calloc(1, length);
|
||||
if ( ! name )
|
||||
if ( ! name ) {
|
||||
free(hwrevs);
|
||||
ALLOC_ERROR_RETURN(NULL);
|
||||
}
|
||||
|
||||
strcpy(name, type);
|
||||
ptr = name + strlen(name);
|
||||
|
||||
+22
-14
@@ -127,9 +127,9 @@ int local_init(void) {
|
||||
|
||||
while ( fgets(buf, sizeof(buf), file) ) {
|
||||
|
||||
if ( strncmp(buf, "Hardware", strlen("Hardware")) == 0 ) {
|
||||
if ( strncmp(buf, "Hardware", sizeof("Hardware")-1) == 0 ) {
|
||||
|
||||
ptr = buf + strlen("Hardware");
|
||||
ptr = buf + sizeof("Hardware")-1;
|
||||
|
||||
while ( ptr < buf + sizeof(buf) && *ptr > 0 && *ptr <= 32 )
|
||||
++ptr;
|
||||
@@ -316,21 +316,23 @@ int local_dump_image(enum image_type image, const char * file) {
|
||||
|
||||
while ( ( dirent = readdir(dir) ) ) {
|
||||
|
||||
snprintf(buf, sizeof(buf), "/sys/class/mmc_host/%s/slot_name", dirent->d_name);
|
||||
if ( snprintf(buf, sizeof(buf), "/sys/class/mmc_host/%s/slot_name", dirent->d_name) <= 0 )
|
||||
continue;
|
||||
|
||||
fd = open(buf, O_RDONLY);
|
||||
if ( fd < 0 )
|
||||
continue;
|
||||
|
||||
buf[0] = 0;
|
||||
if ( read(fd, buf, sizeof(buf)) < 0 )
|
||||
memset(buf, 0, sizeof(buf));
|
||||
if ( read(fd, buf, sizeof(buf)-1) < 0 )
|
||||
buf[0] = 0;
|
||||
close(fd);
|
||||
|
||||
if ( strncmp(buf, "internal", strlen("internal")) != 0 )
|
||||
if ( strncmp(buf, "internal", sizeof("internal")-1) != 0 )
|
||||
continue;
|
||||
|
||||
snprintf(buf, sizeof(buf), "/sys/class/mmc_host/%s/%s:0001/", dirent->d_name, dirent->d_name);
|
||||
if ( snprintf(buf, sizeof(buf), "/sys/class/mmc_host/%s/%s:0001/", dirent->d_name, dirent->d_name) <= 0 )
|
||||
continue;
|
||||
|
||||
dir2 = opendir(buf);
|
||||
if ( ! dir2 )
|
||||
@@ -338,10 +340,11 @@ int local_dump_image(enum image_type image, const char * file) {
|
||||
|
||||
while ( ( dirent2 = readdir(dir2) ) ) {
|
||||
|
||||
if ( strncmp(dirent2->d_name, "block:mmcblk", strlen("block:mmcblk")) != 0 )
|
||||
if ( strncmp(dirent2->d_name, "block:mmcblk", sizeof("block:mmcblk")-1) != 0 )
|
||||
continue;
|
||||
|
||||
snprintf(buf, sizeof(buf), "/sys/class/mmc_host/%s/%s:0001/%s/dev", dirent->d_name, dirent->d_name, dirent2->d_name);
|
||||
if ( snprintf(buf, sizeof(buf), "/sys/class/mmc_host/%s/%s:0001/%s/dev", dirent->d_name, dirent->d_name, dirent2->d_name) <= 0 )
|
||||
continue;
|
||||
|
||||
f = fopen(buf, "r");
|
||||
if ( ! f )
|
||||
@@ -385,7 +388,8 @@ int local_dump_image(enum image_type image, const char * file) {
|
||||
|
||||
while ( ( dirent = readdir(dir) ) ) {
|
||||
|
||||
snprintf(buf, sizeof(buf), "/dev/%s", dirent->d_name);
|
||||
if ( snprintf(buf, sizeof(buf), "/dev/%s", dirent->d_name) <= 0 )
|
||||
continue;
|
||||
|
||||
if ( stat(buf, &st) != 0 )
|
||||
continue;
|
||||
@@ -410,7 +414,7 @@ int local_dump_image(enum image_type image, const char * file) {
|
||||
|
||||
VERBOSE("Detected internal mmc device: '%s'\n", blk);
|
||||
|
||||
strncat(blk, "p1", sizeof(blk));
|
||||
strncat(blk, "p1", sizeof(blk)-strlen(blk)-1);
|
||||
|
||||
printf("Using MyDocs mmc device: '%s'\n", blk);
|
||||
|
||||
@@ -457,6 +461,10 @@ int local_dump_image(enum image_type image, const char * file) {
|
||||
if ( addr[nlen-1] != 0xFF )
|
||||
break;
|
||||
|
||||
for ( ; nlen > 0; --nlen )
|
||||
if ( addr[nlen-1] != 0x00 )
|
||||
break;
|
||||
|
||||
if ( image == IMAGE_MMC )
|
||||
align = 8;
|
||||
else
|
||||
@@ -532,7 +540,7 @@ int local_set_usb_host_mode(int enable) {
|
||||
|
||||
int local_get_rd_mode(void) {
|
||||
|
||||
if ( strncmp(rd_mode, "master", strlen("master")) == 0 )
|
||||
if ( strncmp(rd_mode, "master", sizeof("master")-1) == 0 )
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
@@ -551,8 +559,8 @@ int local_get_rd_flags(char * flags, size_t size) {
|
||||
|
||||
const char * ptr;
|
||||
|
||||
if ( strncmp(rd_mode, "master", strlen("master")) == 0 )
|
||||
ptr = rd_mode + strlen("master");
|
||||
if ( strncmp(rd_mode, "master", sizeof("master")-1) == 0 )
|
||||
ptr = rd_mode + sizeof("master")-1;
|
||||
else
|
||||
ptr = rd_mode;
|
||||
|
||||
|
||||
+66
-21
@@ -53,8 +53,8 @@ static void show_usage(void) {
|
||||
" -f flash all specified images\n"
|
||||
" -c cold flash 2nd and secondary images\n"
|
||||
" -x [/dev/mtd] check for bad blocks on mtd device (default: all)\n"
|
||||
" -E file dump all device images to one fiasco image, see -t\n"
|
||||
" -e [dir] dump all device images to directory, see -t (default: current)\n"
|
||||
" -E file dump all device images to one fiasco image\n"
|
||||
" -e [dir] dump all device images (or one -t) to directory (default: current)\n"
|
||||
"\n"
|
||||
|
||||
"Device configuration:\n"
|
||||
@@ -84,7 +84,7 @@ static void show_usage(void) {
|
||||
"\n"
|
||||
|
||||
"Image filters:\n"
|
||||
" -t types filter images by type\n"
|
||||
" -t type filter images by type\n"
|
||||
" -d dev filter images by device\n"
|
||||
" -w hw filter images by HW revision\n"
|
||||
"\n"
|
||||
@@ -210,7 +210,7 @@ static void parse_image_arg(char * arg, struct image_list ** image_first) {
|
||||
exit(1);
|
||||
}
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
layout = malloc(len);
|
||||
layout = malloc(len+1);
|
||||
if ( ! layout ) {
|
||||
ALLOC_ERROR();
|
||||
exit(1);
|
||||
@@ -219,6 +219,8 @@ static void parse_image_arg(char * arg, struct image_list ** image_first) {
|
||||
ERROR_INFO("Cannot read %lu bytes from layout file %s", len, layout_file);
|
||||
exit(1);
|
||||
}
|
||||
layout[len] = 0;
|
||||
close(fd);
|
||||
}
|
||||
|
||||
image = image_alloc_from_file(file, type, device, hwrevs, version, layout);
|
||||
@@ -661,6 +663,9 @@ int main(int argc, char **argv) {
|
||||
goto clean;
|
||||
}
|
||||
filter_images_by_type(type, &image_first);
|
||||
/* make sure that fiasco_in has valid images */
|
||||
if ( fiasco_in )
|
||||
fiasco_in->first = image_first;
|
||||
}
|
||||
|
||||
/* filter images by device */
|
||||
@@ -672,11 +677,18 @@ int main(int argc, char **argv) {
|
||||
goto clean;
|
||||
}
|
||||
filter_images_by_device(device, &image_first);
|
||||
/* make sure that fiasco_in has valid images */
|
||||
if ( fiasco_in )
|
||||
fiasco_in->first = image_first;
|
||||
}
|
||||
|
||||
/* filter images by hwrev */
|
||||
if ( filter_hwrev )
|
||||
if ( filter_hwrev ) {
|
||||
filter_images_by_hwrev(atoi(filter_hwrev_arg), &image_first);
|
||||
/* make sure that fiasco_in has valid images */
|
||||
if ( fiasco_in )
|
||||
fiasco_in->first = image_first;
|
||||
}
|
||||
|
||||
/* reorder images for flashing (first x-loader, second secondary) */
|
||||
/* set 2nd and secondary images for cold-flashing */
|
||||
@@ -740,12 +752,30 @@ int main(int argc, char **argv) {
|
||||
image_ptr = next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* make sure that fiasco_in has valid images*/
|
||||
/* make sure that fiasco_in has valid images */
|
||||
if ( fiasco_in )
|
||||
fiasco_in->first = image_first;
|
||||
|
||||
}
|
||||
|
||||
/* remove 2nd image when doing normal flash */
|
||||
if ( dev_flash ) {
|
||||
image_ptr = image_first;
|
||||
while ( image_ptr ) {
|
||||
struct image_list * next = image_ptr->next;
|
||||
if ( image_ptr->image->type == IMAGE_2ND ) {
|
||||
if ( image_ptr == image_first )
|
||||
image_first = next;
|
||||
image_list_del(image_ptr);
|
||||
}
|
||||
image_ptr = next;
|
||||
}
|
||||
|
||||
/* make sure that fiasco_in has valid images */
|
||||
if ( fiasco_in )
|
||||
fiasco_in->first = image_first;
|
||||
}
|
||||
|
||||
/* identify images */
|
||||
if ( image_ident ) {
|
||||
if ( fiasco_in ) {
|
||||
@@ -782,8 +812,9 @@ int main(int argc, char **argv) {
|
||||
WARNING("Removing unknown image (specified by %s %s)", image_ptr->image->orig_filename ? "file" : "fiasco", image_ptr->image->orig_filename ? image_ptr->image->orig_filename : "image");
|
||||
if ( image_ptr == image_first )
|
||||
image_first = next;
|
||||
image_list_unlink(image_ptr);
|
||||
free(image_ptr);
|
||||
if ( fiasco_in && image_ptr == fiasco_in->first )
|
||||
fiasco_in->first = fiasco_in->first->next;
|
||||
image_list_del(image_ptr);
|
||||
}
|
||||
image_ptr = next;
|
||||
}
|
||||
@@ -983,6 +1014,8 @@ int main(int argc, char **argv) {
|
||||
filter_images_by_device(dev->detected_device, &image_first);
|
||||
if ( detected_hwrev )
|
||||
filter_images_by_hwrev(dev->detected_hwrev, &image_first);
|
||||
if ( fiasco_in && ( detected_device || detected_hwrev ) )
|
||||
fiasco_in->first = image_first;
|
||||
|
||||
/* set kernel and initfs images for loading */
|
||||
if ( dev_load ) {
|
||||
@@ -1047,8 +1080,7 @@ int main(int argc, char **argv) {
|
||||
if ( fiasco_in && image_kernel == fiasco_in->first )
|
||||
fiasco_in->first = fiasco_in->first->next;
|
||||
|
||||
image_list_unlink(image_kernel);
|
||||
free(image_kernel);
|
||||
image_list_del(image_kernel);
|
||||
image_kernel = NULL;
|
||||
}
|
||||
|
||||
@@ -1059,11 +1091,10 @@ int main(int argc, char **argv) {
|
||||
|
||||
if ( image_initfs == image_first )
|
||||
image_first = image_first->next;
|
||||
if ( fiasco_in && image_kernel == fiasco_in->first )
|
||||
if ( fiasco_in && image_initfs == fiasco_in->first )
|
||||
fiasco_in->first = fiasco_in->first->next;
|
||||
|
||||
image_list_unlink(image_initfs);
|
||||
free(image_initfs);
|
||||
image_list_del(image_initfs);
|
||||
image_initfs = NULL;
|
||||
}
|
||||
}
|
||||
@@ -1079,11 +1110,10 @@ int main(int argc, char **argv) {
|
||||
|
||||
if ( image_ptr == image_first )
|
||||
image_first = image_first->next;
|
||||
if ( fiasco_in && image_kernel == fiasco_in->first )
|
||||
if ( fiasco_in && image_ptr == fiasco_in->first )
|
||||
fiasco_in->first = fiasco_in->first->next;
|
||||
|
||||
image_list_unlink(image_ptr);
|
||||
free(image_ptr);
|
||||
image_list_del(image_ptr);
|
||||
image_ptr = next;
|
||||
}
|
||||
}
|
||||
@@ -1175,9 +1205,21 @@ int main(int argc, char **argv) {
|
||||
buf[0] = 0;
|
||||
}
|
||||
|
||||
if ( filter_type ) {
|
||||
enum image_type type = image_type_from_string(filter_type_arg);
|
||||
if ( ! type || ! image_tmp_name(type) ) {
|
||||
ERROR("Specified unknown image type for filtering: %s", filter_type_arg);
|
||||
ret = 1;
|
||||
goto clean;
|
||||
}
|
||||
ret = dev_dump_image(dev, type, image_tmp_name(type));
|
||||
if ( ret != 0 )
|
||||
goto clean;
|
||||
} else {
|
||||
for ( i = 0; i < IMAGE_COUNT; ++i )
|
||||
if ( image_tmp_name(i) )
|
||||
dev_dump_image(dev, i, image_tmp_name(i));
|
||||
}
|
||||
|
||||
if ( buf[0] )
|
||||
if ( chdir(buf) < 0 )
|
||||
@@ -1196,7 +1238,8 @@ int main(int argc, char **argv) {
|
||||
if ( ! image_tmp_name(i) )
|
||||
continue;
|
||||
|
||||
sprintf(buf, "%hd", dev->detected_hwrev);
|
||||
buf[0] = 0;
|
||||
snprintf(buf, sizeof(buf), "%hd", dev->detected_hwrev);
|
||||
|
||||
switch ( i ) {
|
||||
case IMAGE_2ND:
|
||||
@@ -1298,14 +1341,16 @@ int main(int argc, char **argv) {
|
||||
break;
|
||||
}
|
||||
|
||||
sprintf(buf, "%s-%s:%hd_%s", image_type_to_string(i), device_to_string(dev->detected_device), dev->detected_hwrev, ptr);
|
||||
buf[0] = 0;
|
||||
snprintf(buf, sizeof(buf), "%s-%s:%hd_%s", image_type_to_string(i), device_to_string(dev->detected_device), dev->detected_hwrev, ptr);
|
||||
printf("Renaming %s image file to %s...\n", image_type_to_string(i), buf);
|
||||
|
||||
if ( rename(image_tmp_name(i), buf) < 0 ) {
|
||||
|
||||
ERROR_INFO("Renaming failed");
|
||||
|
||||
sprintf(buf, "%s-%s_%s", image_type_to_string(i), device_to_string(dev->detected_device), ptr);
|
||||
buf[0] = 0;
|
||||
snprintf(buf, sizeof(buf), "%s-%s_%s", image_type_to_string(i), device_to_string(dev->detected_device), ptr);
|
||||
printf("Trying to rename %s image file to %s...\n", image_type_to_string(i), buf);
|
||||
|
||||
if ( rename(image_tmp_name(i), buf) < 0 )
|
||||
|
||||
+33
-17
@@ -84,12 +84,14 @@ static void nolo_error_log(struct usb_device_info * dev, int only_clear) {
|
||||
|
||||
char buf[2048];
|
||||
size_t i, count;
|
||||
int ret;
|
||||
|
||||
for ( count = 0; count < 20; ++count ) {
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
if ( usb_control_msg(dev->udev, NOLO_QUERY, NOLO_ERROR_LOG, 0, 0, buf, sizeof(buf), 2000) <= 0 )
|
||||
ret = usb_control_msg(dev->udev, NOLO_QUERY, NOLO_ERROR_LOG, 0, 0, buf, sizeof(buf), 2000);
|
||||
if ( ret < 0 )
|
||||
break;
|
||||
|
||||
if ( ! only_clear ) {
|
||||
@@ -103,6 +105,9 @@ static void nolo_error_log(struct usb_device_info * dev, int only_clear) {
|
||||
|
||||
}
|
||||
|
||||
if ( (size_t)ret < sizeof(buf) )
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -176,14 +181,14 @@ static int nolo_get_version_string(struct usb_device_info * dev, const char * st
|
||||
if ( strlen(str) > 500 )
|
||||
return -1;
|
||||
|
||||
sprintf(buf, "version:%s", str);
|
||||
if ( sprintf(buf, "version:%s", str) <= 0 )
|
||||
return -1;
|
||||
|
||||
ret = nolo_get_string(dev, buf, out, size);
|
||||
|
||||
if ( ret < 0 ) {
|
||||
nolo_error_log(dev, 1);
|
||||
|
||||
if ( ret < 0 )
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ( ! out[0] )
|
||||
return -1;
|
||||
@@ -311,7 +316,7 @@ static int nolo_send_image(struct usb_device_info * dev, struct image * image, i
|
||||
if ( bufs ) {
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
snprintf(buf, 8, "%d", dev->hwrev);
|
||||
snprintf(buf, 8+1, "%d", dev->hwrev);
|
||||
|
||||
for ( i = 0; bufs[i]; ++i ) {
|
||||
len = ((uint8_t*)bufs[i])[0];
|
||||
@@ -418,8 +423,8 @@ int nolo_flash_image(struct usb_device_info * dev, struct image * image) {
|
||||
unsigned long long int part;
|
||||
unsigned long long int total;
|
||||
unsigned long long int last_total;
|
||||
char status[20];
|
||||
char buf[128];
|
||||
char * ptr;
|
||||
|
||||
if ( image->type == IMAGE_ROOTFS )
|
||||
flash = 1;
|
||||
@@ -463,7 +468,7 @@ int nolo_flash_image(struct usb_device_info * dev, struct image * image) {
|
||||
if ( nolo_get_string(dev, "cmt:status", buf, sizeof(buf)) < 0 )
|
||||
NOLO_ERROR_RETURN("cmt:status failed", -1);
|
||||
|
||||
if ( strncmp(buf, "idle", strlen("idle")) == 0 )
|
||||
if ( strncmp(buf, "idle", sizeof("idle")-1) == 0 )
|
||||
state = 4;
|
||||
else
|
||||
printf("Erasing CMT...\n");
|
||||
@@ -475,7 +480,7 @@ int nolo_flash_image(struct usb_device_info * dev, struct image * image) {
|
||||
NOLO_ERROR_RETURN("cmt:status failed", -1);
|
||||
}
|
||||
|
||||
if ( strncmp(buf, "finished", strlen("finished")) == 0 ) {
|
||||
if ( strncmp(buf, "finished", sizeof("finished")-1) == 0 ) {
|
||||
|
||||
if ( state <= 0 ) {
|
||||
printf_progressbar(last_total, last_total);
|
||||
@@ -490,18 +495,29 @@ int nolo_flash_image(struct usb_device_info * dev, struct image * image) {
|
||||
|
||||
state = 4;
|
||||
|
||||
} else if ( strncmp(buf, "error", sizeof("error")-1) == 0 ) {
|
||||
|
||||
PRINTF_ERROR_RETURN("cmt:status error", -1);
|
||||
|
||||
} else {
|
||||
|
||||
if ( sscanf(buf, "%s:%llu/%llu", status, &part, &total) != 3 )
|
||||
ptr = strchr(buf, ':');
|
||||
if ( ! ptr )
|
||||
PRINTF_ERROR_RETURN("cmt:status unknown", -1);
|
||||
|
||||
if ( strcmp(status, "program") == 0 && state <= 0 ) {
|
||||
*ptr = 0;
|
||||
ptr++;
|
||||
|
||||
if ( sscanf(ptr, "%llu/%llu", &part, &total) != 2 )
|
||||
PRINTF_ERROR_RETURN("cmt:status unknown", -1);
|
||||
|
||||
if ( strcmp(buf, "program") == 0 && state <= 0 ) {
|
||||
printf_progressbar(last_total, last_total);
|
||||
printf("Done\n");
|
||||
state = 1;
|
||||
}
|
||||
|
||||
if ( strcmp(status, "program") == 0 && state <= 1 ) {
|
||||
if ( strcmp(buf, "program") == 0 && state <= 1 ) {
|
||||
printf("Programming CMT...\n");
|
||||
state = 2;
|
||||
}
|
||||
@@ -509,12 +525,12 @@ int nolo_flash_image(struct usb_device_info * dev, struct image * image) {
|
||||
printf_progressbar(part, total);
|
||||
last_total = total;
|
||||
|
||||
if ( strcmp(status, "erase") == 0 && state <= 0 && part == total ) {
|
||||
if ( strcmp(buf, "erase") == 0 && state <= 0 && part == total ) {
|
||||
printf("Done\n");
|
||||
state = 1;
|
||||
}
|
||||
|
||||
if ( strcmp(status, "program") == 0 && state <= 2 && part == total ) {
|
||||
if ( strcmp(buf, "program") == 0 && state <= 2 && part == total ) {
|
||||
printf("Done\n");
|
||||
state = 3;
|
||||
}
|
||||
@@ -536,9 +552,9 @@ int nolo_boot_device(struct usb_device_info * dev, const char * cmdline) {
|
||||
int size = 0;
|
||||
int mode = NOLO_BOOT_MODE_NORMAL;
|
||||
|
||||
if ( cmdline && strncmp(cmdline, "update", strlen("update")) == 0 && cmdline[strlen("update")] <= 32 ) {
|
||||
if ( cmdline && strncmp(cmdline, "update", sizeof("update")-1) == 0 && cmdline[sizeof("update")-1] <= 32 ) {
|
||||
mode = NOLO_BOOT_MODE_UPDATE;
|
||||
cmdline += strlen("update");
|
||||
cmdline += sizeof("update")-1;
|
||||
if ( *cmdline ) ++cmdline;
|
||||
while ( *cmdline && *cmdline <= 32 )
|
||||
++cmdline;
|
||||
@@ -763,7 +779,7 @@ int nolo_set_hwrev(struct usb_device_info * dev, int16_t hwrev) {
|
||||
|
||||
char buf[9];
|
||||
memset(buf, 0, sizeof(buf));
|
||||
snprintf(buf, 8, "%d", hwrev);
|
||||
snprintf(buf, sizeof(buf), "%d", hwrev);
|
||||
printf("Setting HW revision to: %s\n", buf);
|
||||
return nolo_set_string(dev, "hw_rev", buf);
|
||||
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ void printf_progressbar(unsigned long long part, unsigned long long total) {
|
||||
int tmp, cols = 80;
|
||||
|
||||
/* percentage calculation */
|
||||
pc = (int)(part*100/total);
|
||||
pc = total==0?100:(int)(part*100/total);
|
||||
(pc<0)?pc=0:(pc>100)?pc=100:0;
|
||||
|
||||
PRINTF_BACK();
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
|
||||
#include <usb.h>
|
||||
|
||||
#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#include "global.h"
|
||||
#include "device.h"
|
||||
#include "usb-device.h"
|
||||
@@ -73,6 +77,25 @@ static void usb_flash_device_info_print(const struct usb_flash_device * dev) {
|
||||
|
||||
}
|
||||
|
||||
static void usb_reattach_kernel_driver(usb_dev_handle * udev, int interface) {
|
||||
|
||||
#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
|
||||
struct {
|
||||
int ifno;
|
||||
int ioctl_code;
|
||||
void * data;
|
||||
} command = {
|
||||
.ifno = interface,
|
||||
.ioctl_code = _IO('U', 23),
|
||||
.data = NULL,
|
||||
};
|
||||
|
||||
usb_release_interface(udev, interface);
|
||||
ioctl(*((int *)udev), _IOWR('U', 18, command), &command);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void usb_descriptor_info_print(usb_dev_handle * udev, struct usb_device * dev, char * product, size_t size) {
|
||||
|
||||
char buf[1024];
|
||||
@@ -145,6 +168,7 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) {
|
||||
if ( usb_claim_interface(udev, usb_devices[i].interface) < 0 ) {
|
||||
PRINTF_ERROR("usb_claim_interface failed");
|
||||
fprintf(stderr, "\n");
|
||||
usb_reattach_kernel_driver(udev, usb_devices[i].interface);
|
||||
usb_close(udev);
|
||||
return NULL;
|
||||
}
|
||||
@@ -154,6 +178,7 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) {
|
||||
if ( usb_set_altinterface(udev, usb_devices[i].alternate) < 0 ) {
|
||||
PRINTF_ERROR("usb_claim_interface failed");
|
||||
fprintf(stderr, "\n");
|
||||
usb_reattach_kernel_driver(udev, usb_devices[i].interface);
|
||||
usb_close(udev);
|
||||
return NULL;
|
||||
}
|
||||
@@ -164,6 +189,7 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) {
|
||||
if ( usb_set_configuration(udev, usb_devices[i].configuration) < 0 ) {
|
||||
PRINTF_ERROR("usb_set_configuration failed");
|
||||
fprintf(stderr, "\n");
|
||||
usb_reattach_kernel_driver(udev, usb_devices[i].interface);
|
||||
usb_close(udev);
|
||||
return NULL;
|
||||
}
|
||||
@@ -172,6 +198,7 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) {
|
||||
ret = calloc(1, sizeof(struct usb_device_info));
|
||||
if ( ! ret ) {
|
||||
ALLOC_ERROR();
|
||||
usb_reattach_kernel_driver(udev, usb_devices[i].interface);
|
||||
usb_close(udev);
|
||||
return NULL;
|
||||
}
|
||||
@@ -197,7 +224,9 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) {
|
||||
if ( ! *device ) {
|
||||
ERROR("Device mishmash");
|
||||
fprintf(stderr, "\n");
|
||||
usb_reattach_kernel_driver(udev, usb_devices[i].interface);
|
||||
usb_close(udev);
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -308,6 +337,7 @@ struct usb_device_info * usb_open_and_wait_for_device(void) {
|
||||
|
||||
void usb_close_device(struct usb_device_info * dev) {
|
||||
|
||||
usb_reattach_kernel_driver(dev->udev, dev->flash_device->interface);
|
||||
usb_close(dev->udev);
|
||||
free(dev);
|
||||
|
||||
|
||||
Reference in new issue
Block a user