static bool gridseed_prepare_work(struct thr_info __maybe_unused *thr, struct work *work) { struct cgpu_info *gridseed = thr->cgpu; GRIDSEED_INFO *info = gridseed->device_data; cgtime(&info->scanhash_time); gc3355_send_cmds(gridseed, str_ltc_reset); usb_buffer_clear(gridseed); return gridseed_send_task(gridseed, work); }
static bool gridseed_check_new_task(struct cgpu_info *gridseed, GRIDSEED_INFO *info) { cgtimer_t ts_now, ts_res; bool ret = false; cgtimer_time(&ts_now); mutex_lock(&info->qlock); cgtimer_sub(&ts_now, &info->query_ts, &ts_res); #ifndef WIN32 if (ts_res.tv_sec > 0 || ts_res.tv_nsec > 350000000) { #else if (ts_res.QuadPart > 3500000) { #endif info->query_qlen = false; info->dev_queue_len = 1; info->needworks = 1; cgtimer_time(&info->query_ts); } mutex_unlock(&info->qlock); } /* * Thread to read response from Miner device */ static void *gridseed_get_results(void *userdata) { struct cgpu_info *gridseed = (struct cgpu_info *)userdata; GRIDSEED_INFO *info = gridseed->device_data; struct thr_info *thr = info->thr; char threadname[24]; unsigned char readbuf[GRIDSEED_READBUF_SIZE]; int offset = 0, ret; snprintf(threadname, sizeof(threadname), "GridSeed_Recv/%d", gridseed->device_id); RenameThread(threadname); applog(LOG_NOTICE, "GridSeed: recv thread running, %s", threadname); while(likely(!gridseed->shutdown)) { unsigned char buf[GRIDSEED_READ_SIZE]; if (offset >= GRIDSEED_READ_SIZE) gridseed_parse_results(gridseed, info, thr, readbuf, &offset); if (unlikely(offset + GRIDSEED_READ_SIZE >= GRIDSEED_READBUF_SIZE)) { applog(LOG_ERR, "Read buffer overflow, resetting %d", gridseed->device_id); offset = 0; } ret = gc3355_get_data(gridseed, buf, sizeof(buf)); if (ret == LIBUSB_ERROR_NO_DEVICE) gridseed->shutdown = true; if (unlikely(ret != 0)) continue; if (opt_debug) { applog(LOG_DEBUG, "GridSeed: get %d bytes", GRIDSEED_READ_SIZE); hexdump((uint8_t *)buf, GRIDSEED_READ_SIZE); } memcpy(readbuf + offset, buf, GRIDSEED_READ_SIZE); offset += GRIDSEED_READ_SIZE; } return NULL; } /* * Thread to send task and queue length query command to device */ static void *gridseed_send_command(void *userdata) { struct cgpu_info *gridseed = (struct cgpu_info *)userdata; GRIDSEED_INFO *info = gridseed->device_data; char threadname[24]; int i; snprintf(threadname, sizeof(threadname), "GridSeed_Send/%d", gridseed->device_id); RenameThread(threadname); applog(LOG_NOTICE, "GridSeed: send thread running, %s", threadname); while(likely(!gridseed->shutdown)) { cgsleep_ms(10); if (info->usefifo == 0) { /* mark the first work in queue as complete after several ms */ if (gridseed_check_new_task(gridseed, info)) continue; } else { /* send query command to device */ if (gridseed_send_query_cmd(gridseed, info)) continue; } /* send task to device */ mutex_lock(&info->qlock); for(i=0; i<info->soft_queue_len; i++) { if (info->workqueue[i] && info->workqueue[i]->devflag == false) { if (gridseed_send_task(gridseed, info, info->workqueue[i])) { info->workqueue[i]->devflag = true; break; } } } mutex_unlock(&info->qlock); /* recv LTC task and send to device */ gridseed_recv_ltc(gridseed, info); } return NULL; } /*========== functions for struct device_drv ===========*/ static void gridseed_detect(bool __maybe_unused hotplug) { usb_detect(&gridseed_drv, gridseed_detect_one); }