예제 #1
0
/* Figure out how many jobs to send. */
static int hfa_jobs(struct cgpu_info *hashfast, struct hashfast_info *info)
{
	int ret = 0;

	if (unlikely(info->overheat)) {
		/* Acknowledge and notify of new condition.*/
		if (info->overheat < 0) {
			applog(LOG_WARNING, "%s %d: Hit overheat temp %.1f, throttling!",
			       hashfast->drv->name, hashfast->device_id, info->max_temp);
			/* Value of 1 means acknowledged overheat */
			info->overheat = 1;
		}
		goto out;
	}

	mutex_lock(&info->lock);
	ret = info->usb_init_base.inflight_target - HF_SEQUENCE_DISTANCE(info->hash_sequence_head, info->device_sequence_tail);
	/* Place an upper limit on how many jobs to queue to prevent sending
	 * more  work than the device can use after a period of outage. */
	if (ret > info->usb_init_base.inflight_target)
		ret = info->usb_init_base.inflight_target;
	mutex_unlock(&info->lock);

out:
	return ret;
}
예제 #2
0
static void hfa_parse_gwq_status(struct cgpu_info *hashfast, struct hashfast_info *info,
				 struct hf_header *h)
{
	struct hf_gwq_data *g = (struct hf_gwq_data *)(h + 1);
	struct work *work;

	applog(LOG_DEBUG, "HFA %d: OP_GWQ_STATUS, device_head %4d tail %4d my tail %4d shed %3d inflight %4d",
		hashfast->device_id, g->sequence_head, g->sequence_tail, info->hash_sequence_tail,
		g->shed_count, HF_SEQUENCE_DISTANCE(info->hash_sequence_head,g->sequence_tail));

	mutex_lock(&info->lock);
	info->hash_count += g->hash_count;
	info->device_sequence_head = g->sequence_head;
	info->device_sequence_tail = g->sequence_tail;
	info->shed_count = g->shed_count;
	/* Free any work that is no longer required */
	while (info->device_sequence_tail != info->hash_sequence_tail) {
		if (++info->hash_sequence_tail >= info->num_sequence)
			info->hash_sequence_tail = 0;
		if (unlikely(!(work = info->works[info->hash_sequence_tail]))) {
			applog(LOG_ERR, "HFA %d: Bad work sequence tail",
			       hashfast->device_id);
			hashfast->shutdown = true;
			break;
		}
		applog(LOG_DEBUG, "HFA %d: Completing work on hash_sequence_tail %d",
		       hashfast->device_id, info->hash_sequence_tail);
		free_work(work);
		info->works[info->hash_sequence_tail] = NULL;
	}
	mutex_unlock(&info->lock);
}
예제 #3
0
/* Figure out how many jobs to send. */
static int hfa_jobs(struct hashfast_info *info)
{
    int ret;

    mutex_lock(&info->lock);
    ret = info->usb_init_base.inflight_target - HF_SEQUENCE_DISTANCE(info->hash_sequence_head, info->device_sequence_tail);
    /* Place an upper limit on how many jobs to queue to prevent sending
     * more  work than the device can use after a period of outage. */
    if (ret > info->usb_init_base.inflight_target)
        ret = info->usb_init_base.inflight_target;
    mutex_unlock(&info->lock);

    return ret;
}
예제 #4
0
static void hfa_parse_gwq_status(struct cgpu_info *hashfast, struct hashfast_info *info,
                                 struct hf_header *h)
{
    struct hf_gwq_data *g = (struct hf_gwq_data *)(h + 1);
    struct work *work;

    applog(LOG_DEBUG, "HFA %d: OP_GWQ_STATUS, device_head %4d tail %4d my tail %4d shed %3d inflight %4d",
           hashfast->device_id, g->sequence_head, g->sequence_tail, info->hash_sequence_tail,
           g->shed_count, HF_SEQUENCE_DISTANCE(info->hash_sequence_head,g->sequence_tail));

    /* This is a special flag that the thermal overload has been tripped */
    if (unlikely(h->core_address & 0x80)) {
        applog(LOG_WARNING, "HFA %d Thermal overload tripped! Resetting device",
               hashfast->device_id);
        hfa_send_shutdown(hashfast);
        if (hfa_reset(hashfast, info)) {
            applog(LOG_NOTICE, "HFA %d: Succesfully reset, continuing operation",
                   hashfast->device_id);
            return;
        }
        applog(LOG_WARNING, "HFA %d Failed to reset device, killing off thread to allow re-hotplug",
               hashfast->device_id);
        usb_nodev(hashfast);
        return;
    }

    mutex_lock(&info->lock);
    info->hash_count += g->hash_count;
    info->device_sequence_head = g->sequence_head;
    info->device_sequence_tail = g->sequence_tail;
    info->shed_count = g->shed_count;
    /* Free any work that is no longer required */
    while (info->device_sequence_tail != info->hash_sequence_tail) {
        if (++info->hash_sequence_tail >= info->num_sequence)
            info->hash_sequence_tail = 0;
        if (unlikely(!(work = info->works[info->hash_sequence_tail]))) {
            applog(LOG_ERR, "HFA %d: Bad work sequence tail",
                   hashfast->device_id);
            hashfast->shutdown = true;
            break;
        }
        applog(LOG_DEBUG, "HFA %d: Completing work on hash_sequence_tail %d",
               hashfast->device_id, info->hash_sequence_tail);
        free_work(work);
        info->works[info->hash_sequence_tail] = NULL;
    }
    mutex_unlock(&info->lock);
}