Beispiel #1
0
static void push_resp () {
	if (status.first_resp == NULL)
		return;

	if (psl_response (status.event, status.first_resp->tag,
	    status.first_resp->code, 1, 0, 0) == PSL_SUCCESS) {
		struct afu_resp *temp;
		temp = status.first_resp;
		status.first_resp = status.first_resp->_next;
		if (status.first_resp == NULL) {
			status.last_resp = NULL;
		}
		free (temp);
	}
}
Beispiel #2
0
// Send a randomly selected pending response back to AFU
void handle_response(struct cmd *cmd)
{
	struct cmd_event **head;
	struct cmd_event *event;
	struct client *client;
	int rc;

	// Select a random pending response (or none)
	client = NULL;
	head = &cmd->list;
	while (*head != NULL) {
		// Fast track error responses
		if (((*head)->resp == PSL_RESPONSE_PAGED) ||
		    ((*head)->resp == PSL_RESPONSE_NRES) ||
		    ((*head)->resp == PSL_RESPONSE_NLOCK) ||
		    ((*head)->resp == PSL_RESPONSE_FAILED) ||
		    ((*head)->resp == PSL_RESPONSE_FLUSHED)) {
			event = *head;
			goto drive_resp;
		}
		if (((*head)->state == MEM_DONE) && !allow_reorder(cmd->parms)) {
			break;
		}
		head = &((*head)->_next);
	}

	// Randomly decide not to drive response yet
	event = *head;
	if ((event == NULL) || ((event->client_state == CLIENT_VALID)
				&& !allow_resp(cmd->parms))) {
		return;
	}
	// Test for client disconnect
	if ((event == NULL) || ((client = _get_client(cmd, event)) == NULL))
		return;

	// Send response, remove command from list and free memory
	if ((event->resp == PSL_RESPONSE_PAGED) ||
	    (event->resp == PSL_RESPONSE_AERROR) ||
	    (event->resp == PSL_RESPONSE_DERROR)) {
		client->flushing = FLUSH_FLUSHING;
		_update_pending_resps(cmd, PSL_RESPONSE_FLUSHED);
	}

 drive_resp:
	// Check for pending buffer activity
	if (event == cmd->buffer_read) {
		fatal_msg("Driving response when buffer read still active");
		_print_event(event);
		assert(event != cmd->buffer_read);
	}

	rc = psl_response(cmd->afu_event, event->tag, event->resp, 1, 0, 0);
	if (rc == PSL_SUCCESS) {
		debug_msg("%s:RESPONSE tag=0x%02x code=0x%x", cmd->afu_name,
			  event->tag, event->resp);
		debug_cmd_response(cmd->dbg_fp, cmd->dbg_id, event->tag);
		if ((client != NULL) && (event->command == PSL_COMMAND_RESTART))
			client->flushing = FLUSH_NONE;
		*head = event->_next;
		free(event->data);
		free(event->parity);
		free(event);
		cmd->credits++;
	}
}