Skip to content

Commit

Permalink
USB automatically handle losing the device and report nodev in the API
Browse files Browse the repository at this point in the history
  • Loading branch information
kanoi committed Feb 2, 2013
1 parent 4f460ca commit 34bcc1c
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 20 deletions.
1 change: 1 addition & 0 deletions API-README
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ Added API commands:

Modified API commands:
'pools' - add 'Best Share'
'devs' and 'pga' - add 'No Device' for PGAs if MMQ or BFL compiled

----------

Expand Down
14 changes: 14 additions & 0 deletions api.c
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@ static const char *JSON_PARAMETER = "parameter";
#define MSG_ZERINV 95
#define MSG_ZERSUM 96
#define MSG_ZERNOSUM 97
#define MSG_USBNODEV 98

enum code_severity {
SEVERITY_ERR,
Expand Down Expand Up @@ -568,6 +569,9 @@ struct CODES {
{ SEVERITY_ERR, MSG_ZERINV, PARAM_STR, "Invalid zero parameter '%s'" },
{ SEVERITY_SUCC, MSG_ZERSUM, PARAM_STR, "Zeroed %s stats with 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 }
};

Expand Down Expand Up @@ -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 Rejected", &(cgpu->diff_rejected), 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);
io_add(io_data, buf);
Expand Down Expand Up @@ -1785,6 +1792,13 @@ static void pgaenable(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char
}
#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++) {
pga = thr_info[i].cgpu->cgminer_id;
if (pga == dev) {
Expand Down
30 changes: 29 additions & 1 deletion driver-bitforce.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012 Andrew Smith
* Copyright 2012-2013 Andrew Smith
* Copyright 2012 Luke Dashjr
* Copyright 2012 Con Kolivas
*
Expand Down Expand Up @@ -82,13 +82,19 @@ static void bitforce_initialise(struct cgpu_info *bitforce, bool lock)
applog(LOG_DEBUG, "%s%i: reset got err %d",
bitforce->drv->name, bitforce->device_id, err);

if (bitforce->nodev)
goto failed;

// Set data control
err = usb_transfer(bitforce, FTDI_TYPE_OUT, FTDI_REQUEST_DATA,
FTDI_VALUE_DATA, bitforce->usbdev->found->interface, C_SETDATA);
if (opt_debug)
applog(LOG_DEBUG, "%s%i: setdata got err %d",
bitforce->drv->name, bitforce->device_id, err);

if (bitforce->nodev)
goto failed;

// Set the baud
err = usb_transfer(bitforce, FTDI_TYPE_OUT, FTDI_REQUEST_BAUD, FTDI_VALUE_BAUD,
(FTDI_INDEX_BAUD & 0xff00) | bitforce->usbdev->found->interface,
Expand All @@ -97,34 +103,48 @@ static void bitforce_initialise(struct cgpu_info *bitforce, bool lock)
applog(LOG_DEBUG, "%s%i: setbaud got err %d",
bitforce->drv->name, bitforce->device_id, err);

if (bitforce->nodev)
goto failed;

// Set Flow Control
err = usb_transfer(bitforce, FTDI_TYPE_OUT, FTDI_REQUEST_FLOW,
FTDI_VALUE_FLOW, bitforce->usbdev->found->interface, C_SETFLOW);
if (opt_debug)
applog(LOG_DEBUG, "%s%i: setflowctrl got err %d",
bitforce->drv->name, bitforce->device_id, err);

if (bitforce->nodev)
goto failed;

// Set Modem Control
err = usb_transfer(bitforce, FTDI_TYPE_OUT, FTDI_REQUEST_MODEM,
FTDI_VALUE_MODEM, bitforce->usbdev->found->interface, C_SETMODEM);
if (opt_debug)
applog(LOG_DEBUG, "%s%i: setmodemctrl got err %d",
bitforce->drv->name, bitforce->device_id, err);

if (bitforce->nodev)
goto failed;

// Clear any sent data
err = usb_transfer(bitforce, FTDI_TYPE_OUT, FTDI_REQUEST_RESET,
FTDI_VALUE_PURGE_TX, bitforce->usbdev->found->interface, C_PURGETX);
if (opt_debug)
applog(LOG_DEBUG, "%s%i: purgetx got err %d",
bitforce->drv->name, bitforce->device_id, err);

if (bitforce->nodev)
goto failed;

// Clear any received data
err = usb_transfer(bitforce, FTDI_TYPE_OUT, FTDI_REQUEST_RESET,
FTDI_VALUE_PURGE_RX, bitforce->usbdev->found->interface, C_PURGERX);
if (opt_debug)
applog(LOG_DEBUG, "%s%i: purgerx got err %d",
bitforce->drv->name, bitforce->device_id, err);

failed:

if (lock)
mutex_unlock(&bitforce->device_mutex);
}
Expand Down Expand Up @@ -322,6 +342,10 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce)
int err, amount;
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
* minimise the chance of interleaved results */
if (bitforce->polling)
Expand Down Expand Up @@ -640,6 +664,10 @@ static int64_t bitforce_scanhash(struct thr_info *thr, struct work *work, int64_
bool send_ret;
int64_t ret;

// Device is gone
if (bitforce->nodev)
return -1;

send_ret = bitforce_send_work(thr, work);

if (!restart_wait(bitforce->sleep_ms))
Expand Down
29 changes: 22 additions & 7 deletions driver-modminer.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012 Andrew Smith
* Copyright 2012-2013 Andrew Smith
* Copyright 2012 Luke Dashjr
*
* This program is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -607,6 +607,7 @@ static bool modminer_fpga_prepare(struct thr_info *thr)
*
* 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 *clocktoolow = "clock too low";
static const char *clocktoohi = "clock too high";
Expand All @@ -620,6 +621,10 @@ static const char *modminer_delta_clock(struct thr_info *thr, int delta, bool te
unsigned char cmd[6], buf[1];
int err, amount;

// Device is gone
if (modminer->nodev)
return clocknodev;

// Only do once if multiple shares per work or multiple reasons
if (!state->new_work && !force)
return clockoldwork;
Expand Down Expand Up @@ -775,9 +780,6 @@ static bool modminer_start_work(struct thr_info *thr)
mutex_lock(modminer->modminer_mutex);

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);

applog(LOG_ERR, "%s%u: Start work failed (%d:%d)",
Expand Down Expand Up @@ -807,6 +809,10 @@ static void check_temperature(struct thr_info *thr)
int tbytes, tamount;
int amount;

// Device is gone
if (modminer->nodev)
return;

if (state->one_byte_temp) {
cmd[0] = MODMINER_TEMP1;
tbytes = 1;
Expand Down Expand Up @@ -891,6 +897,10 @@ static uint64_t modminer_process_results(struct thr_info *thr)
double timeout;
int temploop;

// Device is gone
if (modminer->nodev)
return -1;

// If we are overheated it will just keep checking for results
// since we can't stop the work
// The next work will not start until the temp drops
Expand All @@ -904,9 +914,6 @@ static uint64_t modminer_process_results(struct thr_info *thr)
while (1) {
mutex_lock(modminer->modminer_mutex);
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);

// timeoutloop never resets so the timeouts can't
Expand Down Expand Up @@ -1053,6 +1060,10 @@ static int64_t modminer_scanhash(struct thr_info *thr, struct work *work, int64_
bool startwork;
struct timeval tv1, tv2;

// Device is gone
if (thr->cgpu->nodev)
return -1;

// Don't start new work if overheated
if (state->overheated == true) {
gettimeofday(&tv1, NULL);
Expand All @@ -1062,6 +1073,10 @@ static int64_t modminer_scanhash(struct thr_info *thr, struct work *work, int64_
while (state->overheated == true) {
check_temperature(thr);

// Device is gone
if (thr->cgpu->nodev)
return -1;

if (state->overheated == true) {
gettimeofday(&tv2, NULL);

Expand Down
1 change: 1 addition & 0 deletions miner.h
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ struct cgpu_info {
};
#if defined(USE_MODMINER) || defined(USE_BITFORCE)
int usbstat;
bool nodev;
#endif
#ifdef USE_MODMINER
char fpgaid;
Expand Down
Loading

0 comments on commit 34bcc1c

Please sign in to comment.