예제 #1
0
/* returns a free command struct if one is available. 
 * It also blanks out anything that may be a wild pointer/value.
 * Also, command buffers are not freed.  They are
 * small so they are saved and kept dmamapped and loaded.
 */
int ips_get_free_cmd(ips_softc_t *sc, ips_command_t **cmd, unsigned long flags)
{
	ips_command_t *command;

	if(sc->state & IPS_OFFLINE){
		return EIO;
	}
	if ((flags & IPS_STATIC_FLAG) == 0) {
		command = SLIST_FIRST(&sc->free_cmd_list);
		if(!command || (sc->state & IPS_TIMEOUT)){
			return EBUSY;
		}
		SLIST_REMOVE_HEAD(&sc->free_cmd_list, next);
		(sc->used_commands)++;
	} else {
		if (sc->state & IPS_STATIC_BUSY)
			return EAGAIN;
		command = sc->staticcmd;
		sc->state |= IPS_STATIC_BUSY;
	}
	clear_ips_command(command);
	bzero(command->command_buffer, IPS_COMMAND_LEN);
	*cmd = command;
	return 0;
}
예제 #2
0
파일: ips.c 프로젝트: MarginC/kame
static void ips_run_waiting_command(ips_softc_t *sc)
{
	ips_wait_list_t *waiter;
	ips_command_t	*command;
	int (*callback)(ips_command_t*);
	intrmask_t mask;

	mask = splbio();
	waiter = STAILQ_FIRST(&sc->cmd_wait_list);
	command = SLIST_FIRST(&sc->free_cmd_list);
	if(!waiter || !command){
		splx(mask);
		return;
	}
	DEVICE_PRINTF(1, sc->dev, "removing command from wait queue\n");
	SLIST_REMOVE_HEAD(&sc->free_cmd_list, next);
	STAILQ_REMOVE_HEAD(&sc->cmd_wait_list, next);
	(sc->used_commands)++;
	splx(mask);
	clear_ips_command(command);
	bzero(command->command_buffer, IPS_COMMAND_LEN);
	command->arg = waiter->data;
	callback = waiter->callback;
	free(waiter, M_DEVBUF);
	callback(command);
	return;	
}
예제 #3
0
파일: ips.c 프로젝트: MarginC/kame
/* returns a free command struct if one is available. 
 * It also blanks out anything that may be a wild pointer/value.
 * Also, command buffers are not freed.  They are
 * small so they are saved and kept dmamapped and loaded.
 */
int ips_get_free_cmd(ips_softc_t *sc, int (*callback)(ips_command_t *), void *data, unsigned long flags)
{
	intrmask_t mask;
	ips_command_t *command;
	mask = splbio();

	if(sc->state & IPS_OFFLINE){
		splx(mask);
		return EIO;
	}
	command = SLIST_FIRST(&sc->free_cmd_list);
	if(!command || (sc->state & IPS_TIMEOUT)){
		splx(mask);
		if(flags & IPS_NOWAIT_FLAG)
			return EAGAIN;
		return ips_add_waiting_command(sc, callback, data, flags);
	}
	SLIST_REMOVE_HEAD(&sc->free_cmd_list, next);
	(sc->used_commands)++;
	splx(mask);
	clear_ips_command(command);
	bzero(command->command_buffer, IPS_COMMAND_LEN);
	command->arg = data;
	return callback(command);
}
예제 #4
0
파일: ips.c 프로젝트: MarginC/kame
static int ips_add_waiting_command(ips_softc_t *sc, int (*callback)(ips_command_t *), void *data, unsigned long flags)
{
	intrmask_t mask;
	ips_command_t *command;
	ips_wait_list_t *waiter;
	unsigned long memflags = 0;
	if(IPS_NOWAIT_FLAG & flags)
		memflags = M_NOWAIT;
	waiter = malloc(sizeof(ips_wait_list_t), M_DEVBUF, memflags);
	if(!waiter)
		return ENOMEM;
	mask = splbio();
	if(sc->state & IPS_OFFLINE){
		splx(mask);
		return EIO;
	}
	command = SLIST_FIRST(&sc->free_cmd_list);
	if(command && !(sc->state & IPS_TIMEOUT)){
		SLIST_REMOVE_HEAD(&sc->free_cmd_list, next);
		(sc->used_commands)++;
		splx(mask);
		clear_ips_command(command);
		bzero(command->command_buffer, IPS_COMMAND_LEN);
		free(waiter, M_DEVBUF);
		command->arg = data;
		return callback(command);
	}
	DEVICE_PRINTF(1, sc->dev, "adding command to the wait queue\n"); 
	waiter->callback = callback; 
	waiter->data = data;
	STAILQ_INSERT_TAIL(&sc->cmd_wait_list, waiter, next);
	splx(mask);
	return 0;
}