aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomasz Kramkowski <tk@the-tk.com>2016-12-22 14:24:13 +0100
committerTomasz Kramkowski <tk@the-tk.com>2016-12-22 14:24:13 +0100
commit27f76df4d35ec26bb7a1571a38cd27d978cd85e2 (patch)
treef283efc5202729e20fa121dec03a96bde0d47499
parent04be5b1456b381303709fdc90385fe74dad1bd10 (diff)
downloadhktool-27f76df4d35ec26bb7a1571a38cd27d978cd85e2.tar.gz
hktool-27f76df4d35ec26bb7a1571a38cd27d978cd85e2.tar.xz
hktool-27f76df4d35ec26bb7a1571a38cd27d978cd85e2.zip
halfkay: overhaul error handling
Errors now handled by eprintf.h instead of log.h.
-rw-r--r--halfkay.c70
1 files changed, 43 insertions, 27 deletions
diff --git a/halfkay.c b/halfkay.c
index 6c41971..8158888 100644
--- a/halfkay.c
+++ b/halfkay.c
@@ -28,7 +28,7 @@
#include <unistd.h>
#include "halfkay.h"
-#include "log.h"
+#include "eprintf.h"
enum {
HK_USB_VID = 0x16c0,
@@ -40,28 +40,33 @@ enum {
HK_USB_VAL = 0x200,
TIMEOUT = 2000,
TIMEOUT_FIRST = 3000,
- TRANS_DELAY = 4000,
- TRANS_ATTEMPTS = 10,
+ SEND_DELAY = 4000,
+ SEND_ATTEMPTS = 10,
+ REBOOTCMD_WIDTH = 3,
+ REBOOTCMD_FILL = 0xff,
};
libusb_device_handle *hk_usb_hnd;
static inline void libusb_err(const char *action, int code)
{
- error(0, "libusb %s failed: %s", action, libusb_strerror(code));
+ eprintf("libusb %s failed: %s", action, libusb_strerror(code));
}
static void usbopen(void)
{
int rc;
+ if (hk_usb_hnd != NULL)
+ return;
+
rc = libusb_init(NULL);
if (libusb_init(NULL) != LIBUSB_SUCCESS)
libusb_err("init", rc);
hk_usb_hnd = libusb_open_device_with_vid_pid(NULL, HK_USB_VID, HK_USB_PID);
if (!hk_usb_hnd)
- error(0, "HalfKay device not found");
+ eprintf("HalfKay device not found");
libusb_set_auto_detach_kernel_driver(hk_usb_hnd, 1);
rc = libusb_claim_interface(hk_usb_hnd, 0);
@@ -71,23 +76,28 @@ static void usbopen(void)
static void usbclose(void)
{
+ if (hk_usb_hnd == NULL)
+ return;
+
libusb_release_interface(hk_usb_hnd, 0);
libusb_close(hk_usb_hnd);
libusb_exit(NULL);
+
+ hk_usb_hnd = NULL;
}
static void usbsendcmd(void *data, size_t size, bool firstxfer)
{
unsigned int timeout = firstxfer ? TIMEOUT_FIRST : TIMEOUT;
int rc, attempt = 0;
- useconds_t delay = TRANS_DELAY;
+ useconds_t delay = SEND_DELAY;
do {
rc = libusb_control_transfer(hk_usb_hnd, HK_USB_REQTYP, HK_USB_REQ,
HK_USB_VAL, 0, data, size, timeout);
usleep(delay);
delay *= 2;
- } while (rc == LIBUSB_ERROR_PIPE && ++attempt < TRANS_ATTEMPTS);
+ } while (rc == LIBUSB_ERROR_PIPE && ++attempt < SEND_ATTEMPTS);
if (rc < 0)
libusb_err("transfer", rc);
@@ -98,6 +108,9 @@ static void fmtcmd(void *_dest, const struct flashparams *fp, size_t addr)
static const size_t MAX_SHIFT = sizeof addr * CHAR_BIT / 8;
unsigned char *dest = _dest;
+ assert(dest);
+ assert(fp);
+
addr >>= fp->addrshft;
for (size_t i = 0; i < fp->cmdsz && i < MAX_SHIFT; i++)
dest[i] = (addr >> (i * 8)) & 0xFF;
@@ -109,24 +122,18 @@ int flash(const struct flashparams *fp, const char *file)
unsigned char *cmd;
size_t tsize;
+ assert(fp);
+ assert(fp->blksz && (fp->blksz & (fp->blksz - 1)) == 0);
+ assert(fp->memsz % fp->blksz == 0);
+ assert(SIZE_MAX - fp->blksz >= fp->cmdsz);
assert(file);
- /* TODO: move checks to parser */
- /*if (!fp->blksz || !(fp->blksz & fp->blksz - 1))*/
- /*error(0, "Block size is not a power of 2");*/
- /*if (fp->memsz % fp->blksz)*/
- /*error(0, "Memory size is not divisible by block size");*/
-
- tsize = fp->blksz + fp->cmdsz;
-
f = fopen(file, "rb");
if (!f)
- error(errno, EMSG_OPEN, file);
+ eprintf("Could not open '%s':", file);
- /* TODO: precalc and check ovf */
- cmd = malloc(tsize);
- if (!cmd)
- error(errno, EMSG_ALLOC);
+ tsize = fp->blksz + fp->cmdsz;
+ cmd = emalloc(tsize);
usbopen();
@@ -135,17 +142,18 @@ int flash(const struct flashparams *fp, const char *file)
fmtcmd(cmd, fp, blkaddr);
count = fread(cmd + fp->cmdsz, 1, fp->blksz, f);
+ if (count != fp->blksz && ferror(f))
+ eprintf("Error while reading '%s', short read", file);
if (count == 0)
break;
- if (count < fp->blksz) {
+ if (count < fp->blksz)
memset(cmd + fp->cmdsz + count, 0, fp->blksz - count);
- }
usbsendcmd(cmd, tsize, blkaddr == 0);
}
if (!feof(f))
- fprintf(stderr, "Device ran out of space during writing!");
+ weprintf("Device ran out of space during writing!");
usbclose();
@@ -157,10 +165,18 @@ int flash(const struct flashparams *fp, const char *file)
int reboot(const struct flashparams *fp)
{
- size_t tsize = fp->blksz + fp->cmdsz;
- unsigned char *cmd = malloc(tsize);
- memset(cmd, 0x00, tsize - 3);
- memset(cmd, 0xff, 3);
+ size_t tsize;
+ unsigned char *cmd;
+
+ assert(fp);
+ assert(fp->blksz && (fp->blksz & (fp->blksz - 1)) == 0);
+ assert(fp->memsz % fp->blksz == 0);
+ assert(SIZE_MAX - fp->blksz >= fp->cmdsz);
+
+ tsize = fp->blksz + fp->cmdsz;
+ cmd = ecalloc(tsize, 1);
+
+ memset(cmd, REBOOTCMD_FILL, REBOOTCMD_WIDTH);
usbopen();
usbsendcmd(cmd, tsize, true);