mirror of
https://github.com/GOSTSec/sgminer
synced 2025-01-22 20:44:19 +00:00
USB automatically handle losing the device and report nodev in the API
This commit is contained in:
parent
4f460ca72d
commit
34bcc1c66d
@ -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
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) {
|
||||||
|
@ -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))
|
||||||
|
@ -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
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
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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…
x
Reference in New Issue
Block a user