h26872
s 00014/00009/00147
d D 3.2 85/06/04 14:51:09 dock 2 1
c changed include files
e
s 00156/00000/00000
d D 3.1 84/11/13 16:28:11 dan 1 0
c date and time created 84/11/13 16:28:11 by dan
e
u
U
t
T
I 1
D 2
/*  inihandlr.c -- Virtual I/O request initialization handler
 *  copyright (c) American Information Systems Corporation
 *	Daniel Steinberg
 *	November, 1984
E 2
I 2

/*
 * %M%: version %I% of %H%
E 2
 *
I 2
 *  inihandlr.c -- Virtual I/O request initialization handler
 *  copyright (c) American Information Systems Corporation
 *	Daniel Steinberg  November, 1984
E 2
 */
I 2
#ifdef SCCS
static char *sccsid = "%W%";
#endif
E 2

D 2
#include "viosconf.h"
#include "handlers.h"
#include "iopacket.h"
#include "viocmds.h"
#include "viostatus.h"
E 2
I 2
#include "vinc/viosconf.h"
#include "vinc/handlers.h"
#include "vinc/iopacket.h"
#include "vinc/viocmds.h"
#include "vinc/viostatus.h"
E 2


    PKT_STATE				/* Throw: V_NO_DEVICE/V_ILL_FUNCTION */
init_request (pkt)
    register PKT_PTR pkt;

/* init_request (pkt) -- Do initial processing of VIOS I/O Requests
 *
 *	in:	pkt		I/O Packet to process
 *	return:	(PKT_STATE)	Next state of i/o packet
 *	thrown:	V_NO_DEVICE	Device does not exist
 *		V_ILL_FUNCTION	Function type is illegal
 *		V_ALL_FAILURE	Allocation failure on Mapped-Buffer
 *		V_BAD_BUFFER	Mapped-Buffer mapping failure
 *
 *	Does initial processing of VIOS I/O Requests as follows:
 *		1) If VDevice(*pkt) is supplied, verify that it is a legal
 *		   virtual or physical device.  If it is, increment its
 *		   outstanding i/o count.
 *		2) Call map_buffer() (in hypersubs.c) to check user-supplied
 *		   buffer.  If TRUE is returned, buffer was mapped and the
 *		   I/O packet was duplicated and requeued; therefore,
 *			return DONE_WAIT_STATE.
 *		3) Set a new handler routine in the packet based on the
 *		   request function type (VCTRL / WRITE / READ / etc).
 *		4) If the function is not a V/PCTRL_FUNCTION, verify that
 *		   a target device was specified. If not, throw V_NO_DEVICE.
 *		5) Return VIO_RUN_STATE to continue processing with the
 *		   next handler.
 *
 *	Throws V_NO_DEVICE if VDevice is supplied, but not legal.  In this
 *	case, VDevice is set to NULL so that io_complete() won't try
 *	to decrement a non-existent descriptor.
 *
 *	Throws V_ILL_FUNCTION if the function type is unrecognized.
 *
 *	Map_buffer() may throw V_ALL_FAILURE or V_BAD_BUFFER if error
 *	while processing Mapped User Buffers.
 */
{
    register IO_PACKET *pk;	/* dereferenced ptr */
    register VDD_PTR    dev;	/* target device */

    dev = VDevice(pk = *pkt);

    switch (Stnum(pk))
	{
    case 0:
	if ( dev NE NULL )
	    {
	    if ( ((catch() EQ 0) AND (checkvd(dev, Osid(pk)), TRUE)) OR
				    ((catch() EQ 0) AND (checkpd(dev), TRUE)) )
		{
		Outstanding_IO(*dev)++;		/* If device is legal, */
		uncatch();			/* increment outstanding i/o */
		}
	    else
		{
		VDevice(pk) = NULL;	/* clear so i/o completion */
		rethrow();		/* doesn't decrement random pool */
		}
	    } /*if-VDevice*/
	
#ifdef DEBUG3   /*************************************************************/
	if ( (Auxparam(pk) NE NULL) AND (NOT(chk_pool(Auxparam(pk)))) )
	    {				/* Invalid auxilliary parameter */
	    error("Bad auxparam in init_request()", NULL);

	    Auxparam(pk) = NULL;	/* don't release invalid pool */
	    throw(V_BAD_PARAMS);
	    } /*if-Auxparam*/
#endif /* DEBUG3 *************************************************************/

	/* Check for Mapped-Buffer ... return DONE_WAIT_STATE if remapped */
	if ((Ubufsize(pk) NE 0) AND (map_buffer(pkt)))
	    return(DONE_WAIT_STATE);

	/* Don't have to refresh dereferenced ptrs since map_buffer either */
	/* returned TRUE or threw an error if pool allocation was attempted */
	/* However, the State Number of the child will be incremented */

    case 1:			/* I/O buffer remapped if entered here */
	Stnum(pk) = 0;		/* reset state number before calling out */

	switch (Ftype(pk))
	    {
	case PCTRL_FUNCTION:
	    Handler(pk) = pctrl_handler;	/* set new handler */
	    if ((dev NE NULL) AND (Devtype(*dev) NE PDTYPE))
		throw(V_NO_DEVICE);
	    return(VIO_RUN_STATE);

	case VCTRL_FUNCTION:
	    Handler(pk) = vctrl_handler;	/* set new handler */
	    goto Novdevok;			/* skip device check */

	case WRITE_FUNCTION:
	    Handler(pk) = vwrt_handler;		/* set new handler */
	    break;

	case READ_FUNCTION:
	    Handler(pk) = vrd_handler;		/* set new handler */
	    break;

	case DEVICE_FUNCTION:
	    switch (Fcode(pk))
		{
	    case VDEV_CONTROL:			/* Virtual Device control */
		Handler(pk) = vdevice_handler;	/* set new handler */
		break;
	    
	    case PDEV_CONTROL:			/* Physical Device control */
		Handler(pk) = pdevice_handler;	/* set new handler */
		if ((dev EQ NULL) OR (Devtype(*dev) NE PDTYPE))
		    throw(V_NO_DEVICE);
		return(VIO_RUN_STATE);
	    
	    default:
		throw(V_ILL_FUNCTION);
		} /*switch-Fcode*/
	    break;

	case AUX_FUNCTION:
	    Handler(pk) = aux_handler;		/* set new handler */
	    goto Novdevok;			/* skip device check */

	case VINFO_FUNCTION:
	    Handler(pk) = vinfo_handler;	/* set new handler */
	    return(VIO_RUN_STATE);		/* no device restraints */

	default:
	    throw(V_ILL_FUNCTION);
	    } /*switch-function type*/

	/* All requests that pass thru here must have a target virtual device */
	if (dev EQ NULL)  throw(V_NO_DEVICE);

Novdevok:
	if ((dev NE NULL) AND (Devtype(*dev) NE VDTYPE))
	    throw(V_NO_DEVICE);

	return(VIO_RUN_STATE);	/* continue processing elsewhere */
	} /*switch-Stnum*/
}
E 1
