From 27f76df4d35ec26bb7a1571a38cd27d978cd85e2 Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Thu, 22 Dec 2016 14:24:13 +0100 Subject: halfkay: overhaul error handling Errors now handled by eprintf.h instead of log.h. --- halfkay.c | 70 +++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 27 deletions(-) (limited to 'halfkay.c') diff --git a/halfkay.c b/halfkay.c index 6c41971..8158888 100644 --- a/halfkay.c +++ b/halfkay.c @@ -28,7 +28,7 @@ #include #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); -- cgit v1.2.3-54-g00ecf