Browse Source

First pass rewriting serialdev into direct usb dev for avalon driver.

nfactor-troky
Con Kolivas 12 years ago
parent
commit
269a8de977
  1. 308
      driver-avalon.c
  2. 7
      driver-avalon.h
  3. 3
      miner.h
  4. 15
      usbutils.c
  5. 15
      usbutils.h

308
driver-avalon.c

@ -122,38 +122,29 @@ static inline void avalon_create_task(struct avalon_task *at,
memcpy(at->data, work->data + 64, 12); memcpy(at->data, work->data + 64, 12);
} }
static int avalon_write(int fd, char *buf, ssize_t len) static int avalon_write(struct cgpu_info *avalon, char *buf, ssize_t len)
{ {
ssize_t wrote = 0; ssize_t wrote = 0;
while (len > 0) { while (len > 0) {
struct timeval timeout; int amount, err;
ssize_t ret;
fd_set wd; err = usb_write(avalon, buf + wrote, len, &amount, C_AVALON_TASK);
applog(LOG_DEBUG, "%s%i: usb_write got err %d",
timeout.tv_sec = 0; avalon->drv->name, avalon->device_id, err);
timeout.tv_usec = 100000;
FD_ZERO(&wd); if (unlikely(err != 0)) {
FD_SET((SOCKETTYPE)fd, &wd); applog(LOG_WARNING, "usb_write error on avalon_write");
ret = select(fd + 1, NULL, &wd, NULL, &timeout);
if (unlikely(ret < 1)) {
applog(LOG_WARNING, "Select error on avalon_write");
return AVA_SEND_ERROR;
}
ret = write(fd, buf + wrote, len);
if (unlikely(ret < 1)) {
applog(LOG_WARNING, "Write error on avalon_write");
return AVA_SEND_ERROR; return AVA_SEND_ERROR;
} }
wrote += ret; wrote += amount;
len -= ret; len -= amount;
} }
return AVA_SEND_OK; return AVA_SEND_OK;
} }
static int avalon_send_task(int fd, const struct avalon_task *at, static int avalon_send_task(const struct avalon_task *at, struct cgpu_info *avalon)
struct cgpu_info *avalon)
{ {
struct timespec p; struct timespec p;
@ -213,7 +204,7 @@ static int avalon_send_task(int fd, const struct avalon_task *at,
applog(LOG_DEBUG, "Avalon: Sent(%u):", (unsigned int)nr_len); applog(LOG_DEBUG, "Avalon: Sent(%u):", (unsigned int)nr_len);
hexdump(buf, nr_len); hexdump(buf, nr_len);
} }
ret = avalon_write(fd, (char *)buf, nr_len); ret = avalon_write(avalon, (char *)buf, nr_len);
p.tv_sec = 0; p.tv_sec = 0;
p.tv_nsec = (long)delay + 4000000; p.tv_nsec = (long)delay + 4000000;
@ -236,31 +227,37 @@ static bool avalon_decode_nonce(struct thr_info *thr, struct cgpu_info *avalon,
return submit_nonce(thr, work, nonce); return submit_nonce(thr, work, nonce);
} }
static int avalon_read(int fd, char *buf, ssize_t len) static int avalon_read(struct cgpu_info *avalon, char *buf, ssize_t len)
{ {
ssize_t aread = 0; ssize_t aread = 0;
while (len > 0) { while (len > 0) {
struct timeval timeout; int amount, err, offset, cp;
ssize_t ret; char readbuf[AVALON_FTDI_READSIZE];
fd_set rd;
err = usb_read_once_timeout(avalon, readbuf, AVALON_FTDI_READSIZE,
timeout.tv_sec = 0; &amount, AVALON_READ_TIMEOUT,
timeout.tv_usec = 100000; C_AVALON_READ);
FD_ZERO(&rd); if (err && err != LIBUSB_ERROR_TIMEOUT) {
FD_SET((SOCKETTYPE)fd, &rd); applog(LOG_WARNING, "%s%i: Get avalon read got err %d",
ret = select(fd + 1, &rd, NULL, NULL, &timeout); avalon->drv->name, avalon->device_id, err);
if (unlikely(ret < 1)) { nmsleep(AVALON_READ_TIMEOUT);
applog(LOG_WARNING, "Select error on avalon_read"); continue;
return AVA_GETS_ERROR;
}
ret = read(fd, buf + aread, len);
if (unlikely(ret < 1)) {
applog(LOG_WARNING, "Read error on avalon_read");
return AVA_GETS_ERROR;
} }
aread += ret;
len -= ret; if (amount < 3)
continue;
offset = 2;
do {
cp = amount - 2;
if (cp > 62)
cp = 62;
memcpy(&buf[aread], readbuf, cp);
aread += cp;
amount -= cp + 2;
offset += 64;
} while (amount > 2);
} }
return AVA_GETS_OK; return AVA_GETS_OK;
@ -268,14 +265,14 @@ static int avalon_read(int fd, char *buf, ssize_t len)
/* Wait until the ftdi chip returns a CTS saying we can send more data. The /* Wait until the ftdi chip returns a CTS saying we can send more data. The
* status is updated every 40ms. */ * status is updated every 40ms. */
static void wait_avalon_ready(int fd) static void wait_avalon_ready(struct cgpu_info *avalon)
{ {
while (avalon_buffer_full(fd) == AVA_BUFFER_FULL) { while (avalon_buffer_full(avalon)) {
nmsleep(40); nmsleep(40);
} }
} }
static int avalon_reset(struct cgpu_info *avalon, int fd, bool initial) static int avalon_reset(struct cgpu_info *avalon, bool initial)
{ {
struct avalon_result ar; struct avalon_result ar;
struct avalon_task at; struct avalon_task at;
@ -292,9 +289,9 @@ static int avalon_reset(struct cgpu_info *avalon, int fd, bool initial)
0, 0, 0, 0,
AVALON_DEFAULT_FREQUENCY); AVALON_DEFAULT_FREQUENCY);
wait_avalon_ready(fd); wait_avalon_ready(avalon);
ret = avalon_send_task(fd, &at, NULL); ret = avalon_send_task(&at, NULL);
if (unlikely(ret == AVA_SEND_ERROR)) if (unlikely(ret == AVA_SEND_ERROR))
return -1; return -1;
@ -303,7 +300,7 @@ static int avalon_reset(struct cgpu_info *avalon, int fd, bool initial)
return 0; return 0;
} }
ret = avalon_read(fd, (char *)&ar, AVALON_READ_SIZE); ret = avalon_read(avalon, (char *)&ar, AVALON_READ_SIZE);
if (unlikely(ret == AVA_GETS_ERROR)) if (unlikely(ret == AVA_GETS_ERROR))
return -1; return -1;
@ -483,13 +480,12 @@ static void get_options(int this_option_offset, int *baud, int *miner_count,
} }
} }
static void avalon_idle(struct cgpu_info *avalon, struct avalon_info *info, static void avalon_idle(struct cgpu_info *avalon, struct avalon_info *info)
int fd)
{ {
int i; int i;
info->idle = true; info->idle = true;
wait_avalon_ready(fd); wait_avalon_ready(avalon);
applog(LOG_WARNING, "AVA%i: Idling %d miners", avalon->device_id, applog(LOG_WARNING, "AVA%i: Idling %d miners", avalon->device_id,
info->miner_count); info->miner_count);
/* Send idle to all miners */ /* Send idle to all miners */
@ -499,53 +495,134 @@ static void avalon_idle(struct cgpu_info *avalon, struct avalon_info *info,
avalon_init_task(&at, 0, 0, info->fan_pwm, info->timeout, avalon_init_task(&at, 0, 0, info->fan_pwm, info->timeout,
info->asic_count, info->miner_count, 1, 1, info->asic_count, info->miner_count, 1, 1,
info->frequency); info->frequency);
avalon_send_task(fd, &at, avalon); avalon_send_task(&at, avalon);
} }
wait_avalon_ready(fd); wait_avalon_ready(avalon);
} }
static bool avalon_detect_one(const char *devpath) static void avalon_initialise(struct cgpu_info *avalon)
{
int err, interface;
if (avalon->usbinfo.nodev)
return;
interface = avalon->usbdev->found->interface;
// Reset
err = usb_transfer(avalon, FTDI_TYPE_OUT, FTDI_REQUEST_RESET,
FTDI_VALUE_RESET, interface, C_RESET);
applog(LOG_DEBUG, "%s%i: reset got err %d",
avalon->drv->name, avalon->device_id, err);
if (avalon->usbinfo.nodev)
return;
// Set data
err = usb_transfer(avalon, FTDI_TYPE_OUT, FTDI_REQUEST_DATA,
FTDI_VALUE_DATA_AVA, interface, C_SETDATA);
applog(LOG_DEBUG, "%s%i: data got err %d",
avalon->drv->name, avalon->device_id, err);
if (avalon->usbinfo.nodev)
return;
// Set the baud
err = usb_transfer(avalon, FTDI_TYPE_OUT, FTDI_REQUEST_BAUD, FTDI_VALUE_BAUD_AVA,
(FTDI_INDEX_BAUD_AVA & 0xff00) | interface,
C_SETBAUD);
applog(LOG_DEBUG, "%s%i: setbaud got err %d",
avalon->drv->name, avalon->device_id, err);
if (avalon->usbinfo.nodev)
return;
// Set Modem Control
err = usb_transfer(avalon, FTDI_TYPE_OUT, FTDI_REQUEST_MODEM,
FTDI_VALUE_MODEM, interface, C_SETMODEM);
applog(LOG_DEBUG, "%s%i: setmodemctrl got err %d",
avalon->drv->name, avalon->device_id, err);
if (avalon->usbinfo.nodev)
return;
// Set Flow Control
err = usb_transfer(avalon, FTDI_TYPE_OUT, FTDI_REQUEST_FLOW,
FTDI_VALUE_FLOW, interface, C_SETFLOW);
applog(LOG_DEBUG, "%s%i: setflowctrl got err %d",
avalon->drv->name, avalon->device_id, err);
if (avalon->usbinfo.nodev)
return;
/* Avalon repeats the following */
// Set Modem Control
err = usb_transfer(avalon, FTDI_TYPE_OUT, FTDI_REQUEST_MODEM,
FTDI_VALUE_MODEM, interface, C_SETMODEM);
applog(LOG_DEBUG, "%s%i: setmodemctrl 2 got err %d",
avalon->drv->name, avalon->device_id, err);
if (avalon->usbinfo.nodev)
return;
// Set Flow Control
err = usb_transfer(avalon, FTDI_TYPE_OUT, FTDI_REQUEST_FLOW,
FTDI_VALUE_FLOW, interface, C_SETFLOW);
applog(LOG_DEBUG, "%s%i: setflowctrl 2 got err %d",
avalon->drv->name, avalon->device_id, err);
}
static bool avalon_detect_one(libusb_device *dev, struct usb_find_devices *found)
{ {
struct avalon_info *info;
int fd, ret;
int baud, miner_count, asic_count, timeout, frequency = 0; int baud, miner_count, asic_count, timeout, frequency = 0;
int this_option_offset = ++option_offset;
struct avalon_info *info;
struct cgpu_info *avalon; struct cgpu_info *avalon;
char devpath[20];
int ret;
avalon = calloc(1, sizeof(struct cgpu_info));
if (unlikely(!avalon))
quit(1, "Failed to calloc avalon in avalon_detect_one");;
avalon->drv = &avalon_drv;
avalon->threads = AVALON_MINER_THREADS;
int this_option_offset = ++option_offset;
get_options(this_option_offset, &baud, &miner_count, &asic_count, get_options(this_option_offset, &baud, &miner_count, &asic_count,
&timeout, &frequency); &timeout, &frequency);
applog(LOG_DEBUG, "Avalon Detect: Attempting to open %s " if (!usb_init(avalon, dev, found))
"(baud=%d miner_count=%d asic_count=%d timeout=%d frequency=%d)",
devpath, baud, miner_count, asic_count, timeout, frequency);
fd = avalon_open2(devpath, baud, true);
if (unlikely(fd == -1)) {
applog(LOG_ERR, "Avalon Detect: Failed to open %s", devpath);
return false; return false;
}
/* We have a real Avalon! */ /* We have a real Avalon! */
avalon = calloc(1, sizeof(struct cgpu_info)); sprintf(devpath, "%d:%d",
avalon->drv = &avalon_drv; (int)(avalon->usbinfo.bus_number),
(int)(avalon->usbinfo.device_address));
avalon_initialise(avalon);
applog(LOG_DEBUG, "Avalon Detected: %s "
"(miner_count=%d asic_count=%d timeout=%d frequency=%d)",
devpath, miner_count, asic_count, timeout, frequency);
avalon->device_path = strdup(devpath); avalon->device_path = strdup(devpath);
avalon->device_fd = fd;
avalon->threads = AVALON_MINER_THREADS;
add_cgpu(avalon); add_cgpu(avalon);
avalon_infos = realloc(avalon_infos, avalon_infos = realloc(avalon_infos,
sizeof(struct avalon_info *) * sizeof(struct avalon_info *) *
(total_devices + 1)); (total_devices + 1));
if (unlikely(!avalon_infos))
applog(LOG_INFO, "Avalon Detect: Found at %s, mark as %d", quit(1, "Failed to malloc avalon_infos");
devpath, avalon->device_id);
avalon_infos[avalon->device_id] = calloc(sizeof(struct avalon_info), 1); avalon_infos[avalon->device_id] = calloc(sizeof(struct avalon_info), 1);
if (unlikely(!(avalon_infos[avalon->device_id]))) if (unlikely(!(avalon_infos[avalon->device_id])))
quit(1, "Failed to calloc avalon_infos"); quit(1, "Failed to malloc avalon_infos device");
info = avalon_infos[avalon->device_id];
avalon->device_data = avalon_infos[avalon->device_id];
info = avalon->device_data;
info->baud = baud; info->baud = baud;
info->miner_count = miner_count; info->miner_count = miner_count;
@ -564,20 +641,20 @@ static bool avalon_detect_one(const char *devpath)
info->temp_old = 0; info->temp_old = 0;
info->frequency = frequency; info->frequency = frequency;
ret = avalon_reset(avalon, fd, true); ret = avalon_reset(avalon, true);
if (ret) { if (ret) {
; /* FIXME: I think IT IS avalon and wait on reset; /* FIXME:
* avalon_close(fd); * avalon_close(fd);
* return false; */ * return false; */
} }
avalon_idle(avalon, info, fd); avalon_idle(avalon, info);
return true; return true;
} }
static inline void avalon_detect() static void avalon_detect(void)
{ {
serial_detect(&avalon_drv, avalon_detect_one); usb_detect(&avalon_drv, avalon_detect_one);
} }
static void avalon_init(struct cgpu_info *avalon) static void avalon_init(struct cgpu_info *avalon)
@ -658,21 +735,21 @@ static void avalon_parse_results(struct cgpu_info *avalon, struct avalon_info *i
} }
static void __avalon_running_reset(struct cgpu_info *avalon, static void __avalon_running_reset(struct cgpu_info *avalon,
struct avalon_info *info, int fd) struct avalon_info *info)
{ {
info->reset = true; info->reset = true;
avalon_reset(avalon, fd, false); avalon_reset(avalon, false);
avalon_idle(avalon, info, fd); avalon_idle(avalon, info);
avalon->results = 0; avalon->results = 0;
info->reset = false; info->reset = false;
} }
static void avalon_running_reset(struct cgpu_info *avalon, static void avalon_running_reset(struct cgpu_info *avalon,
struct avalon_info *info, int fd) struct avalon_info *info)
{ {
/* Lock to prevent more work being sent during reset */ /* Lock to prevent more work being sent during reset */
mutex_lock(&info->qlock); mutex_lock(&info->qlock);
__avalon_running_reset(avalon, info, fd); __avalon_running_reset(avalon, info);
mutex_unlock(&info->qlock); mutex_unlock(&info->qlock);
} }
@ -683,7 +760,6 @@ static void *avalon_get_results(void *userdata)
const int rsize = AVALON_FTDI_READSIZE; const int rsize = AVALON_FTDI_READSIZE;
char readbuf[AVALON_READBUF_SIZE]; char readbuf[AVALON_READBUF_SIZE];
struct thr_info *thr = info->thr; struct thr_info *thr = info->thr;
int fd = avalon->device_fd;
char threadname[24]; char threadname[24];
int offset = 0; int offset = 0;
@ -693,10 +769,8 @@ static void *avalon_get_results(void *userdata)
RenameThread(threadname); RenameThread(threadname);
while (42) { while (42) {
struct timeval timeout; int amount, err, ofs, cp;
char buf[rsize]; char buf[rsize];
ssize_t ret;
fd_set rd;
if (offset >= (int)AVALON_READ_SIZE) if (offset >= (int)AVALON_READ_SIZE)
avalon_parse_results(avalon, info, thr, readbuf, &offset); avalon_parse_results(avalon, info, thr, readbuf, &offset);
@ -707,26 +781,21 @@ static void *avalon_get_results(void *userdata)
offset = 0; offset = 0;
} }
timeout.tv_sec = 0; err = usb_read_once_timeout(avalon, buf, rsize, &amount,
timeout.tv_usec = AVALON_READ_TIMEOUT * 1000; AVALON_READ_TIMEOUT, C_AVALON_READ);
FD_ZERO(&rd); if (err && err != LIBUSB_ERROR_TIMEOUT) {
FD_SET((SOCKETTYPE)fd, &rd); applog(LOG_WARNING, "%s%i: Get avalon read got err %d",
ret = select(fd + 1, &rd, NULL, NULL, &timeout); avalon->drv->name, avalon->device_id, err);
if (ret < 1) { nmsleep(AVALON_READ_TIMEOUT);
if (unlikely(ret < 0))
applog(LOG_WARNING, "Select error in avalon_get_results");
continue; continue;
} }
ret = read(fd, buf, AVALON_FTDI_READSIZE);
if (unlikely(ret < 1)) { if (amount < 3)
if (unlikely(ret < 0))
applog(LOG_WARNING, "Read error in avalon_get_results");
continue; continue;
}
if (opt_debug) { if (opt_debug) {
applog(LOG_DEBUG, "Avalon: get:"); applog(LOG_DEBUG, "Avalon: get:");
hexdump((uint8_t *)buf, ret); hexdump((uint8_t *)buf, amount);
} }
/* During a reset, goes on reading but discards anything */ /* During a reset, goes on reading but discards anything */
@ -735,8 +804,16 @@ static void *avalon_get_results(void *userdata)
continue; continue;
} }
memcpy(&readbuf[offset], buf, ret); ofs = 2;
offset += ret; do {
cp = amount - 2;
if (cp > 62)
cp = 62;
memcpy(&readbuf[offset], &buf[ofs], cp);
offset += cp;
amount -= cp + 2;
ofs += 64;
} while (amount > 2);
} }
return NULL; return NULL;
} }
@ -753,7 +830,6 @@ static void *avalon_send_tasks(void *userdata)
struct cgpu_info *avalon = (struct cgpu_info *)userdata; struct cgpu_info *avalon = (struct cgpu_info *)userdata;
struct avalon_info *info = avalon->device_data; struct avalon_info *info = avalon->device_data;
const int avalon_get_work_count = info->miner_count; const int avalon_get_work_count = info->miner_count;
int fd = avalon->device_fd;
char threadname[24]; char threadname[24];
pthread_detach(pthread_self()); pthread_detach(pthread_self());
@ -766,13 +842,13 @@ static void *avalon_send_tasks(void *userdata)
struct avalon_task at; struct avalon_task at;
int idled = 0; int idled = 0;
wait_avalon_ready(fd); wait_avalon_ready(avalon);
mutex_lock(&info->qlock); mutex_lock(&info->qlock);
start_count = avalon->work_array * avalon_get_work_count; start_count = avalon->work_array * avalon_get_work_count;
end_count = start_count + avalon_get_work_count; end_count = start_count + avalon_get_work_count;
for (i = start_count, j = 0; i < end_count; i++, j++) { for (i = start_count, j = 0; i < end_count; i++, j++) {
if (unlikely(avalon_buffer_full(fd) == AVA_BUFFER_FULL)) { if (unlikely(avalon_buffer_full(avalon))) {
applog(LOG_WARNING, applog(LOG_WARNING,
"AVA%i: Buffer full after only %d of %d work queued", "AVA%i: Buffer full after only %d of %d work queued",
avalon->device_id, j, avalon_get_work_count); avalon->device_id, j, avalon_get_work_count);
@ -791,12 +867,12 @@ static void *avalon_send_tasks(void *userdata)
info->timeout, info->asic_count, info->timeout, info->asic_count,
info->miner_count, 1, 1, info->frequency); info->miner_count, 1, 1, info->frequency);
} }
ret = avalon_send_task(fd, &at, avalon); ret = avalon_send_task(&at, avalon);
if (unlikely(ret == AVA_SEND_ERROR)) { if (unlikely(ret == AVA_SEND_ERROR)) {
applog(LOG_ERR, "AVA%i: Comms error(buffer)", applog(LOG_ERR, "AVA%i: Comms error(buffer)",
avalon->device_id); avalon->device_id);
dev_error(avalon, REASON_DEV_COMMS_ERROR); dev_error(avalon, REASON_DEV_COMMS_ERROR);
__avalon_running_reset(avalon, info, fd); __avalon_running_reset(avalon, info);
break; break;
} }
} }
@ -875,15 +951,13 @@ static void do_avalon_close(struct thr_info *thr)
{ {
struct cgpu_info *avalon = thr->cgpu; struct cgpu_info *avalon = thr->cgpu;
struct avalon_info *info = avalon->device_data; struct avalon_info *info = avalon->device_data;
int fd = avalon->device_fd;
pthread_cancel(info->read_thr); pthread_cancel(info->read_thr);
pthread_cancel(info->write_thr); pthread_cancel(info->write_thr);
__avalon_running_reset(avalon, info, fd); __avalon_running_reset(avalon, info);
avalon_idle(avalon, info, fd); avalon_idle(avalon, info);
avalon_free_work(thr); avalon_free_work(thr);
avalon_close(fd); //avalon_close();
avalon->device_fd = -1;
info->no_matching_work = 0; info->no_matching_work = 0;
} }
@ -1028,7 +1102,7 @@ static int64_t avalon_scanhash(struct thr_info *thr)
if (avalon->results < -miner_count) { if (avalon->results < -miner_count) {
applog(LOG_ERR, "AVA%d: Result return rate low, resetting!", applog(LOG_ERR, "AVA%d: Result return rate low, resetting!",
avalon->device_id); avalon->device_id);
avalon_running_reset(avalon, info, avalon->device_fd); avalon_running_reset(avalon, info);
} }
/* This hashmeter is just a utility counter based on returned shares */ /* This hashmeter is just a utility counter based on returned shares */

