Browse Source

USB automatically handle losing the device and report nodev in the API

nfactor-troky
Kano 12 years ago
parent
commit
34bcc1c66d
  1. 1
      API-README
  2. 14
      api.c
  3. 30
      driver-bitforce.c
  4. 29
      driver-modminer.c
  5. 1
      miner.h
  6. 104
      usbutils.c
  7. 6
      usbutils.h

1
API-README

@ -419,6 +419,7 @@ Added API commands:
Modified API commands: Modified API commands:
'pools' - add 'Best Share' 'pools' - add 'Best Share'
'devs' and 'pga' - add 'No Device' for PGAs if MMQ or BFL compiled
---------- ----------

14
api.c

@ -391,6 +391,7 @@ static const char *JSON_PARAMETER = "parameter";
#define MSG_ZERINV 95 #define MSG_ZERINV 95
#define MSG_ZERSUM 96 #define MSG_ZERSUM 96
#define MSG_ZERNOSUM 97 #define MSG_ZERNOSUM 97
#define MSG_USBNODEV 98
enum code_severity { enum code_severity {
SEVERITY_ERR, SEVERITY_ERR,
@ -568,6 +569,9 @@ struct CODES {
{ SEVERITY_ERR, MSG_ZERINV, PARAM_STR, "Invalid zero parameter '%s'" }, { SEVERITY_ERR, MSG_ZERINV, PARAM_STR, "Invalid zero parameter '%s'" },
{ SEVERITY_SUCC, MSG_ZERSUM, PARAM_STR, "Zeroed %s stats with summary" }, { SEVERITY_SUCC, MSG_ZERSUM, PARAM_STR, "Zeroed %s stats with summary" },
{ SEVERITY_SUCC, MSG_ZERNOSUM, PARAM_STR, "Zeroed %s stats without summary" }, { SEVERITY_SUCC, MSG_ZERNOSUM, PARAM_STR, "Zeroed %s stats without summary" },
#if defined(USE_MODMINER) || defined(USE_BITFORCE)
{ SEVERITY_ERR, MSG_USBNODEV, PARAM_PGA, "PGA%d has no device" },
#endif
{ SEVERITY_FAIL, 0, 0, NULL } { SEVERITY_FAIL, 0, 0, NULL }
}; };
@ -1570,6 +1574,9 @@ static void pgastatus(struct io_data *io_data, int pga, bool isjson, bool precom
root = api_add_diff(root, "Difficulty Accepted", &(cgpu->diff_accepted), false); root = api_add_diff(root, "Difficulty Accepted", &(cgpu->diff_accepted), false);
root = api_add_diff(root, "Difficulty Rejected", &(cgpu->diff_rejected), false); root = api_add_diff(root, "Difficulty Rejected", &(cgpu->diff_rejected), false);
root = api_add_diff(root, "Last Share Difficulty", &(cgpu->last_share_diff), false); root = api_add_diff(root, "Last Share Difficulty", &(cgpu->last_share_diff), false);
#if defined(USE_MODMINER) || defined(USE_BITFORCE)
root = api_add_bool(root, "No Device", &(cgpu->nodev), false);
#endif
root = print_data(root, buf, isjson, precom); root = print_data(root, buf, isjson, precom);
io_add(io_data, buf); io_add(io_data, buf);
@ -1785,6 +1792,13 @@ static void pgaenable(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char
} }
#endif #endif
#if defined(USE_MODMINER) || defined(USE_BITFORCE)
if (cgpu->nodev) {
message(io_data, MSG_USBNODEV, id, NULL, isjson);
return;
}
#endif
for (i = 0; i < mining_threads; i++) { for (i = 0; i < mining_threads; i++) {
pga = thr_info[i].cgpu->cgminer_id; pga = thr_info[i].cgpu->cgminer_id;
if (pga == dev) { if (pga == dev) {

30
driver-bitforce.c

@ -1,5 +1,5 @@
/* /*
* Copyright 2012 Andrew Smith * Copyright 2012-2013 Andrew Smith
* Copyright 2012 Luke Dashjr * Copyright 2012 Luke Dashjr
* Copyright 2012 Con Kolivas * Copyright 2012 Con Kolivas
* *
@ -82,6 +82,9 @@ static void bitforce_initialise(struct cgpu_info *bitforce, bool lock)
applog(LOG_DEBUG, "%s%i: reset got err %d", applog(LOG_DEBUG, "%s%i: reset got err %d",
bitforce->drv->name, bitforce->device_id, err); bitforce->drv->name, bitforce->device_id, err);
if (bitforce->nodev)
goto failed;
// Set data control // Set data control
err = usb_transfer(bitforce, FTDI_TYPE_OUT, FTDI_REQUEST_DATA, err = usb_transfer(bitforce, FTDI_TYPE_OUT, FTDI_REQUEST_DATA,
FTDI_VALUE_DATA, bitforce->usbdev->found->interface, C_SETDATA); FTDI_VALUE_DATA, bitforce->usbdev->found->interface, C_SETDATA);
@ -89,6 +92,9 @@ static void bitforce_initialise(struct cgpu_info *bitforce, bool lock)
applog(LOG_DEBUG, "%s%i: setdata got err %d", applog(LOG_DEBUG, "%s%i: setdata got err %d",
bitforce->drv->name, bitforce->device_id, err); bitforce->drv->name, bitforce->device_id, err);
if (bitforce->nodev)
goto failed;
// Set the baud // Set the baud
err = usb_transfer(bitforce, FTDI_TYPE_OUT, FTDI_REQUEST_BAUD, FTDI_VALUE_BAUD, err = usb_transfer(bitforce, FTDI_TYPE_OUT, FTDI_REQUEST_BAUD, FTDI_VALUE_BAUD,
(FTDI_INDEX_BAUD & 0xff00) | bitforce->usbdev->found->interface, (FTDI_INDEX_BAUD & 0xff00) | bitforce->usbdev->found->interface,
@ -97,6 +103,9 @@ static void bitforce_initialise(struct cgpu_info *bitforce, bool lock)
applog(LOG_DEBUG, "%s%i: setbaud got err %d", applog(LOG_DEBUG, "%s%i: setbaud got err %d",
bitforce->drv->name, bitforce->device_id, err); bitforce->drv->name, bitforce->device_id, err);
if (bitforce->nodev)
goto failed;
// Set Flow Control // Set Flow Control
err = usb_transfer(bitforce, FTDI_TYPE_OUT, FTDI_REQUEST_FLOW, err = usb_transfer(bitforce, FTDI_TYPE_OUT, FTDI_REQUEST_FLOW,
FTDI_VALUE_FLOW, bitforce->usbdev->found->interface, C_SETFLOW); FTDI_VALUE_FLOW, bitforce->usbdev->found->interface, C_SETFLOW);
@ -104,6 +113,9 @@ static void bitforce_initialise(struct cgpu_info *bitforce, bool lock)
applog(LOG_DEBUG, "%s%i: setflowctrl got err %d", applog(LOG_DEBUG, "%s%i: setflowctrl got err %d",
bitforce->drv->name, bitforce->device_id, err); bitforce->drv->name, bitforce->device_id, err);
if (bitforce->nodev)
goto failed;
// Set Modem Control // Set Modem Control
err = usb_transfer(bitforce, FTDI_TYPE_OUT, FTDI_REQUEST_MODEM, err = usb_transfer(bitforce, FTDI_TYPE_OUT, FTDI_REQUEST_MODEM,
FTDI_VALUE_MODEM, bitforce->usbdev->found->interface, C_SETMODEM); FTDI_VALUE_MODEM, bitforce->usbdev->found->interface, C_SETMODEM);
@ -111,6 +123,9 @@ static void bitforce_initialise(struct cgpu_info *bitforce, bool lock)
applog(LOG_DEBUG, "%s%i: setmodemctrl got err %d", applog(LOG_DEBUG, "%s%i: setmodemctrl got err %d",
bitforce->drv->name, bitforce->device_id, err); bitforce->drv->name, bitforce->device_id, err);
if (bitforce->nodev)
goto failed;
// Clear any sent data // Clear any sent data
err = usb_transfer(bitforce, FTDI_TYPE_OUT, FTDI_REQUEST_RESET, err = usb_transfer(bitforce, FTDI_TYPE_OUT, FTDI_REQUEST_RESET,
FTDI_VALUE_PURGE_TX, bitforce->usbdev->found->interface, C_PURGETX); FTDI_VALUE_PURGE_TX, bitforce->usbdev->found->interface, C_PURGETX);
@ -118,6 +133,9 @@ static void bitforce_initialise(struct cgpu_info *bitforce, bool lock)
applog(LOG_DEBUG, "%s%i: purgetx got err %d", applog(LOG_DEBUG, "%s%i: purgetx got err %d",
bitforce->drv->name, bitforce->device_id, err); bitforce->drv->name, bitforce->device_id, err);
if (bitforce->nodev)
goto failed;
// Clear any received data // Clear any received data
err = usb_transfer(bitforce, FTDI_TYPE_OUT, FTDI_REQUEST_RESET, err = usb_transfer(bitforce, FTDI_TYPE_OUT, FTDI_REQUEST_RESET,
FTDI_VALUE_PURGE_RX, bitforce->usbdev->found->interface, C_PURGERX); FTDI_VALUE_PURGE_RX, bitforce->usbdev->found->interface, C_PURGERX);
@ -125,6 +143,8 @@ static void bitforce_initialise(struct cgpu_info *bitforce, bool lock)
applog(LOG_DEBUG, "%s%i: purgerx got err %d", applog(LOG_DEBUG, "%s%i: purgerx got err %d",
bitforce->drv->name, bitforce->device_id, err); bitforce->drv->name, bitforce->device_id, err);
failed:
if (lock) if (lock)
mutex_unlock(&bitforce->device_mutex); mutex_unlock(&bitforce->device_mutex);
} }
@ -322,6 +342,10 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce)
int err, amount; int err, amount;
char *s; char *s;
// Device is gone
if (bitforce->nodev)
return false;
/* Do not try to get the temperature if we're polling for a result to /* Do not try to get the temperature if we're polling for a result to
* minimise the chance of interleaved results */ * minimise the chance of interleaved results */
if (bitforce->polling) if (bitforce->polling)
@ -640,6 +664,10 @@ static int64_t bitforce_scanhash(struct thr_info *thr, struct work *work, int64_
bool send_ret; bool send_ret;
int64_t ret; int64_t ret;
// Device is gone
if (bitforce->nodev)
return -1;
send_ret = bitforce_send_work(thr, work); send_ret = bitforce_send_work(thr, work);
if (!restart_wait(bitforce->sleep_ms)) if (!restart_wait(bitforce->sleep_ms))

29
driver-modminer.c

@ -1,5 +1,5 @@
/* /*
* Copyright 2012 Andrew Smith * Copyright 2012-2013 Andrew Smith
* Copyright 2012 Luke Dashjr * Copyright 2012 Luke Dashjr
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
@ -607,6 +607,7 @@ static bool modminer_fpga_prepare(struct thr_info *thr)
* *
* N.B. clock must always be a multiple of 2 * N.B. clock must always be a multiple of 2
*/ */
static const char *clocknodev = "clock failed - no device";
static const char *clockoldwork = "clock already changed for this work"; static const char *clockoldwork = "clock already changed for this work";
static const char *clocktoolow = "clock too low"; static const char *clocktoolow = "clock too low";
static const char *clocktoohi = "clock too high"; static const char *clocktoohi = "clock too high";
@ -620,6 +621,10 @@ static const char *modminer_delta_clock(struct thr_info *thr, int delta, bool te
unsigned char cmd[6], buf[1]; unsigned char cmd[6], buf[1];
int err, amount; int err, amount;
// Device is gone
if (modminer->nodev)
return clocknodev;
// Only do once if multiple shares per work or multiple reasons // Only do once if multiple shares per work or multiple reasons
if (!state->new_work && !force) if (!state->new_work && !force)
return clockoldwork; return clockoldwork;
@ -775,9 +780,6 @@ static bool modminer_start_work(struct thr_info *thr)
mutex_lock(modminer->modminer_mutex); mutex_lock(modminer->modminer_mutex);
if ((err = usb_write(modminer, (char *)(state->next_work_cmd), 46, &amount, C_SENDWORK)) < 0 || amount != 46) { if ((err = usb_write(modminer, (char *)(state->next_work_cmd), 46, &amount, C_SENDWORK)) < 0 || amount != 46) {
// TODO: err = LIBUSB_ERROR_NO_DEVICE means the MMQ disappeared
// - need to delete it and rescan for it? (after a delay?)
// but check all (4) disappeared
mutex_unlock(modminer->modminer_mutex); mutex_unlock(modminer->modminer_mutex);
applog(LOG_ERR, "%s%u: Start work failed (%d:%d)", applog(LOG_ERR, "%s%u: Start work failed (%d:%d)",
@ -807,6 +809,10 @@ static void check_temperature(struct thr_info *thr)
int tbytes, tamount; int tbytes, tamount;
int amount; int amount;
// Device is gone
if (modminer->nodev)
return;
if (state->one_byte_temp) { if (state->one_byte_temp) {
cmd[0] = MODMINER_TEMP1; cmd[0] = MODMINER_TEMP1;
tbytes = 1; tbytes = 1;
@ -891,6 +897,10 @@ static uint64_t modminer_process_results(struct thr_info *thr)
double timeout; double timeout;
int temploop; int temploop;
// Device is gone
if (modminer->nodev)
return -1;
// If we are overheated it will just keep checking for results // If we are overheated it will just keep checking for results
// since we can't stop the work // since we can't stop the work
// The next work will not start until the temp drops // The next work will not start until the temp drops
@ -904,9 +914,6 @@ static uint64_t modminer_process_results(struct thr_info *thr)
while (1) { while (1) {
mutex_lock(modminer->modminer_mutex); mutex_lock(modminer->modminer_mutex);
if ((err = usb_write(modminer, cmd, 2, &amount, C_REQUESTWORKSTATUS)) < 0 || amount != 2) { if ((err = usb_write(modminer, cmd, 2, &amount, C_REQUESTWORKSTATUS)) < 0 || amount != 2) {
// TODO: err = LIBUSB_ERROR_NO_DEVICE means the MMQ disappeared
// - need to delete it and rescan for it? (after a delay?)
// but check all (4) disappeared
mutex_unlock(modminer->modminer_mutex); mutex_unlock(modminer->modminer_mutex);
// timeoutloop never resets so the timeouts can't // timeoutloop never resets so the timeouts can't
@ -1053,6 +1060,10 @@ static int64_t modminer_scanhash(struct thr_info *thr, struct work *work, int64_
bool startwork; bool startwork;
struct timeval tv1, tv2; struct timeval tv1, tv2;
// Device is gone
if (thr->cgpu->nodev)
return -1;
// Don't start new work if overheated // Don't start new work if overheated
if (state->overheated == true) { if (state->overheated == true) {
gettimeofday(&tv1, NULL); gettimeofday(&tv1, NULL);
@ -1062,6 +1073,10 @@ static int64_t modminer_scanhash(struct thr_info *thr, struct work *work, int64_
while (state->overheated == true) { while (state->overheated == true) {
check_temperature(thr); check_temperature(thr);
// Device is gone
if (thr->cgpu->nodev)
return -1;
if (state->overheated == true) { if (state->overheated == true) {
gettimeofday(&tv2, NULL); gettimeofday(&tv2, NULL);

1
miner.h

@ -399,6 +399,7 @@ struct cgpu_info {
}; };
#if defined(USE_MODMINER) || defined(USE_BITFORCE) #if defined(USE_MODMINER) || defined(USE_BITFORCE)
int usbstat; int usbstat;
bool nodev;
#endif #endif
#ifdef USE_MODMINER #ifdef USE_MODMINER
char fpgaid; char fpgaid;

104
usbutils.c

@ -1,5 +1,5 @@
/* /*
* Copyright 2012 Andrew Smith * Copyright 2012-2013 Andrew Smith
* *
* This program is free software; you can redistribute it and/or modify it * 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 * under the terms of the GNU General Public License as published by the Free
@ -16,6 +16,10 @@
#include "miner.h" #include "miner.h"
#include "usbutils.h" #include "usbutils.h"
#define NODEV(err) ((err) == LIBUSB_ERROR_NO_DEVICE || \
(err) == LIBUSB_ERROR_PIPE || \
(err) == LIBUSB_ERROR_OTHER)
#ifdef USE_ICARUS #ifdef USE_ICARUS
#define DRV_ICARUS 1 #define DRV_ICARUS 1
#endif #endif
@ -161,6 +165,7 @@ static int next_stat = 0;
static const char **usb_commands; static const char **usb_commands;
static const char *C_REJECTED_S = "RejectedNoDevice";
static const char *C_PING_S = "Ping"; static const char *C_PING_S = "Ping";
static const char *C_CLEAR_S = "Clear"; static const char *C_CLEAR_S = "Clear";
static const char *C_REQUESTVERSION_S = "RequestVersion"; static const char *C_REQUESTVERSION_S = "RequestVersion";
@ -551,6 +556,7 @@ static void cgusb_check_init()
// use constants so the stat generation is very quick // use constants so the stat generation is very quick
// and the association between number and name can't // and the association between number and name can't
// be missalined easily // be missalined easily
usb_commands[C_REJECTED] = C_REJECTED_S;
usb_commands[C_PING] = C_PING_S; usb_commands[C_PING] = C_PING_S;
usb_commands[C_CLEAR] = C_CLEAR_S; usb_commands[C_CLEAR] = C_CLEAR_S;
usb_commands[C_REQUESTVERSION] = C_REQUESTVERSION_S; usb_commands[C_REQUESTVERSION] = C_REQUESTVERSION_S;
@ -673,8 +679,7 @@ static void release(uint8_t bus_number, uint8_t device_address, bool lock)
if (lock) if (lock)
mutex_lock(list_lock); mutex_lock(list_lock);
usb_tmp = usb_head; if ((usb_tmp = usb_head))
if (usb_tmp)
do { do {
if (bus_number == usb_tmp->bus_number if (bus_number == usb_tmp->bus_number
&& device_address == usb_tmp->device_address) { && device_address == usb_tmp->device_address) {
@ -698,6 +703,8 @@ static void release(uint8_t bus_number, uint8_t device_address, bool lock)
if (usb_tmp->next == usb_tmp) { if (usb_tmp->next == usb_tmp) {
usb_head = NULL; usb_head = NULL;
} else { } else {
if (usb_head == usb_tmp)
usb_head = usb_tmp->next;
usb_tmp->next->prev = usb_tmp->prev; usb_tmp->next->prev = usb_tmp->prev;
usb_tmp->prev->next = usb_tmp->next; usb_tmp->prev->next = usb_tmp->next;
} }
@ -719,13 +726,6 @@ static void release_dev(libusb_device *dev, bool lock)
release(bus_number, device_address, lock); release(bus_number, device_address, lock);
} }
#if 0
static void release_cgusb(struct cg_usb_device *cgusb, bool lock)
{
release(cgusb->bus_number, cgusb->device_address, lock);
}
#endif
static struct cg_usb_device *free_cgusb(struct cg_usb_device *cgusb) static struct cg_usb_device *free_cgusb(struct cg_usb_device *cgusb)
{ {
if (cgusb->serial_string && cgusb->serial_string != BLANK) if (cgusb->serial_string && cgusb->serial_string != BLANK)
@ -739,6 +739,8 @@ static struct cg_usb_device *free_cgusb(struct cg_usb_device *cgusb)
free(cgusb->descriptor); free(cgusb->descriptor);
free(cgusb->found);
free(cgusb); free(cgusb);
return NULL; return NULL;
@ -751,6 +753,31 @@ void usb_uninit(struct cgpu_info *cgpu)
cgpu->usbdev = free_cgusb(cgpu->usbdev); cgpu->usbdev = free_cgusb(cgpu->usbdev);
} }
void release_cgpu(struct cgpu_info *cgpu)
{
struct cg_usb_device *cgusb = cgpu->usbdev;
uint8_t bus_number;
uint8_t device_address;
int i;
cgpu->nodev = true;
// Any devices sharing the same USB device should be marked also
// Currently only MMQ shares a USB device
for (i = 0; i < total_devices; i++)
if (devices[i] != cgpu && devices[i]->usbdev == cgusb) {
devices[i]->nodev = true;
devices[i]->usbdev = NULL;
}
bus_number = cgusb->bus_number;
device_address = cgusb->device_address;
usb_uninit(cgpu);
release(bus_number, device_address, true);
}
bool usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct usb_find_devices *found) bool usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct usb_find_devices *found)
{ {
struct cg_usb_device *cgusb = NULL; struct cg_usb_device *cgusb = NULL;
@ -1172,6 +1199,19 @@ static void stats(struct cgpu_info *cgpu, struct timeval *tv_start, struct timev
memcpy(&(details->item[item].last), tv_start, sizeof(tv_start)); memcpy(&(details->item[item].last), tv_start, sizeof(tv_start));
details->item[item].count++; details->item[item].count++;
} }
static void rejected_inc(struct cgpu_info *cgpu)
{
struct cg_usb_stats_details *details;
int item = CMD_ERROR;
if (cgpu->usbstat < 1)
newstats(cgpu);
details = &(usb_stats[cgpu->usbstat - 1].details[C_REJECTED * 2 + 0]);
details->item[item].count++;
}
#endif #endif
int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *processed, unsigned int timeout, int eol, enum usb_cmds cmd, bool ftdi) int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *processed, unsigned int timeout, int eol, enum usb_cmds cmd, bool ftdi)
@ -1186,6 +1226,15 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro
int err, got, tot, i; int err, got, tot, i;
bool first = true; bool first = true;
if (cgpu->nodev) {
*buf = '\0';
*processed = 0;
#if DO_USB_STATS
rejected_inc(cgpu);
#endif
return LIBUSB_ERROR_NO_DEVICE;
}
if (timeout == DEVTIMEOUT) if (timeout == DEVTIMEOUT)
timeout = usbdev->found->timeout; timeout = usbdev->found->timeout;
@ -1212,6 +1261,11 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro
*processed = got; *processed = got;
if (NODEV(err)) {
cgpu->nodev = true;
release_cgpu(cgpu);
}
return err; return err;
} }
@ -1268,6 +1322,11 @@ goteol:
*processed = tot; *processed = tot;
if (NODEV(err)) {
cgpu->nodev = true;
release_cgpu(cgpu);
}
return err; return err;
} }
@ -1279,6 +1338,14 @@ int _usb_write(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pr
#endif #endif
int err, sent; int err, sent;
if (cgpu->nodev) {
*processed = 0;
#if DO_USB_STATS
rejected_inc(cgpu);
#endif
return LIBUSB_ERROR_NO_DEVICE;
}
sent = 0; sent = 0;
STATS_TIMEVAL(&tv_start); STATS_TIMEVAL(&tv_start);
err = libusb_bulk_transfer(usbdev->handle, err = libusb_bulk_transfer(usbdev->handle,
@ -1291,6 +1358,11 @@ int _usb_write(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pr
*processed = sent; *processed = sent;
if (NODEV(err)) {
cgpu->nodev = true;
release_cgpu(cgpu);
}
return err; return err;
} }
@ -1302,6 +1374,13 @@ int _usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest
#endif #endif
int err; int err;
if (cgpu->nodev) {
#if DO_USB_STATS
rejected_inc(cgpu);
#endif
return LIBUSB_ERROR_NO_DEVICE;
}
STATS_TIMEVAL(&tv_start); STATS_TIMEVAL(&tv_start);
err = libusb_control_transfer(usbdev->handle, request_type, err = libusb_control_transfer(usbdev->handle, request_type,
bRequest, wValue, wIndex, NULL, 0, bRequest, wValue, wIndex, NULL, 0,
@ -1309,6 +1388,11 @@ int _usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest
STATS_TIMEVAL(&tv_finish); STATS_TIMEVAL(&tv_finish);
USB_STATS(cgpu, &tv_start, &tv_finish, err, cmd, SEQ0); USB_STATS(cgpu, &tv_start, &tv_finish, err, cmd, SEQ0);
if (NODEV(err)) {
cgpu->nodev = true;
release_cgpu(cgpu);
}
return err; return err;
} }

6
usbutils.h

@ -1,5 +1,5 @@
/* /*
* Copyright 2012 Andrew Smith * Copyright 2012-2013 Andrew Smith
* *
* This program is free software; you can redistribute it and/or modify it * 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 * under the terms of the GNU General Public License as published by the Free
@ -79,7 +79,8 @@ struct cg_usb_device {
}; };
enum usb_cmds { enum usb_cmds {
C_PING = 0, C_REJECTED = 0,
C_PING,
C_CLEAR, C_CLEAR,
C_REQUESTVERSION, C_REQUESTVERSION,
C_GETVERSION, C_GETVERSION,
@ -120,6 +121,7 @@ struct device_drv;
struct cgpu_info; struct cgpu_info;
void usb_uninit(struct cgpu_info *cgpu); void usb_uninit(struct cgpu_info *cgpu);
void release_cgpu(struct cgpu_info *cgpu);
bool usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct usb_find_devices *found); bool usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct usb_find_devices *found);
void usb_detect(struct device_drv *drv, bool (*device_detect)(struct libusb_device *, struct usb_find_devices *)); void usb_detect(struct device_drv *drv, bool (*device_detect)(struct libusb_device *, struct usb_find_devices *));
struct api_data *api_usb_stats(int *count); struct api_data *api_usb_stats(int *count);

Loading…
Cancel
Save