Files
org-hyperion-cules/hchan.c
Fish (David B. Trout) d29545f2a8 silence some warnings
2014-01-03 13:53:17 -08:00

237 lines
8.2 KiB
C

/* HCHAN.C (c) Copyright Ivan Warren, 2005-2012 */
/* Based on work (c)Roger Bowler, Jan Jaeger & Others 1999-2009 */
/* Generic channel device handler */
/* */
/* Released under "The Q Public License Version 1" */
/* (http://www.hercules-390.org/herclic.html) as modifications to */
/* Hercules. */
/**CAUTION*CAUTION*CAUTION*CAUTION*CAUTION*CAUTION*CAUTION*CAUTION****/
/* THIS CODE IS CURRENTLY IN A DEVELOPMENT STAGE AND IS NOT */
/* OPERATIONAL */
/* THIS FONCTIONALITY IS NOT YET SUPPORTED */
/**CAUTION*CAUTION*CAUTION*CAUTION*CAUTION*CAUTION*CAUTION*CAUTION****/
/*-------------------------------------------------------------------*/
/* This module contains code to handle a generic protocol to */
/* communicate with external device handlers. */
/*-------------------------------------------------------------------*/
#include "hstdinc.h"
#include "hercules.h"
#include "devtype.h"
#include "hchan.h"
#if defined(OPTION_DYNAMIC_LOAD) && defined(WIN32) && !defined(HDL_USE_LIBTOOL) && !defined(_MSVC_)
SYSBLK *psysblk;
#define sysblk (*psysblk)
#endif
/*
* Initialisation string for a Generic Subchannel
*
* Format :
* <method> parms
* The 'EXEC' method will attempt to fork/exec the specified
* program. If the program dies during device initialisation, the
* subchannel will be invalidated (initialisation error). If it fails
* afterwards, the subchannel will be put offline and the offload
* thread will attempt to restart it at periodic intervals.
* The 'CONNECT' method will attempt to establish a TCP connection
* to the IP/PORT specified. If the connection fails, the connection
* will be attempted at periodic intervals.
* The 'ITHREAD' method will spawn a thread using a dynamically loaded module
*/
static int hchan_init_handler ( DEVBLK *dev, int argc, char *argv[] )
{
int rc;
/* For re-initialisation, close the existing file, if any */
if (dev->fd >= 0)
(dev->hnd->close)(dev);
dev->devtype=0x2880; /* Temporary until the device is actually initialised */
while(1)
{
if(argc<1)
{
WRMSG(HHC01350,"E",SSID_TO_LCSS(dev->ssid),dev->devnum);
rc=-1;
break;
}
if(strcasecmp(argv[0],"EXEC")==0)
{
rc=hchan_init_exec(dev,argc,argv);
break;
}
if(strcasecmp(argv[0],"CONNECT")==0)
{
rc=hchan_init_connect(dev,argc,argv);
break;
}
if(strcasecmp(argv[0],"ITHREAD")==0)
{
rc=hchan_init_int(dev,argc,argv);
break;
}
WRMSG(HHC01351,"E",SSID_TO_LCSS(dev->ssid),dev->devnum,argv[0]);
rc=-1;
break;
}
if(rc)
{
WRMSG(HHC01352,"T",SSID_TO_LCSS(dev->ssid),dev->devnum);
}
WRMSG(HHC01353,"W",SSID_TO_LCSS(dev->ssid),dev->devnum);
return(rc);
}
static int hchan_init_exec(DEVBLK *dev,int ac,char **av)
{
UNREFERENCED(dev);
UNREFERENCED(ac);
UNREFERENCED(av);
return(0);
}
static int hchan_init_connect(DEVBLK *dev,int ac,char **av)
{
UNREFERENCED(dev);
UNREFERENCED(ac);
UNREFERENCED(av);
return(0);
}
static int hchan_init_int(DEVBLK *dev,int ac,char **av)
{
UNREFERENCED(dev);
UNREFERENCED(ac);
UNREFERENCED(av);
return(0);
}
/*-------------------------------------------------------------------*/
/* Query the device definition */
/*-------------------------------------------------------------------*/
static void hchan_query_device (DEVBLK *dev, char **devclass,
int buflen, char *buffer)
{
BEGIN_DEVICE_CLASS_QUERY( "CHAN", dev, devclass, buflen, buffer );
snprintf(buffer,buflen,"** CONTROL UNIT OFFLINE **");
}
/*-------------------------------------------------------------------*/
/* Close the device */
/*-------------------------------------------------------------------*/
static int hchan_close_device ( DEVBLK *dev )
{
UNREFERENCED(dev);
return 0;
}
/*-------------------------------------------------------------------*/
/* Execute a Channel Command Word */
/*-------------------------------------------------------------------*/
static void hchan_execute_ccw ( DEVBLK *dev, BYTE code, BYTE flags,
BYTE chained, U32 count, BYTE prevcode, int ccwseq,
BYTE *iobuf, BYTE *more, BYTE *unitstat, U32 *residual )
{
UNREFERENCED(flags);
UNREFERENCED(prevcode);
UNREFERENCED(ccwseq);
UNREFERENCED(chained);
UNREFERENCED(count);
UNREFERENCED(iobuf);
UNREFERENCED(more);
UNREFERENCED(residual);
/* Process depending on CCW opcode */
switch (code) {
default:
/*---------------------------------------------------------------*/
/* INVALID OPERATION */
/*---------------------------------------------------------------*/
/* Set command reject sense byte, and unit check status */
dev->sense[0] = SENSE_CR;
*unitstat = CSW_CE | CSW_DE | CSW_UC;
}
}
#if defined(OPTION_DYNAMIC_LOAD)
static
#endif
DEVHND hchan_device_hndinfo = {
&hchan_init_handler, /* Device Initialisation */
&hchan_execute_ccw, /* Device CCW execute */
&hchan_close_device, /* Device Close */
&hchan_query_device, /* Device Query */
NULL, /* Extended Device Query */
NULL, /* Device Start channel pgm */
NULL, /* Device End channel pgm */
NULL, /* Device Resume channel pgm */
NULL, /* Device Suspend channel pgm */
NULL, /* Device Halt channel pgm */
NULL, /* Device Read */
NULL, /* Device Write */
NULL, /* Device Query used */
NULL, /* Device Reserve */
NULL, /* Device Release */
NULL, /* Device Attention */
NULL, /* Immediate CCW Codes */
NULL, /* Signal Adapter Input */
NULL, /* Signal Adapter Output */
NULL, /* Signal Adapter Sync */
NULL, /* Signal Adapter Output Mult */
NULL, /* QDIO subsys desc */
NULL, /* QDIO set subchan ind */
NULL, /* Hercules suspend */
NULL /* Hercules resume */
};
/* Libtool static name colision resolution */
/* note : lt_dlopen will look for symbol & modulename_LTX_symbol */
#if !defined(HDL_BUILD_SHARED) && defined(HDL_USE_LIBTOOL)
#define hdl_ddev hdt0000_LTX_hdl_ddev
#define hdl_depc hdt0000_LTX_hdl_depc
#define hdl_reso hdt0000_LTX_hdl_reso
#define hdl_init hdt0000_LTX_hdl_init
#define hdl_fini hdt0000_LTX_hdl_fini
#endif
#if defined(OPTION_DYNAMIC_LOAD)
HDL_DEPENDENCY_SECTION;
{
HDL_DEPENDENCY(HERCULES);
HDL_DEPENDENCY(DEVBLK);
HDL_DEPENDENCY(SYSBLK);
}
END_DEPENDENCY_SECTION
#if defined(WIN32) && !defined(HDL_USE_LIBTOOL) && !defined(_MSVC_)
#undef sysblk
HDL_RESOLVER_SECTION;
{
HDL_RESOLVE_PTRVAR( psysblk, sysblk );
}
END_RESOLVER_SECTION
#endif
HDL_DEVICE_SECTION;
{
HDL_DEVICE(HCHAN, hchan_device_hndinfo );
HDL_DEVICE(2860, hchan_device_hndinfo );
HDL_DEVICE(2870, hchan_device_hndinfo );
HDL_DEVICE(2880, hchan_device_hndinfo );
HDL_DEVICE(9032, hchan_device_hndinfo );
}
END_DEVICE_SECTION
#endif