diff options
| author | Tomasz Kramkowski <tk@the-tk.com> | 2016-12-22 14:24:13 +0100 | 
|---|---|---|
| committer | Tomasz Kramkowski <tk@the-tk.com> | 2016-12-22 14:24:13 +0100 | 
| commit | 27f76df4d35ec26bb7a1571a38cd27d978cd85e2 (patch) | |
| tree | f283efc5202729e20fa121dec03a96bde0d47499 | |
| parent | 04be5b1456b381303709fdc90385fe74dad1bd10 (diff) | |
| download | hktool-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.c | 70 | 
1 files changed, 43 insertions, 27 deletions
@@ -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);  | 
