Browse Source

Merge branch 'master' into libusbx

nfactor-troky
Con Kolivas 11 years ago
parent
commit
c3b0566247
  1. 2
      api.c
  2. 2
      cgminer.c
  3. 799
      driver-klondike.c
  4. 28
      usbutils.c
  5. 53
      util.c
  6. 10
      util.h

2
api.c

@ -624,7 +624,7 @@ struct CODES {
{ SEVERITY_SUCC, MSG_ASCIDENT,PARAM_ASC, "Identify command sent to ASC%d" }, { SEVERITY_SUCC, MSG_ASCIDENT,PARAM_ASC, "Identify command sent to ASC%d" },
{ SEVERITY_WARN, MSG_ASCNOID, PARAM_ASC, "ASC%d does not support identify" }, { SEVERITY_WARN, MSG_ASCNOID, PARAM_ASC, "ASC%d does not support identify" },
{ SEVERITY_ERR, MSG_MISASCOPT, PARAM_NONE, "Missing option after ASC number" }, { SEVERITY_ERR, MSG_MISASCOPT, PARAM_NONE, "Missing option after ASC number" },
{ SEVERITY_WARN, MSG_ASCNOSET, PARAM_ASC, "ASC %d does not support pgaset" }, { SEVERITY_WARN, MSG_ASCNOSET, PARAM_ASC, "ASC %d does not support ascset" },
{ SEVERITY_INFO, MSG_ASCHELP, PARAM_BOTH, "ASC %d set help: %s" }, { SEVERITY_INFO, MSG_ASCHELP, PARAM_BOTH, "ASC %d set help: %s" },
{ SEVERITY_SUCC, MSG_ASCSETOK, PARAM_BOTH, "ASC %d set OK" }, { SEVERITY_SUCC, MSG_ASCSETOK, PARAM_BOTH, "ASC %d set OK" },
{ SEVERITY_ERR, MSG_ASCSETERR, PARAM_BOTH, "ASC %d set failed: %s" }, { SEVERITY_ERR, MSG_ASCSETERR, PARAM_BOTH, "ASC %d set failed: %s" },

2
cgminer.c

@ -4004,7 +4004,7 @@ static void set_blockdiff(const struct work *work)
static bool test_work_current(struct work *work) static bool test_work_current(struct work *work)
{ {
bool ret = true; bool ret = true;
char hexstr[20]; char hexstr[40];
if (work->mandatory) if (work->mandatory)
return ret; return ret;

799
driver-klondike.c

File diff suppressed because it is too large Load Diff

28
usbutils.c

@ -2194,15 +2194,13 @@ static char *find_end(unsigned char *buf, unsigned char *ptr, int ptrlen, int to
#define USB_RETRY_MAX 5 #define USB_RETRY_MAX 5
struct usb_transfer { struct usb_transfer {
pthread_mutex_t mutex; cgsem_t cgsem;
pthread_cond_t cond;
struct libusb_transfer *transfer; struct libusb_transfer *transfer;
}; };
static void init_usb_transfer(struct usb_transfer *ut) static void init_usb_transfer(struct usb_transfer *ut)
{ {
mutex_init(&ut->mutex); cgsem_init(&ut->cgsem);
pthread_cond_init(&ut->cond, NULL);
ut->transfer = libusb_alloc_transfer(0); ut->transfer = libusb_alloc_transfer(0);
if (unlikely(!ut->transfer)) if (unlikely(!ut->transfer))
quit(1, "Failed to libusb_alloc_transfer"); quit(1, "Failed to libusb_alloc_transfer");
@ -2213,9 +2211,7 @@ static void LIBUSB_CALL transfer_callback(struct libusb_transfer *transfer)
{ {
struct usb_transfer *ut = transfer->user_data; struct usb_transfer *ut = transfer->user_data;
mutex_lock(&ut->mutex); cgsem_post(&ut->cgsem);
pthread_cond_signal(&ut->cond);
mutex_unlock(&ut->mutex);
} }
/* Wait for callback function to tell us it has finished the USB transfer, but /* Wait for callback function to tell us it has finished the USB transfer, but
@ -2223,25 +2219,19 @@ static void LIBUSB_CALL transfer_callback(struct libusb_transfer *transfer)
static int callback_wait(struct usb_transfer *ut, int *transferred, unsigned int timeout) static int callback_wait(struct usb_transfer *ut, int *transferred, unsigned int timeout)
{ {
struct libusb_transfer *transfer= ut->transfer; struct libusb_transfer *transfer= ut->transfer;
struct timespec ts_now, ts_end;
struct timeval tv_now;
int ret; int ret;
cgtime(&tv_now); ret = cgsem_mswait(&ut->cgsem, timeout);
ms_to_timespec(&ts_end, timeout); if (ret == ETIMEDOUT) {
timeval_to_spec(&ts_now, &tv_now);
timeraddspec(&ts_end, &ts_now);
ret = pthread_cond_timedwait(&ut->cond, &ut->mutex, &ts_end);
if (ret) {
/* We are emulating a timeout ourself here */ /* We are emulating a timeout ourself here */
libusb_cancel_transfer(transfer); libusb_cancel_transfer(transfer);
/* Now wait for the callback function to be invoked. */ /* Now wait for the callback function to be invoked. */
pthread_cond_wait(&ut->cond, &ut->mutex); cgsem_wait(&ut->cgsem);
} }
ret = transfer->status; ret = transfer->status;
if (ret == LIBUSB_TRANSFER_CANCELLED) if (ret == LIBUSB_TRANSFER_CANCELLED)
ret = LIBUSB_TRANSFER_TIMED_OUT; ret = LIBUSB_ERROR_TIMEOUT;
/* No need to sort out mutexes here since they won't be reused */ /* No need to sort out mutexes here since they won't be reused */
*transferred = transfer->actual_length; *transferred = transfer->actual_length;
@ -2283,7 +2273,6 @@ usb_bulk_transfer(struct libusb_device_handle *dev_handle, int intinfo,
USBDEBUG("USB debug: @usb_bulk_transfer(%s (nodev=%s),intinfo=%d,epinfo=%d,data=%p,length=%d,timeout=%u,mode=%d,cmd=%s,seq=%d) endpoint=%d", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), intinfo, epinfo, data, length, timeout, mode, usb_cmdname(cmd), seq, (int)endpoint); USBDEBUG("USB debug: @usb_bulk_transfer(%s (nodev=%s),intinfo=%d,epinfo=%d,data=%p,length=%d,timeout=%u,mode=%d,cmd=%s,seq=%d) endpoint=%d", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), intinfo, epinfo, data, length, timeout, mode, usb_cmdname(cmd), seq, (int)endpoint);
init_usb_transfer(&ut); init_usb_transfer(&ut);
mutex_lock(&ut.mutex);
/* We give the transfer no timeout since we manage timeouts ourself */ /* We give the transfer no timeout since we manage timeouts ourself */
libusb_fill_bulk_transfer(ut.transfer, dev_handle, endpoint, buf, length, libusb_fill_bulk_transfer(ut.transfer, dev_handle, endpoint, buf, length,
transfer_callback, &ut, 0); transfer_callback, &ut, 0);
@ -2587,7 +2576,7 @@ int _usb_read(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_t
memcpy((char *)buf, (const char *)usbbuf, (tot < (int)bufsiz) ? tot + 1 : (int)bufsiz); memcpy((char *)buf, (const char *)usbbuf, (tot < (int)bufsiz) ? tot + 1 : (int)bufsiz);
out_unlock: out_unlock:
if (err && err != LIBUSB_ERROR_TIMEOUT && err != LIBUSB_TRANSFER_TIMED_OUT) { if (err && err != LIBUSB_ERROR_TIMEOUT) {
applog(LOG_WARNING, "%s %i usb read error: %s", cgpu->drv->name, cgpu->device_id, applog(LOG_WARNING, "%s %i usb read error: %s", cgpu->drv->name, cgpu->device_id,
libusb_error_name(err)); libusb_error_name(err));
if (cgpu->usbinfo.continuous_ioerr_count > USB_RETRY_MAX) if (cgpu->usbinfo.continuous_ioerr_count > USB_RETRY_MAX)
@ -2716,7 +2705,6 @@ static int usb_control_transfer(libusb_device_handle *dev_handle, uint8_t bmRequ
int err, transferred; int err, transferred;
init_usb_transfer(&ut); init_usb_transfer(&ut);
mutex_lock(&ut.mutex);
libusb_fill_control_setup(buf, bmRequestType, bRequest, wValue, libusb_fill_control_setup(buf, bmRequestType, bRequest, wValue,
wIndex, wLength); wIndex, wLength);
libusb_fill_control_transfer(ut.transfer, dev_handle, buf, transfer_callback, libusb_fill_control_transfer(ut.transfer, dev_handle, buf, transfer_callback,

53
util.c

@ -881,6 +881,14 @@ void ms_to_timespec(struct timespec *spec, int64_t ms)
spec->tv_nsec = tvdiv.rem * 1000000; spec->tv_nsec = tvdiv.rem * 1000000;
} }
void ms_to_timeval(struct timeval *val, int64_t ms)
{
lldiv_t tvdiv = lldiv(ms, 1000);
val->tv_sec = tvdiv.quot;
val->tv_usec = tvdiv.rem * 1000;
}
void timeraddspec(struct timespec *a, const struct timespec *b) void timeraddspec(struct timespec *a, const struct timespec *b)
{ {
a->tv_sec += b->tv_sec; a->tv_sec += b->tv_sec;
@ -2407,6 +2415,31 @@ void _cgsem_destroy(cgsem_t *cgsem)
close(cgsem->pipefd[1]); close(cgsem->pipefd[1]);
close(cgsem->pipefd[0]); close(cgsem->pipefd[0]);
} }
/* This is similar to sem_timedwait but takes a millisecond value */
int _cgsem_mswait(cgsem_t *cgsem, int ms, const char *file, const char *func, const int line)
{
struct timeval timeout;
int ret, fd;
fd_set rd;
char buf;
fd = cgsem->pipefd[0];
FD_ZERO(&rd);
FD_SET(fd, &rd);
ms_to_timeval(&timeout, ms);
ret = select(fd + 1, &rd, NULL, NULL, &timeout);
if (ret > 0) {
ret = read(fd, &buf, 1);
return 0;
}
if (likely(!ret))
return ETIMEDOUT;
quitfrom(1, file, func, line, "Failed to sem_timedwait errno=%d cgsem=0x%p", errno, cgsem);
/* We don't reach here */
return 0;
}
#else #else
void _cgsem_init(cgsem_t *cgsem, const char *file, const char *func, const int line) void _cgsem_init(cgsem_t *cgsem, const char *file, const char *func, const int line)
{ {
@ -2427,6 +2460,26 @@ void _cgsem_wait(cgsem_t *cgsem, const char *file, const char *func, const int l
quitfrom(1, file, func, line, "Failed to sem_wait errno=%d cgsem=0x%p", errno, cgsem); quitfrom(1, file, func, line, "Failed to sem_wait errno=%d cgsem=0x%p", errno, cgsem);
} }
int _cgsem_mswait(cgsem_t *cgsem, int ms, const char *file, const char *func, const int line)
{
struct timespec abs_timeout, ts_now;
struct timeval tv_now;
int ret;
cgtime(&tv_now);
timeval_to_spec(&ts_now, &tv_now);
ms_to_timespec(&abs_timeout, ms);
timeraddspec(&abs_timeout, &ts_now);
ret = sem_timedwait(cgsem, &abs_timeout);
if (ret) {
if (likely(sock_timeout()))
return ETIMEDOUT;
quitfrom(1, file, func, line, "Failed to sem_timedwait errno=%d cgsem=0x%p", errno, cgsem);
}
return 0;
}
void _cgsem_destroy(cgsem_t *cgsem) void _cgsem_destroy(cgsem_t *cgsem)
{ {
sem_destroy(cgsem); sem_destroy(cgsem);

10
util.h

@ -20,6 +20,10 @@
{ {
return (errno == EAGAIN || errno == EWOULDBLOCK); return (errno == EAGAIN || errno == EWOULDBLOCK);
} }
static inline bool sock_timeout(void)
{
return (errno == ETIMEDOUT);
}
#elif defined WIN32 #elif defined WIN32
#include <ws2tcpip.h> #include <ws2tcpip.h>
#include <winsock2.h> #include <winsock2.h>
@ -37,6 +41,10 @@
{ {
return (WSAGetLastError() == WSAEWOULDBLOCK); return (WSAGetLastError() == WSAEWOULDBLOCK);
} }
static inline bool sock_timeout(void)
{
return (errno == WSAETIMEDOUT);
}
#ifndef SHUT_RDWR #ifndef SHUT_RDWR
#define SHUT_RDWR SD_BOTH #define SHUT_RDWR SD_BOTH
#endif #endif
@ -124,11 +132,13 @@ void RenameThread(const char* name);
void _cgsem_init(cgsem_t *cgsem, const char *file, const char *func, const int line); void _cgsem_init(cgsem_t *cgsem, const char *file, const char *func, const int line);
void _cgsem_post(cgsem_t *cgsem, const char *file, const char *func, const int line); void _cgsem_post(cgsem_t *cgsem, const char *file, const char *func, const int line);
void _cgsem_wait(cgsem_t *cgsem, const char *file, const char *func, const int line); void _cgsem_wait(cgsem_t *cgsem, const char *file, const char *func, const int line);
int _cgsem_mswait(cgsem_t *cgsem, int ms, const char *file, const char *func, const int line);
void _cgsem_destroy(cgsem_t *cgsem); void _cgsem_destroy(cgsem_t *cgsem);
#define cgsem_init(_sem) _cgsem_init(_sem, __FILE__, __func__, __LINE__) #define cgsem_init(_sem) _cgsem_init(_sem, __FILE__, __func__, __LINE__)
#define cgsem_post(_sem) _cgsem_post(_sem, __FILE__, __func__, __LINE__) #define cgsem_post(_sem) _cgsem_post(_sem, __FILE__, __func__, __LINE__)
#define cgsem_wait(_sem) _cgsem_wait(_sem, __FILE__, __func__, __LINE__) #define cgsem_wait(_sem) _cgsem_wait(_sem, __FILE__, __func__, __LINE__)
#define cgsem_mswait(_sem, _timeout) _cgsem_mswait(_sem, _timeout, __FILE__, __func__, __LINE__)
#define cgsem_destroy(_sem) _cgsem_destroy(_sem) #define cgsem_destroy(_sem) _cgsem_destroy(_sem)
/* Align a size_t to 4 byte boundaries for fussy arches */ /* Align a size_t to 4 byte boundaries for fussy arches */

Loading…
Cancel
Save