/*  hstdispat.c -- Handlers for HOST devices
 *  copyright (c) American Information Systems Corporation
 *	Daniel Steinberg
 *	November, 1984
 *
 */

#include "viosconf.h"
#include "iopacket.h"
#include "viocmds.h"
#include "viostatus.h"
#include "handlers.h"
#include "hostsubrs.h"
#include "hostflags.h"


    PKT_STATE					/* Throw: Errors from drivers */
host_dispatcher (cmd, dev, pkt)
    int cmd;
    PDD_PTR dev;
    PKT_PTR pkt;

/* host_dispatcher (cmd, dev, pkt)
 *	in:	cmd		dispatcher function (PDCREATE / PDREMOVE / etc)
 *	in:	dev		bufptr to physical device descriptor
 *	in:	pkt		bufptr to active i/o packet
 *	return:	(PKT_STATE)	current state of i/o packet
 *	thrown:	(?)		(Drivers may throw errors...see note 1 below)
 *
 *	Main dispatcher for HOST-owned devices (devices whose physical names
 *	begin with the string "HOST:").  Typically, this dispatcher will not
 *	be called for device creation (PDCREATE) without
 *	an active i/o packet, since no host device initialization should occur
 *	at initial system startup.
 *
 *	This routine should be called with interrupts disabled (unless PDREMOVE
 *	function).
 *
 *	The following should be noted concerning device dispatchers:
 *		1) 'pkt' is assumed to be the i/o packet that is currently
 *		   being dispatched through main_dispatcher() (in viomain.c).
 *		   If this is not the case, thrown errors must be caught
 *		   upstream before they reach main_dispatcher().
 *
 *		2) Device dispatchers are typically called by q2device()
 *		   (in rdwrtsubs.c) which is called by class dispatchers..
 *		   Those routines should be referred to for more specifics
 *		   on the conditions under which the dispatcher is requested
 *		   when the 'cmd' is STARTIO.
 *
 *		3) A STARTIO request will not be dispatched if the device
 *		   has its current packet non-NULL (Devipkt / Devopkt | Devpkt).
 *		   Therefore, single-request devices must ensure that the
 *		   current packet pointer slot is maintained correctly;
 *		   multi-request devices (e.g. host disk devices) must keep
 *		   that slot (or slots, if full-duplex) clear.
 */
{
    switch (cmd)
	{
    case PDCREATE:
	Handler(*pkt) = host_create;
	break;

    case PDREMOVE:
	return(host_remove(dev));

    case STARTIO:
	switch (Ftype(*pkt))
	    {
	case DEVICE_FUNCTION:
	    Handler(*pkt) = host_control;
	    break;

	case WRITE_FUNCTION:
	    Handler(*pkt) = host_write;
	    break;

	case READ_FUNCTION:
	    Handler(*pkt) = host_read;
	    break;

#ifdef DEBUG4   /*************************************************************/
	default:
	    error ("Bad i/o function in host_dispatcher: %d", Function(*pkt));
#endif /* DEBUG4 *************************************************************/

	    } /*switch - Ftype*/
	break;


#ifdef DEBUG_MAP   /***********************************************************/
    case PDMAPPOOL:
	return(NULL);
#endif /* DEBUG_MAP ***********************************************************/

#ifdef DEBUG4   /*************************************************************/
    default:
	error ("Bad cmd to host_dispatcher: %d", cmd);
#endif /* DEBUG4 *************************************************************/

	} /*switch - cmd*/

	Stnum(*pkt) = 0;		/* reset state number */

	if (Host_connected)
	    return(VIO_RUN_STATE);		/* continue processing */
	else
	    return(HCNCT_WAIT_STATE);		/* wait for host */
}