7
driver-avalon.h

@ -122,13 +122,6 @@ struct avalon_info {
#define AVA_SEND_ERROR -1 #define AVA_SEND_ERROR -1
#define AVA_SEND_OK 0 #define AVA_SEND_OK 0
#define AVA_BUFFER_FULL 0
#define AVA_BUFFER_EMPTY 1
#define avalon_open2(devpath, baud, purge) serial_open(devpath, baud, AVALON_RESET_FAULT_DECISECONDS, purge)
#define avalon_open(devpath, baud) avalon_open2(devpath, baud, true)
#define avalon_close(fd) close(fd)
#define avalon_buffer_full(avalon) !usb_ftdi_cts(avalon) #define avalon_buffer_full(avalon) !usb_ftdi_cts(avalon)
#define AVALON_READ_TIME(baud) ((double)AVALON_READ_SIZE * (double)8.0 / (double)(baud)) #define AVALON_READ_TIME(baud) ((double)AVALON_READ_SIZE * (double)8.0 / (double)(baud))

3
miner.h

@ -429,9 +429,6 @@ struct cgpu_info {
#endif #endif
#ifdef USE_USBUTILS #ifdef USE_USBUTILS
struct cg_usb_device *usbdev; struct cg_usb_device *usbdev;
#endif
#ifdef USE_AVALON
int device_fd;
#endif #endif
}; };
#ifdef USE_AVALON #ifdef USE_AVALON

15
usbutils.c

@ -455,6 +455,12 @@ static const char *C_SENDTESTWORK_S = "SendTestWork";
static const char *C_LATENCY_S = "SetLatency"; static const char *C_LATENCY_S = "SetLatency";
static const char *C_SETLINE_S = "SetLine"; static const char *C_SETLINE_S = "SetLine";
static const char *C_VENDOR_S = "Vendor"; static const char *C_VENDOR_S = "Vendor";
static const char *C_AVALON_TASK_S = "AvalonTask";
static const char *C_AVALON_READ_S = "AvalonRead";
static const char *C_GET_AVALON_READY_S = "AvalonReady";
static const char *C_AVALON_RESET_S = "AvalonReset";
static const char *C_GET_AR_S = "AvalonResult";
static const char *C_FTDI_STATUS_S = "FTDIStatus";
#ifdef EOL #ifdef EOL
#undef EOL #undef EOL
@ -927,6 +933,12 @@ static void cgusb_check_init()
usb_commands[C_LATENCY] = C_LATENCY_S; usb_commands[C_LATENCY] = C_LATENCY_S;
usb_commands[C_SETLINE] = C_SETLINE_S; usb_commands[C_SETLINE] = C_SETLINE_S;
usb_commands[C_VENDOR] = C_VENDOR_S; usb_commands[C_VENDOR] = C_VENDOR_S;
usb_commands[C_AVALON_TASK] = C_AVALON_TASK_S;
usb_commands[C_AVALON_READ] = C_AVALON_READ_S;
usb_commands[C_GET_AVALON_READY] = C_GET_AVALON_READY_S;
usb_commands[C_AVALON_RESET] = C_AVALON_RESET_S;
usb_commands[C_GET_AR] = C_GET_AR_S;
usb_commands[C_FTDI_STATUS] = C_FTDI_STATUS_S;
stats_initialised = true; stats_initialised = true;
} }
@ -2218,6 +2230,9 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro
int usb_ftdi_cts(struct cgpu_info *cgpu) int usb_ftdi_cts(struct cgpu_info *cgpu)
{ {
struct cg_usb_device *usbdev = cgpu->usbdev;
unsigned char buf[2], ret;
libusb_control_transfer(usbdev->handle, (uint8_t)FTDI_TYPE_IN, libusb_control_transfer(usbdev->handle, (uint8_t)FTDI_TYPE_IN,
(uint8_t)5, (uint16_t)0, (uint16_t)0, buf, 2, (uint8_t)5, (uint16_t)0, (uint16_t)0, buf, 2,
DEVTIMEOUT); DEVTIMEOUT);

15
usbutils.h

@ -18,6 +18,7 @@
// For 0x0403:0x6014/0x6001 FT232H (and possibly others?) - BFL, BAS, BLT, LLT, AVA // For 0x0403:0x6014/0x6001 FT232H (and possibly others?) - BFL, BAS, BLT, LLT, AVA
#define FTDI_TYPE_OUT (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT) #define FTDI_TYPE_OUT (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT)
#define FTDI_TYPE_IN (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN)
#define FTDI_REQUEST_RESET ((uint8_t)0) #define FTDI_REQUEST_RESET ((uint8_t)0)
#define FTDI_REQUEST_MODEM ((uint8_t)1) #define FTDI_REQUEST_MODEM ((uint8_t)1)
@ -40,6 +41,11 @@
#define FTDI_VALUE_BAUD_BLT 0x001a #define FTDI_VALUE_BAUD_BLT 0x001a
#define FTDI_INDEX_BAUD_BLT 0x0000 #define FTDI_INDEX_BAUD_BLT 0x0000
#define FTDI_VALUE_BAUD_AVA 0x001A
#define FTDI_INDEX_BAUD_AVA 0x0000
#define FTDI_VALUE_DATA_AVA 8
// Data control // Data control
#define FTDI_VALUE_DATA_BFL 0 #define FTDI_VALUE_DATA_BFL 0
#define FTDI_VALUE_DATA_BAS FTDI_VALUE_DATA_BFL #define FTDI_VALUE_DATA_BAS FTDI_VALUE_DATA_BFL
@ -210,6 +216,12 @@ enum usb_cmds {
C_LATENCY, C_LATENCY,
C_SETLINE, C_SETLINE,
C_VENDOR, C_VENDOR,
C_AVALON_TASK,
C_AVALON_READ,
C_GET_AVALON_READY,
C_AVALON_RESET,
C_GET_AR,
C_FTDI_STATUS,
C_MAX C_MAX
}; };
@ -238,6 +250,9 @@ void usb_initialise();
#define usb_read_once(cgpu, buf, bufsiz, read, cmd) \ #define usb_read_once(cgpu, buf, bufsiz, read, cmd) \
_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, true) _usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, true)
#define usb_read_once_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \
_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, true)
#define usb_read_nl(cgpu, buf, bufsiz, read, cmd) \ #define usb_read_nl(cgpu, buf, bufsiz, read, cmd) \
_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, "\n", cmd, false) _usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, "\n", cmd, false)

Loading…
Cancel
Save